/* portal-parts.jsx — zdieľané časti zamestnaneckého portálu (vzhľad, slovník, drobné
   komponenty). Dátovo nezávislé od transportu — pracujú len s tvarom tiketu, ktorý vracia
   portal-data.jsx (zuzTiket). */

/* ---------- tón komunikácie ---------- */
// PF.tone sa v produkcii nastavuje raz pri štarte portálu (portal.jsx) a nemení sa za behu —
// žiadny prepínač tónu nie je vystavený zamestnancom. Slovník necháme dvojaký (aj "vecny")
// pre prípad, že sa v budúcnosti rozhodneme tón zmeniť — je to lacné na údržbu.
const PF = { tone: "priatelsky" };

const TXT = {
  priatelsky: {
    eyebrow: null, // dynamický pozdrav
    heroH1: "S čím vám dnes pomôžeme?",
    heroSub: "Vyberte oblasť, ktorej sa problém týka — alebo nám jednoducho napíšte vlastnými slovami.",
    ctaNew: "Nahlásiť problém",
    hours: "Bežne odpovedáme do 2 hodín · Po–Pi 7:30–16:30",
    quickStart: "Rýchly štart podľa témy",
    myReq: "Moje požiadavky",
    emptyT: "Nemáte žiadne otvorené požiadavky",
    emptyD: "Ak niečo nefunguje, dajte nám vedieť — sme tu pre vás.",
    formH1: "Nahlásiť problém",
    formSub: "Stačí pár riadkov. Technik sa vám ozve e-mailom aj sem do portálu.",
    q1: "Čoho sa to týka?", q2: "Čo sa deje?", q3: "Ako veľmi vás to obmedzuje?",
    tip: "Tip: čím konkrétnejšie, tým rýchlejšie vieme pomôcť.",
    submit: "Odoslať požiadavku",
    next: "Čo bude nasledovať",
    okH1: "Máme to, ďakujeme!",
    okSub: "Vaša požiadavka bola zaevidovaná pod číslom",
    doneQ: "Funguje už všetko?",
    doneD: "Ak problém pretrváva, pokojne nám dajte vedieť — vrátime sa k nemu.",
    doneYes: "Áno, je to vyriešené",
  },
  vecny: {
    eyebrow: "Portál podpory IT",
    heroH1: "Nahlásenie požiadavky",
    heroSub: "Zvoľte kategóriu požiadavky alebo zadajte vlastný popis problému.",
    ctaNew: "Nová požiadavka",
    hours: "Reakčná doba do 2 h · prevádzka Po–Pi 7:30–16:30",
    quickStart: "Kategórie požiadaviek",
    myReq: "Zoznam požiadaviek",
    emptyT: "Žiadne otvorené požiadavky",
    emptyD: "Novú požiadavku zadáte tlačidlom vyššie.",
    formH1: "Nová požiadavka",
    formSub: "Vyplňte povinné polia. Odpoveď bude doručená e-mailom a do portálu.",
    q1: "Kategória a téma", q2: "Popis požiadavky", q3: "Dopad na prácu",
    tip: "Uveďte presné znenie chybovej hlášky, ak sa zobrazila.",
    submit: "Odoslať",
    next: "Priebeh spracovania",
    okH1: "Požiadavka bola odoslaná",
    okSub: "Evidenčné číslo požiadavky",
    doneQ: "Potvrdenie vyriešenia",
    doneD: "Potvrďte vyriešenie, alebo požiadavku vráťte na dopracovanie.",
    doneYes: "Potvrdiť vyriešenie",
  },
};
const txt = (k) => (TXT[PF.tone] && TXT[PF.tone][k] != null ? TXT[PF.tone][k] : TXT.priatelsky[k]);

/* farebné charaktery — "slnecna" zámerne rovnaký hex ako ACCENTS.orange v app.jsx
   (technický workspace), aby prípadná zhoda farieb naprieč appkou nebola náhodná. */
const PALETY = {
  modra:   { a: "#0f6cbd", h: "#115ea3", tl: "#e8f1fb", td: "#0c2c45" },
  zelena:  { a: "#0e7a6b", h: "#0c6b5d", tl: "#e3f3f0", td: "#0a2e29" },
  slnecna: { a: "#c2410c", h: "#9a3412", tl: "#fdeee4", td: "#3a1e0e" },
  fialova: { a: "#6b4fbb", h: "#5a41a0", tl: "#eeeafa", td: "#241d3d" },
};

