/* ReportForm.jsx — public report flow, wired to /api/report */
const { useState } = React;

function CategoryGrid({ selected, toggle, lang }) {
  return (
    <div className="cat-grid">
      {window.MELD.categories.map((c) => {
        const on = selected.includes(c.id);
        return (
          <button key={c.id} type="button" onClick={() => toggle(c.id)}
            className={"cat-chip" + (on ? " on" : "")}>
            <span className="cat-ico"><Ico name={c.icon} size={22} /></span>
            <span className="cat-label">{c[lang]}</span>
            <span className="cat-check">{on ? <Ico name="check" size={14} /> : null}</span>
          </button>
        );
      })}
    </div>
  );
}

function WhenField({ when, setWhen, t }) {
  const isNow = when === "now";
  const now = new Date();
  const pad = (n) => String(n).padStart(2, "0");
  const maxDt = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}T${pad(now.getHours())}:${pad(now.getMinutes())}`;
  return (
    <div>
      <div className="seg">
        <button type="button" className={"seg-btn" + (isNow ? " on" : "")} onClick={() => setWhen("now")}>
          <Ico name="clock" size={15} /> {t.when_now}
        </button>
        <button type="button" className={"seg-btn" + (!isNow ? " on" : "")}
          onClick={() => setWhen(when === "now" ? maxDt : when)}>
          <Ico name="calendar" size={15} /> {t.when_earlier}
        </button>
      </div>
      {!isNow && (
        <input type="datetime-local" className="input" style={{ marginTop: 10 }}
          value={when} max={maxDt} onChange={(e) => setWhen(e.target.value)} />
      )}
    </div>
  );
}

function EvidenceField({ files, setFiles, t }) {
  const inputRef = React.useRef(null);
  const cameraRef = React.useRef(null);
  const [drag, setDrag] = useState(false);

  function add(list) {
    const arr = Array.from(list).map((f) => ({ name: f.name, size: f.size, type: f.type, _file: f }));
    setFiles((prev) => [...prev, ...arr].slice(0, 6));
  }

  return (
    <div>
      <div className={"dropzone" + (drag ? " drag" : "")}
        onDragOver={(e) => { e.preventDefault(); setDrag(true); }}
        onDragLeave={() => setDrag(false)}
        onDrop={(e) => { e.preventDefault(); setDrag(false); add(e.dataTransfer.files); }}
        onClick={() => inputRef.current && inputRef.current.click()}>
        <input ref={inputRef} type="file" accept="image/*,video/*" multiple hidden
          onChange={(e) => add(e.target.files)} />
        <input ref={cameraRef} type="file" accept="image/*" capture="environment" hidden
          onChange={(e) => add(e.target.files)} />
        <div className="dz-actions">
          <span className="dz-btn" onClick={(e) => { e.stopPropagation(); cameraRef.current && cameraRef.current.click(); }}>
            <Ico name="camera" size={18} /> {t.drop_photo}
          </span>
          <span className="dz-btn"><Ico name="upload" size={18} /> {t.drop_upload}</span>
        </div>
        <div className="dz-hint">{t.drop_hint}</div>
      </div>
      {files.length > 0 && (
        <div className="file-list">
          {files.map((f, i) => (
            <div key={i} className="file-pill">
              <Ico name={f.type && f.type.startsWith("video") ? "video" : "image"} size={15} />
              <span className="file-name">{f.name}</span>
              <button type="button" className="file-x" onClick={() => setFiles((p) => p.filter((_, j) => j !== i))}>
                <Ico name="x" size={13} />
              </button>
            </div>
          ))}
        </div>
      )}
      <div className="notice notice-warn" style={{ marginTop: 12 }}>
        <Ico name="eye-off" size={16} /> <span>{t.privacy_warn}</span>
      </div>
    </div>
  );
}

function ContactField({ contact, setContact, t }) {
  const c = contact;
  const set = (k, v) => setContact({ ...c, [k]: v });
  return (
    <div className="contact-split">
      <div className={"contact-left" + (c.anon ? " contact-left-dim" : "")}>
        <div>
          <label className="field-label">{t.name} {!c.anon && <span className="req">*</span>}</label>
          <input className="input" value={c.name} disabled={c.anon}
            onChange={(e) => set("name", e.target.value)} />
        </div>
        <div className="contact-row">
          <div>
            <label className="field-label">{t.email}</label>
            <input className="input" type="email" value={c.email} disabled={c.anon}
              onChange={(e) => set("email", e.target.value)} />
          </div>
          <div>
            <label className="field-label">{t.phone}</label>
            <input className="input" value={c.phone} disabled={c.anon}
              onChange={(e) => set("phone", e.target.value)} />
          </div>
        </div>
        {!c.anon && <p className="contact-hint">{t.contact_hint || (t.email + " oder " + t.phone + " wird benötigt.")}</p>}
      </div>
      <div className="contact-oder"><span>{t.contact_oder || "oder"}</span></div>
      <div className="contact-right">
        <label className="anon-toggle anon-toggle-v">
          <input type="checkbox" checked={c.anon} onChange={(e) => set("anon", e.target.checked)} />
          <span className="anon-box">{c.anon ? <Ico name="check" size={13} /> : null}</span>
          <span>{t.anon_ok}</span>
        </label>
      </div>
    </div>
  );
}

function MapField({ loc, setLoc, locErr, setLocErr, t, tall }) {
  const locateRef = React.useRef(null);
  const [busy, setBusy] = useState(false);
  const [serverAreas, setServerAreas] = useState(null);

  React.useEffect(() => {
    fetch("/api/areas")
      .then(r => r.json())
      .then(d => setServerAreas(d.success && d.areas && d.areas.length ? d.areas : []))
      .catch(() => setServerAreas([]));
  }, []);

  function applyLoc(ll) {
    setBusy(false);
    const hasServerAreas = serverAreas && serverAreas.length > 0;
    const inBounds = !hasServerAreas || isInAnyGeoJSONArea(ll.lat, ll.lng, serverAreas);
    if (!inBounds) {
      setLocErr && setLocErr(t.out_of_bounds);
      setLoc(null);
      return;
    }
    setLocErr && setLocErr(null);
    const zones = window.MELD.zones;
    const z = zones[Math.abs(Math.round((ll.lat + ll.lng) * 1000)) % zones.length];
    setLoc({ ...ll, zone: z });
  }
  return (
    <div>
      <div className="map-wrap" style={{ height: tall ? 420 : 300 }}>
        <MapPicker mode="pick" center={window.MELD.center} mapStyle="satellite"
          value={loc} onChange={applyLoc} t={t} locateRef={locateRef}
          showGeofence={false}
          areas={serverAreas || []} />
        <button type="button" className="map-locate" onClick={() => { setBusy(true); locateRef.current && locateRef.current(); }}>
          <Ico name="locate-fixed" size={16} /> {busy ? t.locating : t.findloc}
        </button>
        {!loc && !locErr && <div className="map-tag">{t.map_hint}</div>}
      </div>
      {locErr && (
        <div className="notice notice-danger anim-up" style={{ marginTop: 10 }}>
          <Ico name="map-pin-x" size={16} /> <span>{locErr}</span>
        </div>
      )}
      {loc && (
        <div className="loc-readout anim-up">
          <Ico name="map-pin" size={16} />
          <div>
            <div className="loc-zone">{t.zone}: <strong>{loc.zone}</strong></div>
            <div className="loc-coords">{loc.lat.toFixed(5)}, {loc.lng.toFixed(5)}</div>
          </div>
        </div>
      )}
    </div>
  );
}

function SectionHead({ n, title, help }) {
  return (
    <div className="sec-head">
      {n != null && <span className="sec-num">{n}</span>}
      <div>
        <h3 className="sec-title">{title}</h3>
        {help && <p className="sec-help">{help}</p>}
      </div>
    </div>
  );
}

function SuccessView({ refId, t, onAgain }) {
  return (
    <div className="success anim-pop">
      <div className="success-mark"><Ico name="check" size={40} /></div>
      <h2 className="display success-title">{t.success_title}</h2>
      <p className="success-lead">{t.success_lead}</p>
      <div className="success-ref">{t.success_ref} <strong>{refId}</strong></div>
      <button className="btn btn-ghost" onClick={onAgain}><Ico name="rotate-ccw" size={16} /> {t.success_again}</button>
    </div>
  );
}

function ReportForm({ lang, t }) {
  const [cats, setCats] = useState([]);
  const [when, setWhen] = useState("now");
  const [desc, setDesc] = useState("");
  const [files, setFiles] = useState([]);
  const [loc, setLoc] = useState(null);
  const [locErr, setLocErr] = useState(null);
  const [contact, setContact] = useState({ name: "", email: "", phone: "", anon: false });
  const [done, setDone] = useState(null);
  const [err, setErr] = useState("");
  const [submitting, setSubmitting] = useState(false);

  const toggleCat = (id) => setCats((p) => (p.includes(id) ? p.filter((x) => x !== id) : [...p, id]));

  function reset() {
    setCats([]); setWhen("now"); setDesc(""); setFiles([]); setLoc(null); setLocErr(null);
    setContact({ name: "", email: "", phone: "", anon: false }); setDone(null); setErr(""); setSubmitting(false);
  }

  async function submit() {
    if (!cats.length) { setErr(t.required_what); return; }
    if (!loc) { setErr(t.required_where); return; }
    if (!contact.anon) {
      if (!contact.name) { setErr(t.required_name); return; }
      if (!contact.email && !contact.phone) { setErr(t.required_contact); return; }
    }

    setErr("");
    setSubmitting(true);

    const fd = new FormData();
    fd.append("latitude", String(loc.lat));
    fd.append("longitude", String(loc.lng));

    const catLabels = cats.map((id) => catById(id)[lang]).join(", ");
    const fullDesc = cats.length ? `[${catLabels}]\n${desc}`.trim() : desc;
    fd.append("description", fullDesc);
    fd.append("categories", JSON.stringify(cats));

    if (when !== "now") {
      fd.append("incident-date-time", when);
    }

    // timezone offset
    const tzOff = -Math.round(new Date().getTimezoneOffset() / 60);
    fd.append("tz-offset", String(tzOff));

    if (!contact.anon) {
      if (contact.name)  fd.append("reporter-name", contact.name);
      if (contact.email) fd.append("reporter-email", contact.email);
      if (contact.phone) fd.append("reporter-phone", contact.phone);
    }

    // Only first file supported by backend
    const firstFile = files.find((f) => f._file);
    if (firstFile) {
      fd.append("file", firstFile._file);
    }

    try {
      const resp = await fetch("/api/report", { method: "POST", body: fd });
      const data = await resp.json();
      if (data.success) {
        setDone(genRef(data.id));
      } else {
        setErr(data.error || t.submit_error);
        setSubmitting(false);
      }
    } catch (e) {
      setErr(t.submit_error);
      setSubmitting(false);
    }
  }

  if (done) return <div className="form-shell"><SuccessView refId={done} t={t} onAgain={reset} /></div>;

  const ctx = { cats, toggleCat, when, setWhen, desc, setDesc, files, setFiles, loc, setLoc, locErr, setLocErr, contact, setContact, lang, t, submitting };

  return <SteppedForm {...ctx} submit={submit} err={err} setErr={setErr} />;
}

window.ReportForm = ReportForm;
window.CategoryGrid = CategoryGrid;
window.WhenField = WhenField;
window.EvidenceField = EvidenceField;
window.ContactField = ContactField;
window.MapField = MapField;
window.SectionHead = SectionHead;
