/* NGIPL PLM — app shell */
const { useState, useEffect, useMemo, useCallback } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "density": "comfortable",
  "printHeader": "charcoal"
}/*EDITMODE-END*/;

function App() {
  const state = PLM.useStore();
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [tab, setTab] = useState("master");
  const [partyId, setPartyId] = useState(state.parties.length ? state.parties[0].id : null);
  const [printSource, setPrintSource] = useState("general");
  const [activeQuoteId, setActiveQuoteId] = useState(null);
  const [historyOpen, setHistoryOpen] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [toasts, setToasts] = useState([]);

  const toast = useCallback((msg) => {
    const id = Date.now() + Math.random();
    setToasts((ts) => [...ts.slice(-2), { id, msg }]);
    setTimeout(() => setToasts((ts) => ts.filter((x) => x.id !== id)), 3600);
  }, []);

  const nav = useMemo(() => ({
    goParty(id) { setPartyId(id); setTab("parties"); },
    goPrint(sourceId) { setPrintSource(sourceId || "general"); setTab("print"); },
    goTab(id) { setTab(id); },
  }), []);

  const staleTotal = PLM.totalStale();

  return (
    <div className={t.density === "compact" ? "density-compact" : ""}>
      <div className="app-chrome">
        <header className="app-top">
          <div className="app-top-inner">
            <img className="app-logo" src="assets/logos/monogram-black-cropped.png" alt="NGIPL monogram" />
            <div className="app-wordmark">
              <div className="wm-name">NATHURMAL</div>
              <div className="wm-sub">GLOBAL INDUSTRIES PVT. LTD.</div>
            </div>
            <div className="app-top-divider"></div>
            <div className="app-title">Price List Manager</div>
            <div className="app-top-right">
              <EditorField state={state}></EditorField>
              <IconBtn title="History" onClick={() => setHistoryOpen(true)}><IHistory size={17}></IHistory></IconBtn>
              <IconBtn title="Settings" onClick={() => setSettingsOpen(true)}><ISliders size={17}></ISliders></IconBtn>
            </div>
          </div>
        </header>
        <nav className="app-tabs-band">
          <div className="app-tabs" role="tablist">
            <button type="button" role="tab" aria-selected={tab === "master"}
              className={"app-tab" + (tab === "master" ? " app-tab--active" : "")} onClick={() => setTab("master")}>
              Master price list
            </button>
            <button type="button" role="tab" aria-selected={tab === "parties"}
              className={"app-tab" + (tab === "parties" ? " app-tab--active" : "")} onClick={() => setTab("parties")}>
              Party rates
              {staleTotal ? <span className="chip chip--warn tab-badge" style={{ fontSize: 9, padding: "1px 6px" }}>{staleTotal}</span> : null}
            </button>
            <button type="button" role="tab" aria-selected={tab === "quotes"}
              className={"app-tab" + (tab === "quotes" ? " app-tab--active" : "")} onClick={() => setTab("quotes")}>
              Quotations
            </button>
            <button type="button" role="tab" aria-selected={tab === "print"}
              className={"app-tab" + (tab === "print" ? " app-tab--active" : "")} onClick={() => setTab("print")}>
              Print &amp; export
            </button>
          </div>
        </nav>
      </div>

      <main className="app-main">
        {tab === "master" ? <MasterView nav={nav} toast={toast}></MasterView> : null}
        {tab === "parties" ? <PartiesView nav={nav} selectedId={partyId} onSelect={setPartyId} toast={toast}></PartiesView> : null}
        {tab === "quotes" ? <QuotesView nav={nav} toast={toast} activeId={activeQuoteId} onActive={setActiveQuoteId} headerStyle={t.printHeader}></QuotesView> : null}
        {tab === "print" ? <PrintView source={printSource} onSource={setPrintSource} headerStyle={t.printHeader} onHeaderStyle={(v) => setTweak("printHeader", v)} nav={nav}></PrintView> : null}
      </main>

      {historyOpen ? <HistoryDrawer onClose={() => setHistoryOpen(false)}></HistoryDrawer> : null}
      {settingsOpen ? <SettingsDialog onClose={() => setSettingsOpen(false)} toast={toast}></SettingsDialog> : null}
      <ToastHost toasts={toasts}></ToastHost>

      <TweaksPanel>
        <TweakSection label="Tables"></TweakSection>
        <TweakRadio label="Density" value={t.density} options={["comfortable", "compact"]}
          onChange={(v) => setTweak("density", v)}></TweakRadio>
        <TweakSection label="Printed sheet"></TweakSection>
        <TweakRadio label="Header" value={t.printHeader} options={["charcoal", "minimal"]}
          onChange={(v) => setTweak("printHeader", v)}></TweakRadio>
      </TweaksPanel>
    </div>
  );
}