/* rytmus rozloženia */
const RYTMUS = {
  hutny:      { hero: "26px", cardPad: "13px 15px", tilePad: "11px 12px", tilePadL: "13px 14px", gap: "8px", radius: "8px", h1: "26px", lh: "1.38" },
  vyvazeny:   { hero: "40px", cardPad: "16px 18px", tilePad: "13px 14px", tilePadL: "16px 16px", gap: "12px", radius: "10px", h1: "32px", lh: "1.45" },
  priestranny:{ hero: "64px", cardPad: "24px 26px", tilePad: "18px 20px", tilePadL: "22px 22px", gap: "18px", radius: "16px", h1: "40px", lh: "1.62" },
};

// Jediné miesto pravdy pre východiskovú tému portálu — portal.jsx ho posiela do
// applyPortalTheme() pri štarte. RYTMUS.vyvazeny (nižšie) a CSS fallback vo
// "Helpdesk PROPLUSCO.html" (--pf-hero/--pf-h1/... v :root, pred prvým vykreslením JS)
// musia mať rovnaké hodnoty ako RYTMUS[PORTAL_DEFAULT_TEMA.rhythm] — inak krátko pred
// spustením applyPortalTheme() naskočí hero sekcia s iným odsadením, než aké nastaví JS.
const PORTAL_DEFAULT_TEMA = { dark: false, palette: "modra", rhythm: "vyvazeny", tone: "priatelsky" };

function applyPortalTheme(t) {
  const root = document.documentElement;
  root.setAttribute("data-theme", t.dark ? "dark" : "light");
  const p = PALETY[t.palette] || PALETY.modra;
  root.style.setProperty("--accent", p.a);
  root.style.setProperty("--accent-hover", p.h);
  root.style.setProperty("--accent-tint", t.dark ? p.td : p.tl);
  const r = RYTMUS[t.rhythm] || RYTMUS.vyvazeny;
  root.style.setProperty("--pf-hero", r.hero);
  root.style.setProperty("--pf-card-pad", r.cardPad);
  root.style.setProperty("--pf-tile-pad", r.tilePad);
  root.style.setProperty("--pf-tile-pad-l", r.tilePadL);
  root.style.setProperty("--pf-gap", r.gap);
  root.style.setProperty("--radius-lg", r.radius);
  root.style.setProperty("--pf-h1", r.h1);
  document.body.style.lineHeight = r.lh;
  PF.tone = t.tone || PF.tone;
}

const STAV_LUDSKY = {
  "Nový": { label: "Prijaté", pop: "Vašu požiadavku sme dostali a čoskoro ju prevezme technik.", krok: 0, farba: "var(--c-novy)" },
  "Priradený": { label: "Priradené technikovi", pop: "Požiadavku prevzal technik a čoskoro sa jej začne venovať.", krok: 1, farba: "var(--c-prirad)" },
  "V riešení": { label: "Pracujeme na tom", pop: "Technik na vašej požiadavke práve pracuje.", krok: 1, farba: "var(--c-riesi)" },
  "Čaká na zákazníka": { label: "Čakáme na vás", pop: "Technik potrebuje od vás doplniť informáciu.", krok: 1, farba: "var(--c-caka)" },
  "Vyriešený": { label: "Vyriešené", pop: "Technik označil požiadavku za vyriešenú. Dajte nám vedieť, či všetko funguje.", krok: 2, farba: "var(--c-vyrie)" },
  "Zatvorený": { label: "Uzavreté", pop: "Požiadavka je uzavretá.", krok: 2, farba: "var(--c-zatv)" },
};
const STAV_VECNY = {
  "Nový": { label: "Nová", pop: "Požiadavka bola zaevidovaná a čaká na pridelenie technikovi.", krok: 0, farba: "var(--c-novy)" },
  "Priradený": { label: "Pridelená", pop: "Požiadavka bola pridelená technikovi.", krok: 1, farba: "var(--c-prirad)" },
  "V riešení": { label: "V riešení", pop: "Na požiadavke prebieha riešenie.", krok: 1, farba: "var(--c-riesi)" },
  "Čaká na zákazníka": { label: "Čaká na doplňujúce informácie", pop: "Riešenie čaká na vašu odpoveď.", krok: 1, farba: "var(--c-caka)" },
  "Vyriešený": { label: "Vyriešená", pop: "Technik označil požiadavku za vyriešenú. Čaká sa na vaše potvrdenie.", krok: 2, farba: "var(--c-vyrie)" },
  "Zatvorený": { label: "Uzavretá", pop: "Požiadavka bola uzavretá.", krok: 2, farba: "var(--c-zatv)" },
};
const stavInfo = (s) => (PF.tone === "vecny" ? STAV_VECNY[s] : STAV_LUDSKY[s]) || STAV_LUDSKY["Nový"];

