/* ============================================================
   Operion WTT — App shell: sidebar, topbar, routing, toasts,
   simulation loop, language selector, Tweaks panel
   ============================================================ */
(function () {
  const { useState, useEffect, useRef, useCallback } = React;
  const { Icon, Badge } = window;
  const h = React.createElement;

  const NAV = [
    { g: 'grp.overview', items: [['dashboard', 'dashboard', 'Dashboard'], ['synoptic', 'synoptic', 'Synoptic']] },
    { g: 'grp.primary', items: [['primary', 'droplet', 'Primary'], ['potable', 'filter', 'Potable']] },
    { g: 'grp.waste', items: [['waste', 'recycle', 'Waste'], ['sludge', 'layers', 'Sludge']] },
    { g: 'grp.assets', items: [['tanks', 'tank', 'Tanks'], ['pumps', 'pump', 'Pumps']] },
    { g: 'grp.ops', items: [['quality', 'flask', 'Quality'], ['chemicals', 'beaker', 'Chemicals'], ['energy', 'zap', 'Energy'], ['maintenance', 'wrench', 'Maintenance'], ['alarms', 'bell', 'Alarms'], ['reports', 'file', 'Reports']] },
    { g: 'grp.admin', items: [['users', 'users', 'Users'], ['settings', 'settings', 'Settings']] },
  ];
  const NAVKEY = { dashboard: 'nav.dashboard', synoptic: 'nav.synoptic', primary: 'nav.primary', potable: 'nav.potable', waste: 'nav.waste', sludge: 'nav.sludge', tanks: 'nav.tanks', pumps: 'nav.pumps', quality: 'nav.quality', chemicals: 'nav.chemicals', energy: 'nav.energy', maintenance: 'nav.maintenance', alarms: 'nav.alarms', reports: 'nav.reports', users: 'nav.users', settings: 'nav.settings' };
  const CRUMB = { dashboard: 'grp.overview', synoptic: 'grp.overview', primary: 'grp.primary', potable: 'grp.primary', waste: 'grp.waste', sludge: 'grp.waste', tanks: 'grp.assets', pumps: 'grp.assets', quality: 'grp.ops', chemicals: 'grp.ops', energy: 'grp.ops', maintenance: 'grp.ops', alarms: 'grp.ops', reports: 'grp.ops', users: 'grp.admin', settings: 'grp.admin' };

  const TEST_ALARMS = [
    { sev: 'critical', area: 'aux', it: 'Emergenza quadro elettrico MCC', en: 'MCC switchboard emergency', es: 'Emergencia cuadro eléctrico', fr: 'Urgence armoire électrique', de: 'Notfall Schaltschrank', code: 'EMG-MCC', act: 'Verificare protezioni, intervento immediato' },
    { sev: 'warning', area: 'primary', it: 'Torbidità uscita elevata', en: 'High outlet turbidity', es: 'Turbidez alta', fr: 'Turbidité élevée', de: 'Hohe Trübung', code: 'QAH-FILT', act: 'Avviare controlavaggio filtri' },
    { sev: 'critical', area: 'aux', it: 'Mancanza comunicazione PLC', en: 'PLC communication loss', es: 'Pérdida comunicación PLC', fr: 'Perte communication PLC', de: 'PLC-Kommunikationsverlust', code: 'COM-PLC', act: 'Verificare rete e gateway Modbus' },
    { sev: 'warning', area: 'chem', it: 'Serbatoio ipoclorito basso', en: 'Hypochlorite tank low', es: 'Tanque hipoclorito bajo', fr: 'Réservoir hypochlorite bas', de: 'Hypochlorit-Tank niedrig', code: 'LSL-401', act: 'Programmare riordino reagente' },
  ];

  // ---- Tweaks ----
  const TW_DEFAULT = { theme: 'light', density: 'normal', statusPreset: 'standard', speed: 2000 };
  function loadTweaks() { try { return Object.assign({}, TW_DEFAULT, JSON.parse(localStorage.getItem('operion_tweaks') || '{}')); } catch (e) { return { ...TW_DEFAULT }; } }
  const STATUS_PRESETS = {
    standard: {}, // default tokens
    contrast: { '--status-run': '#0E7A3F', '--status-warn': '#C77800', '--status-alarm': '#B00020' },
    cb: { '--status-run': '#1A85FF', '--status-warn': '#E8A317', '--status-alarm': '#D41159', '--status-run-bg': '#E3EFFF' },
  };

  function App() {
    const s = window.useStore();
    const [route, setRoute] = useState('dashboard');
    const [lang, setLangState] = useState('it');
    const [toasts, setToasts] = useState([]);
    const [navCollapsed, setNavCollapsed] = useState(false);
    const [langOpen, setLangOpen] = useState(false);
    const [twOpen, setTwOpen] = useState(false);
    const [tw, setTw] = useState(loadTweaks);
    const toastId = useRef(0);

    const t = window.I18N.makeT(lang);
    const tl = useCallback((obj) => (obj ? (obj[lang] || obj.it || '') : ''), [lang]);

    // apply tweaks to DOM
    useEffect(() => {
      const root = document.documentElement;
      root.setAttribute('data-theme', tw.theme);
      root.setAttribute('data-density', tw.density === 'normal' ? '' : tw.density);
      const preset = STATUS_PRESETS[tw.statusPreset] || {};
      Object.keys(STATUS_PRESETS.contrast).concat(Object.keys(STATUS_PRESETS.cb)).forEach((k) => root.style.removeProperty(k));
      Object.entries(preset).forEach(([k, v]) => root.style.setProperty(k, v));
      localStorage.setItem('operion_tweaks', JSON.stringify(tw));
    }, [tw]);

    // sim loop
    useEffect(() => {
      const iv = setInterval(() => window.STORE.tick(), tw.speed);
      return () => clearInterval(iv);
    }, [tw.speed]);
    // clock loop (always 1s)
    useEffect(() => {
      const iv = setInterval(() => { window.STORE.state.clock = new Date(); window.STORE.emit(); }, 1000);
      return () => clearInterval(iv);
    }, []);

    const toast = useCallback((kind, title, msg) => {
      const id = ++toastId.current;
      setToasts((arr) => [...arr.slice(-3), { id, kind, title, msg }]);
      setTimeout(() => setToasts((arr) => arr.map((x) => (x.id === id ? { ...x, leaving: true } : x))), 3600);
      setTimeout(() => setToasts((arr) => arr.filter((x) => x.id !== id)), 3900);
    }, []);

    const setLang = useCallback((l) => {
      setLangState(l); window.STORE.setLang(l); setLangOpen(false);
      const tt = window.I18N.makeT(l);
      toast('info', tt('toast.langchanged'), window.I18N.LANGS.find((x) => x.code === l).label);
    }, [toast]);

    const sim = {
      running: s ? window.STORE.simRunning : true,
      toggle: () => { const r = !window.STORE.simRunning; window.STORE.setSim(r); toast(r ? 'run' : 'warn', t(r ? 'toast.simstart' : 'toast.simpause'), ''); },
      start: () => { window.STORE.setSim(true); toast('run', t('toast.simstart'), ''); },
      pause: () => { window.STORE.setSim(false); toast('warn', t('toast.simpause'), ''); },
      reset: () => { window.STORE.reset(); toast('info', t('toast.simreset'), ''); },
      testAlarm: () => { const a = TEST_ALARMS[Math.floor(Math.random() * TEST_ALARMS.length)]; window.STORE.spawnAlarm({ ...a, auto: true }); toast(a.sev === 'critical' ? 'alarm' : 'warn', t('toast.testalarm'), a.code); },
    };

    const ctx = { t, tl, lang, setLang, toast, route, setRoute, sim, tw, setTw };
    window.OPERION_WTT_CONTEXT = ctx;
    window.OPERION_WTT_SET_ROUTE = setRoute;
    const openAlarms = s.alarms.filter((a) => a.state === 'open').length;
    const Section = window.Sections[{ dashboard: 'Dashboard', synoptic: 'Synoptic', primary: 'Primary', potable: 'Potable', waste: 'Waste', sludge: 'Sludge', tanks: 'Tanks', pumps: 'Pumps', quality: 'Quality', chemicals: 'Chemicals', energy: 'Energy', maintenance: 'Maintenance', alarms: 'Alarms', reports: 'Reports', users: 'Users', settings: 'Settings' }[route]] || window.Sections.Dashboard;

    return h(window.AppCtx.Provider, { value: ctx },
      h('div', { className: 'app' + (navCollapsed ? ' nav-collapsed' : '') },
        // ---- Sidebar ----
        h('aside', { className: 'sidebar' },
          h('div', { className: 'sidebar-head' },
            h('img', { className: 'sidebar-logo', src: 'assets/logo-jit-white.png', alt: 'JIT' }),
            h('div', { className: 'sidebar-brand' }, h('span', { className: 'pn' }, 'Operion WTT'), h('span', { className: 'pt' }, 'WATER · JIT'))),
          h('div', { className: 'sidebar-scroll' },
            NAV.map((grp) => h('div', { key: grp.g },
              h('div', { className: 'nav-group-label' }, t(grp.g)),
              grp.items.map((it) => h('div', { key: it[0], className: 'nav-item' + (route === it[0] ? ' active' : ''), onClick: () => setRoute(it[0]), title: t(NAVKEY[it[0]]) },
                h(Icon, { name: it[1], size: 19 }),
                h('span', { className: 'label' }, t(NAVKEY[it[0]])),
                it[0] === 'alarms' && openAlarms > 0 && h('span', { className: 'nav-badge' }, openAlarms)))))),
          h('div', { className: 'sidebar-foot' },
            h('div', { className: 'plc-status' },
              h('span', { className: 'dot', style: { background: '#F2941F', animation: 'pulse 1.6s ease-in-out infinite' } }),
              h('div', { className: 'plc-txt' }, h('b', null, 'PLC · ' + t('st.sim').toUpperCase()), h('span', null, 'SCADA ' + t('st.online')))))),

        // ---- Main ----
        h('div', { className: 'main' },
          h('div', { className: 'topbar' },
            h('button', { className: 'icon-btn', onClick: () => setNavCollapsed((v) => !v), title: 'menu' }, h(Icon, { name: 'menu', size: 19 })),
            h('div', { className: 'topbar-title' },
              h('span', { className: 'crumb' }, t(CRUMB[route])),
              h('h1', null, t(NAVKEY[route]))),
            h('span', { className: 'topbar-spacer' }),
            h('div', { className: 'topclock' },
              h('span', { className: 't' }, fmtTime(s.clock)),
              h('span', null, fmtDate(s.clock, lang))),
            // sim pill
            h('button', { className: 'sim-pill ' + (sim.running ? 'on' : 'off'), onClick: sim.toggle },
              h('span', { className: 'dot' }), sim.running ? t('sim.on') : t('sim.off')),
            // language
            h('div', { className: 'lang-sel' },
              h('button', { className: 'lang-btn', onClick: () => setLangOpen((v) => !v) },
                h('span', { className: 'flag' }, window.I18N.LANGS.find((l) => l.code === lang).flag),
                h('span', null, lang.toUpperCase()),
                h(Icon, { name: 'chevDown', size: 14 })),
              langOpen && h(React.Fragment, null,
                h('div', { style: { position: 'fixed', inset: 0, zIndex: 55 }, onClick: () => setLangOpen(false) }),
                h('div', { className: 'lang-menu' }, window.I18N.LANGS.map((l) => h('div', { key: l.code, className: 'lang-opt' + (l.code === lang ? ' active' : ''), onClick: () => setLang(l.code) },
                  h('span', { className: 'flag' }, l.flag), h('span', null, l.label), l.code === lang && h('span', { className: 'chk' }, h(Icon, { name: 'check', size: 15 }))))))),
            h('button', { className: 'icon-btn', onClick: () => setRoute('alarms'), title: t('nav.alarms') },
              h(Icon, { name: 'bell', size: 19 }), openAlarms > 0 && h('span', { className: 'dot-badge' })),
            h('div', { className: 'user-chip', onClick: () => setRoute('users') },
              h('div', { style: { textAlign: 'right' } }, h('div', { className: 'nm' }, 'M. Rossi'), h('div', { className: 'rl' }, t('grp.admin'))),
              h('span', { className: 'avatar' }, 'MR'))),
          h('div', { className: 'content' }, h(Section))),

        // ---- Toasts ----
        h('div', { className: 'toast-wrap' }, toasts.map((to) => h('div', { key: to.id, className: 'toast ' + to.kind + (to.leaving ? ' leaving' : '') },
          h('span', { className: 't-ic' }, h(Icon, { name: to.kind === 'run' ? 'check' : to.kind === 'alarm' ? 'alert' : to.kind === 'warn' ? 'alert' : 'info', size: 19 })),
          h('div', { className: 't-body' }, h('div', { className: 't-title' }, to.title), to.msg && h('div', { className: 't-msg' }, to.msg)),
          h('button', { className: 't-x', onClick: () => setToasts((arr) => arr.filter((x) => x.id !== to.id)) }, h(Icon, { name: 'x', size: 15 }))))),

        // ---- Tweaks ----
        h('button', { className: 'tw-fab', onClick: () => setTwOpen((v) => !v), title: 'Tweaks' }, h(Icon, { name: twOpen ? 'x' : 'sliders', size: 20 })),
        twOpen && h(Tweaks, { tw, setTw, lang, setLang, t, tl, onClose: () => setTwOpen(false) })));
  }

  function Tweaks({ tw, setTw, lang, setLang, t, tl, onClose }) {
    const set = (k, v) => setTw((x) => ({ ...x, [k]: v }));
    const Sec = ({ label, children }) => h('div', { className: 'tw-sec' }, h('label', null, label), children);
    const Opts = ({ k, opts }) => h('div', { className: 'tw-opts' }, opts.map((o) => h('button', { key: o.v, className: 'tw-opt' + (tw[k] === o.v ? ' active' : ''), onClick: () => set(k, o.v) }, o.label)));
    return h('div', { className: 'tw-panel' },
      h('div', { className: 'tw-head' }, h('h4', null, 'Tweaks'), h('button', { className: 'tw-x', onClick: onClose }, h(Icon, { name: 'x', size: 17 }))),
      h('div', { className: 'tw-body' },
        h(Sec, { label: tl({ it: 'Tema', en: 'Theme', es: 'Tema', fr: 'Thème', de: 'Thema' }) },
          h(Opts, { k: 'theme', opts: [{ v: 'light', label: tl({ it: 'Chiaro', en: 'Light', es: 'Claro', fr: 'Clair', de: 'Hell' }) }, { v: 'dark', label: tl({ it: 'Control room', en: 'Control room', es: 'Sala control', fr: 'Salle contrôle', de: 'Leitstand' }) }] })),
        h(Sec, { label: tl({ it: 'Densità', en: 'Density', es: 'Densidad', fr: 'Densité', de: 'Dichte' }) },
          h(Opts, { k: 'density', opts: [{ v: 'compact', label: tl({ it: 'Compatta', en: 'Compact', es: 'Compacta', fr: 'Compacte', de: 'Kompakt' }) }, { v: 'normal', label: tl({ it: 'Normale', en: 'Normal', es: 'Normal', fr: 'Normale', de: 'Normal' }) }, { v: 'comfortable', label: tl({ it: 'Comoda', en: 'Comfy', es: 'Cómoda', fr: 'Confort', de: 'Komfort' }) }] })),
        h(Sec, { label: tl({ it: 'Palette stati', en: 'Status palette', es: 'Paleta estados', fr: 'Palette états', de: 'Statuspalette' }) },
          h(Opts, { k: 'statusPreset', opts: [{ v: 'standard', label: tl({ it: 'Standard', en: 'Standard', es: 'Estándar', fr: 'Standard', de: 'Standard' }) }, { v: 'contrast', label: tl({ it: 'Contrasto', en: 'Contrast', es: 'Contraste', fr: 'Contraste', de: 'Kontrast' }) }, { v: 'cb', label: tl({ it: 'Daltonici', en: 'Colorblind', es: 'Daltónico', fr: 'Daltonien', de: 'Farbenblind' }) }] })),
        h(Sec, { label: tl({ it: 'Lingua', en: 'Language', es: 'Idioma', fr: 'Langue', de: 'Sprache' }) },
          h('div', { className: 'tw-opts' }, window.I18N.LANGS.map((l) => h('button', { key: l.code, className: 'tw-opt' + (lang === l.code ? ' active' : ''), onClick: () => setLang(l.code), style: { minWidth: 44, flex: '0 0 auto' } }, l.flag + ' ' + l.code.toUpperCase())))),
        h(Sec, { label: tl({ it: 'Velocità simulazione', en: 'Simulation speed', es: 'Velocidad sim.', fr: 'Vitesse sim.', de: 'Sim-Geschwindigkeit' }) },
          h('div', { className: 'tw-opts' }, [{ v: 4000, label: '0.5×' }, { v: 2000, label: '1×' }, { v: 1000, label: '2×' }, { v: 500, label: '4×' }].map((o) => h('button', { key: o.v, className: 'tw-opt' + (tw.speed === o.v ? ' active' : ''), onClick: () => set('speed', o.v) }, o.label))))));
  }

  function fmtTime(d) { return [d.getHours(), d.getMinutes(), d.getSeconds()].map((x) => String(x).padStart(2, '0')).join(':'); }
  function fmtDate(d, lang) {
    const days = { it: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'], en: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], es: ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'], fr: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'], de: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'] };
    return (days[lang] || days.it)[d.getDay()] + ' ' + String(d.getDate()).padStart(2, '0') + '/' + String(d.getMonth() + 1).padStart(2, '0') + '/' + d.getFullYear();
  }

  ReactDOM.createRoot(document.getElementById('root')).render(h(App));
})();