function EditorField({ state }) {
  const [v, setV] = useState(state.settings.editor || "");
  useEffect(() => { setV(state.settings.editor || ""); }, [state.settings.editor]);
  return (
    <label style={{ display: "inline-flex", alignItems: "center", gap: 8 }} title="Your initials — recorded against every price change">
      <span className="f-label" style={{ margin: 0 }}>Editing as</span>
      <input className="f-input" style={{ width: 64, height: 30, fontSize: 12, textTransform: "uppercase", textAlign: "center", letterSpacing: "0.1em" }}
        maxLength={4} placeholder="AB" value={v}
        onChange={(e) => setV(e.target.value.toUpperCase())}
        onBlur={() => PLM.setSettings({ editor: v.trim() })} />
    </label>
  );
}

const HIST_ICONS = {
  rate: IPencil, bulk: IPercent, product: IPlus, party: IJump, wef: IHistory, import: ICheck, quote: IChevronR, print: IPrinter,
};
const HIST_FILTERS = [
  ["all", "All"], ["rate", "Rates"], ["bulk", "Bulk"], ["party", "Parties"],
  ["quote", "Quotes"], ["print", "Printed"], ["product", "Items"],
];
function HistoryDrawer({ onClose }) {
  const state = PLM.useStore();
  const [expanded, setExpanded] = useState({});
  const [flt, setFlt] = useState("all");
  const entries = flt === "all" ? state.history : state.history.filter((h) => h.type === flt);
  useEffect(() => {
    function onKey(e) { if (e.key === "Escape") onClose(); }
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [onClose]);
  return (
    <React.Fragment>
      <div className="drawer-scrim" onClick={onClose}></div>
      <div className="drawer" data-screen-label="Revision History">
        <div className="dlg-head">
          <div className="dlg-title">Revision history</div>
          <IconBtn title="Close" onClick={onClose}><IX size={16}></IX></IconBtn>
        </div>
        <div style={{ display: "flex", gap: 6, padding: "10px 20px", borderBottom: "1px solid var(--border-subtle)", flexWrap: "wrap" }}>
          {HIST_FILTERS.map(([id, label]) => (
            <button key={id} type="button" className={"fchip" + (flt === id ? " fchip--on" : "")} onClick={() => setFlt(id)}>{label}</button>
          ))}
        </div>
        <div className="drawer-body">
          {entries.map((h) => {
            const Ic = HIST_ICONS[h.type] || IHistory;
            return (
              <div className="hist-item" key={h.id}>
                <div style={{ display: "flex", gap: 10 }}>
                  <span style={{ color: "var(--gray-500)", paddingTop: 2 }}><Ic size={14}></Ic></span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="hist-label">{h.label}</div>
                    {h.note ? <div className="caption" style={{ marginTop: 2 }}>{h.note}</div> : null}
                    <div className="hist-meta">{h.editor} · {PLM.fmtDate(h.ts)}</div>
                    {h.changes && h.changes.length ? (
                      <React.Fragment>
                        <button type="button" className="fchip" style={{ marginTop: 6 }}
                          onClick={() => setExpanded({ ...expanded, [h.id]: !expanded[h.id] })}>
                          {expanded[h.id] ? "Hide" : "Show"} {h.changes.length} changes
                        </button>
                        {expanded[h.id] ? (
                          <div className="hist-changes">
                            {h.changes.map((c, i) => (
                              <div key={i}>
                                <span style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{c.name}</span>
                                <span className="tnum" style={{ whiteSpace: "nowrap" }}>₹{PLM.fmtRate(c.old)} → ₹{PLM.fmtRate(c.new)}</span>
                              </div>
                            ))}
                          </div>
                        ) : null}
                      </React.Fragment>
                    ) : null}
                  </div>
                </div>
              </div>
            );
          })}
          {!entries.length ? <div className="caption" style={{ padding: 20 }}>No {flt === "all" ? "changes" : "entries in this filter"} yet.</div> : null}
        </div>
      </div>
    </React.Fragment>
  );
}

function SettingsDialog({ onClose, toast }) {
  const state = PLM.useStore();
  const [confirmReset, setConfirmReset] = useState(false);
  return (
    <Dialog title="Settings" onClose={onClose} width={560}
      footer={<Btn variant="ghost" size="sm" onClick={onClose}>Close</Btn>}>
      <div className="f-stack">
        <div className="f-row">
          <Field label="Effective date (W.E.F.)">
            <WefField value={state.settings.wef} onChange={(v) => PLM.setWef(v)}></WefField>
          </Field>
          <Field label="Default billing entity (general list)">
            <select className="f-select" value={state.settings.defaultEntityId} onChange={(e) => PLM.setSettings({ defaultEntityId: e.target.value })}>
              {state.entities.map((en) => <option key={en.id} value={en.id}>{en.name}</option>)}
            </select>
          </Field>
        </div>
        <Field label="Printed footer note">
          <textarea className="f-textarea" rows={2} value={state.settings.priceNote} onChange={(e) => PLM.setSettings({ priceNote: e.target.value })}></textarea>
        </Field>
        <div>
          <div className="f-label">Billing entities</div>
          <div className="panel">
            {state.entities.map((en) => (
              <div key={en.id} style={{ padding: "10px 14px", borderBottom: "1px solid var(--border-subtle)" }}>
                <div style={{ fontWeight: 600, fontSize: 13 }}>{en.name}</div>
                <div className="caption">GST {en.gst} · FSSAI {en.fssai} · {en.email}</div>
              </div>
            ))}
          </div>
        </div>
        <div style={{ borderTop: "1px solid var(--border-default)", paddingTop: 14 }}>
          <div className="f-label">Backup</div>
          <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
            <Btn variant="secondary" size="sm" onClick={() => {
              const a = document.createElement("a");
              a.href = URL.createObjectURL(new Blob([PLM.exportSnapshot()], { type: "application/json" }));
              a.download = "NGIPL Price Data " + new Date().toISOString().slice(0, 10) + ".json";
              a.click();
              URL.revokeObjectURL(a.href);
              toast("Backup downloaded");
            }}><IDownload size={13}></IDownload> Download backup</Btn>
            <Btn variant="secondary" size="sm" onClick={() => document.getElementById("plm-restore-file").click()}>Restore from file</Btn>
            <input id="plm-restore-file" type="file" accept=".json,application/json" style={{ display: "none" }}
              onChange={(e) => {
                const f = e.target.files && e.target.files[0];
                e.target.value = "";
                if (!f) return;
                const rd = new FileReader();
                rd.onload = () => {
                  let obj = null;
                  try { obj = JSON.parse(rd.result); } catch (err) { toast("Could not read file — not valid JSON"); return; }
                  const err = PLM.importSnapshot(obj);
                  toast(err ? err : "Backup restored — all items, party rates and quotations loaded");
                  if (!err) onClose();
                };
                rd.readAsText(f);
              }} />
          </div>
          <div className="caption" style={{ marginTop: 8 }}>Saves every item, special rate and quotation to a file. Restore it into any newer version of this app — including the cloud edition.</div>
        </div>
        <div style={{ borderTop: "1px solid var(--border-default)", paddingTop: 14, display: "flex", alignItems: "center", gap: 10 }}>
          {confirmReset ? (
            <React.Fragment>
              <span className="caption">Discard all edits and reload the imported Excel data?</span>
              <Btn variant="danger" size="sm" onClick={() => { PLM.resetToSeed(); toast("Reset to imported workbook data"); onClose(); }}>Reset</Btn>
              <Btn variant="ghost" size="sm" onClick={() => setConfirmReset(false)}>Cancel</Btn>
            </React.Fragment>
          ) : (
            <React.Fragment>
              <Btn variant="ghost" size="sm" style={{ color: "var(--red-700)" }} onClick={() => setConfirmReset(true)}>Reset to imported data</Btn>
              <span className="caption">Reloads the uploaded workbook (master + 14 party lists). All edits since import are lost.</span>
            </React.Fragment>
          )}
        </div>
      </div>
    </Dialog>
  );
}

if (window.PLM_CLOUD) {
  window.__PLM_MOUNT_APP = function () {
    ReactDOM.createRoot(document.getElementById("root")).render(<App></App>);
  };
  if (window.__PLM_CLOUD_READY) window.__PLM_MOUNT_APP();
} else {
  ReactDOM.createRoot(document.getElementById("root")).render(<App></App>);
}