const KROKY = () => (PF.tone === "vecny" ? ["Čaká na váš vstup", "V riešení", "Uzavretá"] : ["Čakáme na vás", "Riešime", "Hotovo"]);

/* stav → svetlo semaforu (stav sa môže vracať späť, preto semafor a nie postupový pruh)
   červená = čaká sa na používateľa · oranžová = na strane IT · zelená = vybavené */
const SEMAFOR = {
  "Čaká na zákazníka": 0,
  "Nový": 1, "Priradený": 1, "V riešení": 1,
  "Vyriešený": 2, "Zatvorený": 2,
};
const SEM_FARBY = ["var(--red)", "var(--p-vysoka)", "var(--green)"];
const semFarba = (stav) => SEM_FARBY[SEMAFOR[stav]];

const KAT_IKONY = {
  "Hardvér": "settings", "Softvér": "grid", "Sieť": "chart", "Iné": "note",
};
const TEMA_IKONY = {
  "Tlačiarne a periférie": "file", "Hardvérové poruchy": "settings",
  "Heslá a prístupy": "person", "E-mail a Outlook": "mail", "Inštalácie softvéru": "grid",
  "VPN a vzdialený prístup": "attach", "Sieť a internet": "chart",
  "Zmena nastavení konta": "person", "Iné": "note",
};

/* rady na svojpomoc — zobrazia sa podľa zvolenej témy */
const RADY = {
  "Heslá a prístupy": [
    { t: "Zabudnuté heslo si viete zmeniť sami", d: "Na prihlasovacej obrazovke kliknite na „Nepamätám si heslo“ a overte sa cez SMS." },
    { t: "Účet je uzamknutý po 5 pokusoch", d: "Odomkne sa sám po 15 minútach. Ak sa ponáhľate, napíšte nám." },
  ],
  "E-mail a Outlook": [
    { t: "Outlook nezobrazuje nové správy", d: "Skúste Súbor → Nastavenia účtu → Opraviť. Vo väčšine prípadov to pomôže." },
  ],
  "Tlačiarne a periférie": [
    { t: "Tlačiareň netlačí", d: "Skontrolujte, či na displeji nesvieti chyba a či nie je vo fronte zaseknutá staršia úloha." },
  ],
  "VPN a vzdialený prístup": [
    { t: "VPN sa nepripojí", d: "Odpojte sa, počkajte 10 sekúnd a skúste znova. Pomáha aj prepnutie z Wi-Fi na mobilné dáta." },
  ],
  "Inštalácie softvéru": [
    { t: "Firemné aplikácie si nainštalujete sami", d: "Otvorte Company Portal na svojom počítači — nájdete tam schválený softvér." },
  ],
};

const NALIEHAVOST = [
  { id: "Nízka", nadpis: "Počká", popis: "Nebráni mi to v práci, stačí keď sa to vyrieši v najbližších dňoch.", ikona: "clock", farba: "var(--p-nizka)" },
  { id: "Stredná", nadpis: "Obmedzuje ma to", popis: "Pracovať sa dá, ale zdržuje ma to alebo musím obchádzať problém.", ikona: "warning", farba: "var(--p-stred)" },
  { id: "Vysoká", nadpis: "Nemôžem pracovať", popis: "Bez vyriešenia neviem pokračovať v práci.", ikona: "warning", farba: "var(--p-vysoka)" },
];
const NALIEHAVOST_VECNA = [
  { id: "Nízka", nadpis: "Nízky dopad", popis: "Práca nie je ohrozená, riešenie v štandardnej lehote.", ikona: "clock", farba: "var(--p-nizka)" },
  { id: "Stredná", nadpis: "Stredný dopad", popis: "Práca je možná s obmedzením alebo náhradným postupom.", ikona: "warning", farba: "var(--p-stred)" },
  { id: "Vysoká", nadpis: "Vysoký dopad", popis: "Prácu nie je možné vykonávať.", ikona: "warning", farba: "var(--p-vysoka)" },
];
const naliehavosti = () => (PF.tone === "vecny" ? NALIEHAVOST_VECNA : NALIEHAVOST);

