// app.jsx — Kingshot R4 dashboard main app

const { useState: useStateApp, useEffect: useEffectApp, useMemo: useMemoApp, useCallback: useCallbackApp } = React;

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

const ACCENT_OPTIONS = [
  { id: 'lime',   hex: '#C4F542', label: 'Lime' },
  { id: 'orange', hex: '#FF6B35', label: 'Orange' },
  { id: 'cyan',   hex: '#67E8F9', label: 'Cyan' },
];

const SETTINGS_DEFAULTS = {
  allianceName: '#2 Kings',
  r4Name: 'R4',
  tzOffsetHrs: 0,
  userTzOffsetHrs: 'auto',
  marchSpeed: 5,
  windowDays: 14,
  activeThreshold: 3,
  normalThreshold: 1,
  dormantLoginDays: 7,
  minChangePower: 1_000_000, // 1M power = a real growth day, vs daily passive drift
};

function loadJSON(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw ? { ...fallback, ...JSON.parse(raw) } : fallback;
  } catch { return fallback; }
}
function saveJSON(key, val) {
  try { localStorage.setItem(key, JSON.stringify(val)); } catch {}
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffectApp(() => {
    document.documentElement.setAttribute('data-density', t.density);
    document.documentElement.setAttribute('data-accent', t.accent);
  }, [t.density, t.accent]);

  // Async data bootstrap — mock or Supabase
  const [data, setData] = useStateApp(null);
  const [dataError, setDataError] = useStateApp(null);
  const [reloadKey, setReloadKey] = useStateApp(0);

  useEffectApp(() => {
    let cancelled = false;
    setData(null);
    setDataError(null);
    window.DataSource.load()
      .then(d => { if (!cancelled) setData(d); })
      .catch(e => { if (!cancelled) setDataError(e.message || String(e)); });
    return () => { cancelled = true; };
  }, [reloadKey]);

  const reload = useCallbackApp(() => setReloadKey(k => k + 1), []);

  if (dataError) {
    return <LoadingScreen error={dataError} onRetry={reload} />;
  }
  if (!data) {
    return <LoadingScreen />;
  }

  return <AppInner data={data} t={t} setTweak={setTweak} onReloadData={reload} />;
}

function LoadingScreen({ error, onRetry }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      minHeight: '100vh', gap: 12,
      fontFamily: 'var(--font-mono)', color: 'var(--fg-2)',
    }}>
      <div style={{ fontSize: 11, letterSpacing: '0.1em', color: 'var(--fg-3)' }}>KINGSHOT // R4</div>
      {error ? (
        <>
          <div style={{ color: 'var(--lost)', fontSize: 13, maxWidth: 480, textAlign: 'center' }}>
            {error}
          </div>
          {onRetry && <button className="btn ghost" onClick={onRetry}>Retry</button>}
          <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>
            Or open <a href="#settings" onClick={(e) => { e.preventDefault(); window.location.hash = 'settings'; window.location.reload(); }} style={{ color: 'var(--accent)' }}>Settings</a> to fix the data source.
          </div>
        </>
      ) : (
        <div style={{ fontSize: 12 }}>Loading roster…</div>
      )}
    </div>
  );
}

