/* oznamy.jsx — správa oznamov IT priamo v hube (PLAN.md 6.1). Len pre Super admina (IT):
   tlačidlo vidí len on a backend to overí znova z tokenu. Oznam sa dá pridať, upraviť a ukončiť
   (platí do = teraz); zmazať sa dá len v SharePointe (rozhodnutie Jakuba, 2026-10-06).
   Vystavuje window.SpravaOznamov a window.NAHLAD_OZNAMY_API (náhľad bez backendu).
*/
(function () {
  "use strict";

  const { useState, useEffect, useRef, useCallback } = React;

  const TYPY = [{ id: "oznam", nazov: "Oznam" }, { id: "vypadok", nazov: "Výpadok" }];
  const FIRMY = [{ id: "vsetci", nazov: "Všetci" }, { id: "PROPLUSCO", nazov: "PROPLUSCO" }, { id: "PLUSIM", nazov: "PLUSIM" }];
  const STAVY = { aktivny: "Aktívny", naplanovany: "Naplánovaný", skonceny: "Skončený" };
  const PRAZDNY = { nadpis: "", text: "", typ: "oznam", firma: "vsetci", platiOd: "", platiDo: "" };

  // ISO (UTC) ↔ hodnota <input type="datetime-local"> v miestnom čase.
  function doPola(iso) {
    if (!iso) return "";
    const d = new Date(iso);
    if (isNaN(d)) return "";
    const p = (n) => String(n).padStart(2, "0");
    return d.getFullYear() + "-" + p(d.getMonth() + 1) + "-" + p(d.getDate()) + "T" + p(d.getHours()) + ":" + p(d.getMinutes());
  }
  const zPola = (v) => (v ? new Date(v).toISOString() : "");

  function datumText(iso) {
    if (!iso) return "";
    return new Date(iso).toLocaleString("sk-SK", { day: "numeric", month: "numeric", year: "numeric", hour: "2-digit", minute: "2-digit" });
  }
  function platnost(o) {
    if (o.platiOd && o.platiDo) return datumText(o.platiOd) + " – " + datumText(o.platiDo);
    if (o.platiOd) return "od " + datumText(o.platiOd);
    if (o.platiDo) return "do " + datumText(o.platiDo);
    return "bez obmedzenia";
  }

  // Tab ostane v dialógu (modálny), Escape zatvorí.
  function useModal(okno, onZavriet) {
    useEffect(() => {
      const predtym = document.activeElement;
      document.body.classList.add("bez-scrollu");
      const prvy = okno.current && okno.current.querySelector("input, textarea, select, button");
      prvy && prvy.focus();
      function klaves(e) {
        if (e.key === "Escape") { e.preventDefault(); onZavriet(); return; }
        if (e.key !== "Tab" || !okno.current) return;
        const prvky = [...okno.current.querySelectorAll("button, input, textarea, select, a[href]")].filter((el) => !el.disabled);
        if (!prvky.length) return;
        const i = prvky.indexOf(document.activeElement);
        if (e.shiftKey && i <= 0) { e.preventDefault(); prvky[prvky.length - 1].focus(); }
        else if (!e.shiftKey && i === prvky.length - 1) { e.preventDefault(); prvky[0].focus(); }
      }
      document.addEventListener("keydown", klaves);
      return () => {
        document.removeEventListener("keydown", klaves);
        document.body.classList.remove("bez-scrollu");
        if (predtym && predtym.focus && predtym !== document.body) predtym.focus();
      };
    }, []);
  }

  function Formular({ povodny, onUloz, onZrus, ukladam }) {
    const [o, setO] = useState(() => povodny
      ? { nadpis: povodny.nadpis, text: povodny.text || "", typ: povodny.typ, firma: povodny.firma,
          platiOd: doPola(povodny.platiOd), platiDo: doPola(povodny.platiDo) }
      : PRAZDNY);
    const nastav = (k) => (e) => setO({ ...o, [k]: e.target.value });
    const prvy = useRef(null);
    useEffect(() => { prvy.current && prvy.current.focus(); }, []);

    function odoslat(e) {
      e.preventDefault();
      onUloz({ ...o, nadpis: o.nadpis.trim(), text: o.text.trim(), platiOd: zPola(o.platiOd), platiDo: zPola(o.platiDo) });
    }

    return (
      <form className="sprava__form" onSubmit={odoslat}>
        <h3>{povodny ? "Upraviť oznam" : "Nový oznam"}</h3>
        <fieldset className="sprava__typ">
          <legend>Typ</legend>
          {TYPY.map((t) => (
            <label key={t.id} className="sprava__volba">
              <input type="radio" name="typ" value={t.id} checked={o.typ === t.id} onChange={nastav("typ")} />
              {t.nazov}
            </label>
          ))}
        </fieldset>
        <p className="sprava__napoveda">
          {o.typ === "vypadok" ? "Výpadok sa ukáže ako oranžový banner nad pozdravom." : "Oznam sa ukáže na karte „Oznam IT“ v pravom stĺpci."}
        </p>
        <label className="pole">
          <span>Nadpis</span>
          <input ref={prvy} type="text" required maxLength={120} value={o.nadpis} onChange={nastav("nadpis")} />
        </label>
        <label className="pole">
          <span>Text <em>(nepovinný)</em></span>
          <textarea rows={4} maxLength={2000} value={o.text} onChange={nastav("text")} />
        </label>
        <div className="pole-riadok">
          <label className="pole">
            <span>Platí od <em>(prázdne = hneď)</em></span>
            <input type="datetime-local" value={o.platiOd} onChange={nastav("platiOd")} />
          </label>
          <label className="pole">
            <span>Platí do <em>(prázdne = bez konca)</em></span>
            <input type="datetime-local" value={o.platiDo} onChange={nastav("platiDo")} />
          </label>
        </div>
        <label className="pole">
          <span>Pre koho</span>
          <select value={o.firma} onChange={nastav("firma")}>
            {FIRMY.map((f) => <option key={f.id} value={f.id}>{f.nazov}</option>)}
          </select>
        </label>
        <div className="sprava__akcie">
          <button type="submit" className="btn btn--primarne" disabled={ukladam}>{ukladam ? "Ukladám…" : "Uložiť"}</button>
          <button type="button" className="btn btn--sekundarne" onClick={onZrus} disabled={ukladam}>Zrušiť</button>
        </div>
      </form>
    );
  }

  function SpravaOznamov({ api, onZavriet, onZmena }) {
    const okno = useRef(null);
    const [zoznam, setZoznam] = useState(null);
    const [chyba, setChyba] = useState(null);
    const [upravujem, setUpravujem] = useState(null); // null | "novy" | oznam
    const [ukladam, setUkladam] = useState(false);
    useModal(okno, onZavriet);

    const nacitaj = useCallback(() => {
      setChyba(null);
      api.zoznam().then(setZoznam).catch((e) => { setZoznam([]); setChyba(e.message); });
    }, [api]);
    useEffect(nacitaj, [nacitaj]);

    async function uloz(o) {
      setUkladam(true); setChyba(null);
      try {
        if (upravujem === "novy") await api.vytvor(o); else await api.uprav(upravujem.id, o);
        setUpravujem(null); nacitaj(); onZmena();
      } catch (e) { setChyba(e.message); }
      setUkladam(false);
    }

    async function ukonci(o) {
      if (!window.confirm("Ukončiť „" + o.nadpis + "“? Z hubu zmizne hneď; v SharePointe ostane.")) return;
      setChyba(null);
      try { await api.ukonci(o.id); nacitaj(); onZmena(); } catch (e) { setChyba(e.message); }
    }

    return (
      <div className="dialog" onMouseDown={(e) => { if (e.target === e.currentTarget && !upravujem) onZavriet(); }}>
        <div className="dialog__okno" ref={okno} role="dialog" aria-modal="true" aria-labelledby="sprava-h">
          <div className="dialog__hlava">
            <h2 id="sprava-h">Oznamy IT</h2>
            <button type="button" className="ikona-btn" onClick={onZavriet} aria-label="Zavrieť"><Icon name="zavriet" size={20} /></button>
          </div>
          <div className="dialog__telo">
            {chyba && <p className="sprava__chyba" role="alert">{chyba}</p>}
            {upravujem ? (
              <Formular povodny={upravujem === "novy" ? null : upravujem} ukladam={ukladam}
                onUloz={uloz} onZrus={() => { setUpravujem(null); setChyba(null); }} />
            ) : (
              <>
                <div className="sprava__lista">
                  <p>Oznamy a výpadky vidia zamestnanci na domovskej obrazovke.</p>
                  <button type="button" className="btn btn--primarne" onClick={() => setUpravujem("novy")}>
                    <Icon name="plus" size={18} strokeWidth={2.4} /> Nový oznam
                  </button>
                </div>
                {zoznam === null ? <p className="sprava__info">Načítavam…</p>
                  : zoznam.length === 0 ? <p className="sprava__info">Zatiaľ žiadne oznamy.</p>
                  : (
                    <ul className="sprava__zoznam">
                      {zoznam.map((o) => (
                        <li key={o.id} className={"sprava__polozka sprava__polozka--" + o.stav}>
                          <div className="sprava__text">
                            <span className="sprava__stitky">
                              <span className={"sprava__stav sprava__stav--" + o.stav}>{STAVY[o.stav]}</span>
                              <span>{o.typ === "vypadok" ? "Výpadok" : "Oznam"} · {o.firma === "vsetci" ? "Všetci" : o.firma}</span>
                            </span>
                            <span className="sprava__nadpis">{o.nadpis}</span>
                            <span className="sprava__meta">{platnost(o)}{o.zadal ? " · " + o.zadal : ""}</span>
                          </div>
                          <div className="sprava__tlacidla">
                            <button type="button" className="btn btn--sekundarne btn--male" onClick={() => setUpravujem(o)}>Upraviť</button>
                            {o.stav !== "skonceny" && (
                              <button type="button" className="btn btn--sekundarne btn--male" onClick={() => ukonci(o)}>Ukončiť</button>
                            )}
                          </div>
                        </li>
                      ))}
                    </ul>
                  )}
              </>
            )}
          </div>
        </div>
      </div>
    );
  }

  // Náhľad (?nahlad=1): rovnaké rozhranie nad dátami v pamäti — nič sa nezapisuje.
  function nahladApi() {
    const h = (ms) => new Date(Date.now() + ms * 3600000).toISOString();
    let data = [
      { id: "3", nadpis: "Plánovaná údržba tiketovacieho systému", text: "Sobota 10. 10., 18:00 – 20:00.", typ: "oznam", firma: "vsetci", platiOd: null, platiDo: h(80), zadal: "Jakub Pernecký", stav: "aktivny" },
      { id: "2", nadpis: "Výmena firewallu", text: "", typ: "vypadok", firma: "PROPLUSCO", platiOd: h(48), platiDo: h(50), zadal: "Peter Poloma", stav: "naplanovany" },
      { id: "1", nadpis: "Výpadok VPN", text: "Vyriešené.", typ: "vypadok", firma: "vsetci", platiOd: h(-30), platiDo: h(-26), zadal: "Jakub Pernecký", stav: "skonceny" },
    ];
    const cakaj = (v) => new Promise((r) => setTimeout(() => r(v), 250));
    const stav = (o) => (o.platiDo && Date.parse(o.platiDo) < Date.now() ? "skonceny" : o.platiOd && Date.parse(o.platiOd) > Date.now() ? "naplanovany" : "aktivny");
    return {
      zoznam: () => cakaj(data.map((o) => ({ ...o }))),
      vytvor: (o) => { if (!o.nadpis) return Promise.reject(new Error("Nadpis je povinný."));
        data = [{ ...o, id: String(Date.now()), zadal: "Náhľad Používateľ", stav: stav(o) }, ...data]; return cakaj({}); },
      uprav: (id, o) => { data = data.map((x) => (x.id === id ? { ...x, ...o, stav: stav(o) } : x)); return cakaj({}); },
      ukonci: (id) => { data = data.map((x) => (x.id === id ? { ...x, platiDo: new Date().toISOString(), stav: "skonceny" } : x)); return cakaj({}); },
    };
  }

  window.SpravaOznamov = SpravaOznamov;
  window.NAHLAD_OZNAMY_API = nahladApi;
})();