/* ---------- semafor stavu ---------- */
function Stepper({ stav, kompakt, bezPopisu }) {
  const info = stavInfo(stav);
  const aktivne = SEMAFOR[stav];
  const popisky = KROKY();
  const lampa = kompakt ? 11 : 15;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: kompakt ? 10 : 14, flexWrap: "wrap" }}>
      <div style={{
        display: "flex", alignItems: "center", gap: kompakt ? 6 : 8, padding: kompakt ? "5px 8px" : "7px 11px",
        borderRadius: 999, background: "var(--surface-3)", border: "1px solid var(--stroke)", flex: "0 0 auto",
      }}>
        {[0, 1, 2].map((i) => {
          const on = i === aktivne;
          const f = on ? info.farba : "var(--text-3)";
          return (
            <span key={i} title={popisky[i]} style={{
              width: lampa, height: lampa, borderRadius: "50%", display: "block",
              background: on ? f : "color-mix(in srgb, " + f + " 18%, transparent)",
              boxShadow: on ? "0 0 0 3px color-mix(in srgb, " + f + " 22%, transparent)" : "inset 0 0 0 1px color-mix(in srgb, " + f + " 24%, transparent)",
              transition: "background .18s, box-shadow .18s",
            }} />
          );
        })}
      </div>
      {!bezPopisu && (
        <span style={{ fontSize: kompakt ? 12 : 13.5, fontWeight: 700, color: info.farba, letterSpacing: "-.01em" }}>
          {info.label}
        </span>
      )}
    </div>
  );
}

/* ---------- ľudský stavový štítok ---------- */
function StavPill({ stav, velky }) {
  const info = stavInfo(stav);
  const f = info.farba;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 7, padding: velky ? "6px 14px" : "4px 11px", borderRadius: 999,
      fontSize: velky ? 13 : 12, fontWeight: 600, color: f, whiteSpace: "nowrap",
      background: "color-mix(in srgb, " + f + " 12%, transparent)",
      border: "1px solid color-mix(in srgb, " + f + " 26%, transparent)",
    }}>
      <span style={{ width: 7, height: 7, borderRadius: "50%", background: f }} />{info.label}
    </span>
  );
}

/* ---------- dlaždica ---------- */
function Tile({ ikona, nadpis, popis, aktivna, onClick, kompakt }) {
  const [hover, setHover] = useState(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} style={{
      display: "flex", flexDirection: "column", alignItems: "flex-start", gap: kompakt ? 7 : 9, textAlign: "left",
      padding: kompakt ? "var(--pf-tile-pad)" : "var(--pf-tile-pad-l)", borderRadius: "var(--radius-lg)", width: "100%",
      background: aktivna ? "var(--accent-tint)" : "var(--surface)",
      border: "1px solid " + (aktivna ? "color-mix(in srgb, var(--accent) 42%, transparent)" : hover ? "var(--stroke-strong)" : "var(--stroke)"),
      boxShadow: hover && !aktivna ? "var(--shadow-md)" : "var(--shadow-sm)",
      transform: hover ? "translateY(-1px)" : "none", transition: "transform .12s, box-shadow .12s, border-color .12s, background .12s",
    }}>
      <span style={{
        width: kompakt ? 30 : 36, height: kompakt ? 30 : 36, borderRadius: 9, display: "inline-flex", alignItems: "center", justifyContent: "center",
        background: aktivna ? "var(--accent)" : "color-mix(in srgb, var(--accent) 12%, transparent)", color: aktivna ? "#fff" : "var(--accent)",
      }}><Icon name={ikona} size={kompakt ? 17 : 19} /></span>
      <span style={{ fontSize: kompakt ? 13 : 14, fontWeight: 700, color: "var(--text)", lineHeight: 1.3 }}>{nadpis}</span>
      {popis && <span style={{ fontSize: 12, color: "var(--text-3)", lineHeight: 1.4 }}>{popis}</span>}
    </button>
  );
}