function AppInner({ data, t, setTweak, onReloadData }) {

  // Tab state from URL hash
  const [tab, setTab] = useStateApp(() => {
    const h = window.location.hash.slice(1);
    return ['home', 'waves', 'activity', 'settings'].includes(h) ? h : 'home';
  });
  useEffectApp(() => { window.location.hash = tab; }, [tab]);

  // Settings (persisted)
  const [settings, setSettingsState] = useStateApp(() => loadJSON('kingshot.settings.v1', SETTINGS_DEFAULTS));
  const setSettings = useCallbackApp((next) => {
    setSettingsState(next);
    saveJSON('kingshot.settings.v1', next);
  }, []);

  // Resolved tzOffsetHrs values
  const serverTzOffset = parseFloat(settings.tzOffsetHrs) || 0;
  const userTzOffset = settings.userTzOffsetHrs === 'auto'
    ? -new Date().getTimezoneOffset() / 60
    : parseFloat(settings.userTzOffsetHrs);

  // Keyboard shortcuts
  useEffectApp(() => {
    const h = (e) => {
      if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) return;
      if (e.key === '1') setTab('home');
      if (e.key === '2') setTab('waves');
      if (e.key === '3') setTab('activity');
      if (e.key === '4') setTab('settings');
      if (e.key === '/') {
        e.preventDefault();
        const s = document.querySelector('.searchbox input');
        if (s) s.focus();
      }
    };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);

  // Manual distance overrides
  const [distances, setDistances] = useStateApp(() => loadJSON('kingshot.distances.v1', {}));
  const setDistance = useCallbackApp((memberId, value) => {
    setDistances(prev => {
      const next = { ...prev, [memberId]: value };
      saveJSON('kingshot.distances.v1', next);
      return next;
    });
  }, []);
  const resetDistances = () => {
    setDistances({});
    try { localStorage.removeItem('kingshot.distances.v1'); } catch {}
  };

  // Hero notes
  const [notes, setNotes] = useStateApp(() => loadJSON('kingshot.notes.v1', {}));
  const setNote = useCallbackApp((memberId, value) => {
    setNotes(prev => {
      const next = { ...prev };
      if (!value || !value.trim()) delete next[memberId];
      else next[memberId] = value;
      saveJSON('kingshot.notes.v1', next);
      return next;
    });
  }, []);

  // Events — start from data source, can be edited
  const [events, setEvents] = useStateApp(() => {
    const stored = loadJSON('kingshot.events.v1', null);
    return stored && Array.isArray(stored.list) ? stored.list : data.events;
  });
  const persistEvents = (list) => {
    setEvents(list);
    saveJSON('kingshot.events.v1', { list });
  };
  const addEvent = (e) => persistEvents([...events, e]);
  const editEvent = (e) => persistEvents(events.map(x => x.id === e.id ? e : x));
  const deleteEvent = (id) => persistEvents(events.filter(x => x.id !== id));

  // Event templates — user-editable, persisted
  const [templates, setTemplates] = useStateApp(() => {
    const stored = loadJSON('kingshot.templates.v1', null);
    return stored && Array.isArray(stored.list) ? stored.list : data.eventTemplates;
  });
  const persistTemplates = (list) => {
    setTemplates(list);
    saveJSON('kingshot.templates.v1', { list });
  };

  const [toast, showToast] = useToast();

  const algoSettings = useMemoApp(() => ({
    windowDays: settings.windowDays,
    activeThreshold: settings.activeThreshold,
    normalThreshold: settings.normalThreshold,
    dormantLoginDays: settings.dormantLoginDays,
    minChangePower: settings.minChangePower,
    marchSpeed: settings.marchSpeed,
    tzOffsetHrs: serverTzOffset,
  }), [settings, serverTzOffset]);

  const { members, history, snapshotMeta } = data;

  return (
    <>
      <TopBar
        tab={tab}
        setTab={setTab}
        tzOffsetHrs={serverTzOffset}
        snapshotMeta={snapshotMeta}
      />

      {tab === 'home' && (
        <HomePage
          events={events}
          eventTemplates={templates}
          tzOffsetHrs={serverTzOffset}
          onToast={showToast}
          onEditEvent={editEvent}
          onAddEvent={addEvent}
          onDeleteEvent={deleteEvent}
        />
      )}
      {tab === 'waves' && (
        <WavesPage
          members={members}
          history={history}
          settings={algoSettings}
          distances={distances}
          setDistance={setDistance}
          notes={notes}
          setNote={setNote}
          onToast={showToast}
          snapshotMeta={snapshotMeta}
        />
      )}
      {tab === 'activity' && (
        <ActivityPage
          members={members}
          history={history}
          settings={algoSettings}
          distances={distances}
          onToast={showToast}
          snapshotMeta={snapshotMeta}
        />
      )}
      {tab === 'settings' && (
        <SettingsPage
          settings={settings}
          onChange={setSettings}
          templates={templates}
          onChangeTemplates={persistTemplates}
          onReloadData={onReloadData}
          dataSource={data.snapshotMeta.source}
          onResetDistances={() => {
            if (confirm('Reset all manual distances?')) {
              resetDistances();
              showToast('Distances reset');
            }
          }}
        />
      )}

      {toast && <div className="toast">{toast}</div>}

      <TweaksPanel title="Tweaks">
        <TweakSection label="Look" />
        <TweakColor
          label="Accent"
          value={ACCENT_OPTIONS.find(a => a.id === t.accent)?.hex || '#C4F542'}
          options={ACCENT_OPTIONS.map(a => a.hex)}
          onChange={(hex) => {
            const found = ACCENT_OPTIONS.find(a => a.hex === hex);
            setTweak('accent', found ? found.id : 'lime');
          }}
        />
        <TweakRadio
          label="Density"
          value={t.density}
          options={['compact', 'comfortable']}
          onChange={(v) => setTweak('density', v)}
        />
      </TweaksPanel>
    </>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