/* ---------- karta požiadavky v zozname ----------
   posledna môže byť undefined (tiket bez jedinej správy — vie vzniknúť, ak zápis prvej
   správy zlyhá medzi vytvorením tiketu a zápisom komunikácie). Bez tohto fallbacku by
   jeden takýto riadok zhodil celý portál rovnako, ako to predtým robilo v TicketRow
   na technickej strane (panels.jsx) — pozri komentár tam. */
function PoziadavkaKarta({ t, onClick }) {
  const [hover, setHover] = useState(false);
  const posledna = t.komunikacia.length ? t.komunikacia[t.komunikacia.length - 1] : null;
  const odpovedTechnika = posledna && posledna.typ === "Odpoveď zákazníkovi";
  const cakaNaMna = t.stav === "Čaká na zákazníka";
  return (
    <button onClick={onClick} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} style={{
      display: "block", width: "100%", textAlign: "left", padding: "var(--pf-card-pad)", borderRadius: "var(--radius-lg)",
      background: "var(--surface)", border: "1px solid " + (cakaNaMna ? "color-mix(in srgb, var(--c-caka) 45%, transparent)" : hover ? "var(--stroke-strong)" : "var(--stroke)"),
      boxShadow: hover ? "var(--shadow-md)" : "var(--shadow-sm)", transition: "box-shadow .12s, border-color .12s, transform .12s",
      transform: hover ? "translateY(-1px)" : "none",
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8, flexWrap: "wrap" }}>
        <StavPill stav={t.stav} />
        <span style={{ fontSize: 11.5, color: "var(--text-3)", fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{t.cislo}</span>
        <span style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--text-3)" }}>{fmtRelative(posledna ? posledna.cas : t.vytvorene)}</span>
      </div>
      <div style={{ fontSize: 15, fontWeight: 700, letterSpacing: "-.01em", marginBottom: 6, lineHeight: 1.3 }}>{t.predmet}</div>
      <div style={{ fontSize: 12.5, color: "var(--text-2)", display: "flex", alignItems: "center", gap: 7, marginBottom: 12 }}>
        <Icon name={TEMA_IKONY[t.podkategoria] || "note"} size={14} style={{ color: "var(--text-3)" }} />
        {t.podkategoria}
        {t.technik && <><span style={{ color: "var(--text-3)" }}>·</span> rieši {t.technik.split(" ")[0]}</>}
      </div>
      {cakaNaMna && (
        <div style={{ display: "flex", alignItems: "center", gap: 7, padding: "8px 11px", borderRadius: "var(--radius)", background: "color-mix(in srgb, var(--c-caka) 10%, transparent)", color: "var(--c-caka)", fontSize: 12.5, fontWeight: 600, marginBottom: 12 }}>
          <Icon name="warning" size={14} /> Technik čaká na vašu odpoveď
        </div>
      )}
      {!cakaNaMna && odpovedTechnika && !["Vyriešený", "Zatvorený"].includes(t.stav) && (
        <div style={{ display: "flex", alignItems: "center", gap: 7, fontSize: 12.5, color: "var(--text-2)", marginBottom: 12 }}>
          <Icon name="mail" size={14} style={{ color: "var(--accent)" }} /> Nová odpoveď od technika
        </div>
      )}
      <Stepper stav={t.stav} kompakt bezPopisu />
    </button>
  );
}

Object.assign(window, {
  PF, TXT, txt, PALETY, RYTMUS, PORTAL_DEFAULT_TEMA, applyPortalTheme, STAV_LUDSKY, STAV_VECNY, stavInfo, KROKY,
  SEMAFOR, SEM_FARBY, semFarba, NALIEHAVOST, naliehavosti, KAT_IKONY, TEMA_IKONY, RADY,
  Stepper, StavPill, Tile, PoziadavkaKarta,
});
