// invodiff-app.jsx — root app, state, top bar with nav tabs + theme switch.

// ── Auth state hook ──────────────────────────────────────────────────────
function useAuthState() {
  const [user, setUser] = React.useState(undefined); // undefined = still checking
  React.useEffect(() => {
    return fbAuth.onAuthStateChanged((u) => setUser(u ?? null));
  }, []);
  return user;
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "density": "comfortable",
  "accent": "steel",
  "seedHistory": true
}/*EDITMODE-END*/;

const ACCENT_MAP = {
  steel:  'oklch(0.72 0.10 240)',
  emerald:'oklch(0.74 0.10 165)',
  amber:  'oklch(0.80 0.13 75)',
  violet: 'oklch(0.72 0.11 300)',
  neutral:'oklch(0.86 0.005 240)',
};

// ── Theme switch ────────────────────────────────────────────────────────
function ThemeSwitch({ value, onChange }) {
  const isDark = value === 'dark';
  return (
    <button
      className="theme-switch"
      onClick={() => onChange(isDark ? 'light' : 'dark')}
      aria-label={`Switch to ${isDark ? 'light' : 'dark'} mode`}
      title={`Switch to ${isDark ? 'light' : 'dark'} mode`}
    >
      <span className="theme-switch-track">
        <span className="theme-switch-thumb" data-on={isDark ? 'dark' : 'light'}>
          {isDark
            ? <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
            : <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
          }
        </span>
      </span>
    </button>
  );
}

// ── Top bar ─────────────────────────────────────────────────────────────
function TopBar({ view, setView, phase, vendor, theme, setTheme, vendorCount, user }) {
  const displayName = user?.displayName || user?.email?.split('@')[0] || '';
  return (
    <div className="topbar">
      <div className="brand">
        <img src="assets/KCG.webp" alt="KCGMatch" className="brand-logo" />
        <div className="brand-name">KCGMatch</div>
      </div>

      <div className="topbar-sep"></div>

      <nav className="navtabs" role="tablist">
        <button
          className={`navtab ${view === 'compare' ? 'is-on' : ''}`}
          role="tab" aria-selected={view === 'compare'}
          onClick={() => setView('compare')}
        >
          <Icon name="file" size={14}/>
          <span>Compare</span>
        </button>
        <button
          className={`navtab ${view === 'vendors' ? 'is-on' : ''}`}
          role="tab" aria-selected={view === 'vendors'}
          onClick={() => setView('vendors')}
        >
          <Icon name="rule" size={14}/>
          <span>Vendors</span>
          {vendorCount > 0 && <span className="navtab-count num">{vendorCount}</span>}
        </button>
      </nav>

      {view === 'compare' && (
        <>
          <div className="topbar-sep"></div>
          <div className="crumbs">
            <span className={phase === 'input' ? 'crumb-active' : ''}>Upload</span>
            <Icon name="chev" size={11} />
            <span className={phase === 'compare' ? 'crumb-active' : ''}>Compare</span>
            <Icon name="chev" size={11} />
            <span className={phase === 'decision' ? 'crumb-active' : ''}>Decision</span>
          </div>
        </>
      )}

      <div className="topbar-spacer"></div>

      {vendor && phase === 'compare' && (
        <span className="pill"><Icon name="rule" size={12}/> {vendor}</span>
      )}
      <ThemeSwitch value={theme} onChange={setTheme} />
      {user && (
        <div className="topbar-user">
          {displayName && <span className="topbar-uname">{displayName}</span>}
          <button className="btn btn-ghost btn-sm" onClick={() => fbAuth.signOut()}>Sign out</button>
        </div>
      )}

      <TopBarStyles />
    </div>
  );
}

const TopBarStyles = () => (
  <style>{`
    .navtabs { display: flex; gap: 2px; padding: 3px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r); }
    .navtab {
      appearance: none; border: 0;
      background-color: transparent;
      padding: 5px 12px; border-radius: 4px;
      font: inherit; font-size: 12.5px; font-weight: 500;
      color: var(--fg-muted); cursor: pointer;
      display: inline-flex; align-items: center; gap: 7px;
    }
    .navtab:hover:not(.is-on) { color: var(--fg); background-color: oklch(from var(--fg) l c h / 0.06); }
    .navtab.is-on { background-color: var(--bg); color: var(--fg); box-shadow: var(--shadow-1); }
    .navtab-count { font-size: 10.5px; padding: 1px 6px; border-radius: 999px; background: var(--surface-3); color: var(--fg-dim); }
    .navtab.is-on .navtab-count { background: oklch(from var(--accent) l c h / 0.20); color: var(--accent); }

    .theme-switch {
      appearance: none; border: 1px solid var(--border); background: var(--surface-2);
      padding: 3px; border-radius: 999px; cursor: pointer;
      display: inline-flex; align-items: center;
      transition: background .12s, border-color .12s;
    }
    .theme-switch:hover { background: var(--surface-3); }
    .theme-switch-track {
      position: relative; display: block; width: 38px; height: 18px;
    }
    .theme-switch-thumb {
      position: absolute; top: 0; bottom: 0; width: 18px;
      border-radius: 50%;
      display: grid; place-items: center;
      background: var(--fg); color: var(--bg);
      transition: left .18s cubic-bezier(.3,.7,.4,1), background .18s, color .18s;
    }
    .theme-switch-thumb[data-on="dark"] { left: 0; }
    .theme-switch-thumb[data-on="light"] { left: 20px; }

    .topbar-user { display: flex; align-items: center; gap: 8px; }
    .topbar-uname { font-size: 12.5px; color: var(--fg-muted); max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  `}</style>
);

// ── App root ────────────────────────────────────────────────────────────
function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const user = useAuthState();

  // ── vendorRules — Firebase-backed ─────────────────────────────────────
  const [vendorRules, setVendorRulesState] = React.useState({});
  const [rulesReady, setRulesReady]         = React.useState(false);
  const seededRef          = React.useRef(false);
  const firestoreSnapRef   = React.useRef(null); // JSON of last value from Firestore
  const saveTimerRef       = React.useRef(null);

  // Load from Firestore when user signs in; reset when they sign out.
  React.useEffect(() => {
    if (!user) {
      clearTimeout(saveTimerRef.current);
      setVendorRulesState({});
      setRulesReady(false);
      seededRef.current = false;
      firestoreSnapRef.current = null;
      return;
    }
    setRulesReady(false);
    fbDb.collection('users').doc(user.uid).get().then((doc) => {
      const saved = doc.exists ? (doc.data().vendorRules || null) : null;
      let initial;
      if (saved) {
        initial = saved;
        seededRef.current = false;
      } else if (t.seedHistory) {
        initial = { ...SEED_VENDOR_RULES };
        seededRef.current = true;
      } else {
        initial = {};
      }
      firestoreSnapRef.current = JSON.stringify(initial);
      setVendorRulesState(initial);
      setRulesReady(true);
    }).catch(() => {
      const initial = t.seedHistory ? { ...SEED_VENDOR_RULES } : {};
      if (t.seedHistory) seededRef.current = true;
      firestoreSnapRef.current = JSON.stringify(initial);
      setVendorRulesState(initial);
      setRulesReady(true);
    });
  }, [user?.uid]);

  // Seed toggle while logged in.
  React.useEffect(() => {
    if (!rulesReady) return;
    if (t.seedHistory && !seededRef.current) {
      setVendorRulesState((prev) => ({ ...SEED_VENDOR_RULES, ...prev }));
      seededRef.current = true;
    } else if (!t.seedHistory && seededRef.current) {
      setVendorRulesState({});
      seededRef.current = false;
    }
  }, [t.seedHistory]);

  // Wrap setter so the rest of the app keeps using setVendorRules.
  const setVendorRules = React.useCallback((updater) => {
    setVendorRulesState(updater);
  }, []);

  // Debounced save — skips on initial Firestore load (value matches snapshot).
  React.useEffect(() => {
    if (!user || !rulesReady) return;
    const current = JSON.stringify(vendorRules);
    if (current === firestoreSnapRef.current) return;
    clearTimeout(saveTimerRef.current);
    saveTimerRef.current = setTimeout(() => {
      firestoreSnapRef.current = current;
      fbDb.collection('users').doc(user.uid)
        .set({ vendorRules }, { merge: true })
        .catch(console.error);
    }, 1000);
    return () => clearTimeout(saveTimerRef.current);
  }, [vendorRules, user?.uid, rulesReady]);

  // ── UI state ──────────────────────────────────────────────────────────
  const [view, setView]   = React.useState('compare');
  const [phase, setPhase] = React.useState('input');
  const [state, setState] = React.useState({ invoiceA: null, invoiceB: null, vendor: '' });

  React.useEffect(() => {
    document.documentElement.dataset.theme = t.theme;
    document.documentElement.dataset.density = t.density;
    document.documentElement.style.setProperty('--accent', ACCENT_MAP[t.accent] || ACCENT_MAP.steel);
  }, [t.theme, t.density, t.accent]);

  const setTheme = (v) => setTweak('theme', v);

  const handleCompare = () => { setPhase('compare'); window.scrollTo({ top: 0, behavior: 'smooth' }); };
  const handleBack    = () => { setPhase('input');   window.scrollTo({ top: 0, behavior: 'smooth' }); };
  const startNewComparison = () => {
    setState({ invoiceA: null, invoiceB: null, vendor: '' });
    setPhase('input'); setView('compare');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };
  const compareWithVendor = (vendorName) => {
    setState({ invoiceA: null, invoiceB: null, vendor: vendorName });
    setPhase('input'); setView('compare');
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const vendorCount = Object.keys(vendorRules).filter((v) => (vendorRules[v] || []).length > 0).length;

  // ── Auth gate ─────────────────────────────────────────────────────────
  if (user === undefined) {
    return (
      <div className="auth-loader">
        <div className="auth-loader-spin"></div>
        <style>{`
          .auth-loader { display:flex; align-items:center; justify-content:center; min-height:100vh; background:var(--bg); }
          .auth-loader-spin { width:28px; height:28px; border-radius:50%; border:2.5px solid var(--border); border-top-color:var(--accent); animation:spin .7s linear infinite; }
          @keyframes spin { to { transform:rotate(360deg); } }
        `}</style>
      </div>
    );
  }
  if (!user) return <LoginScreen />;

  return (
    <div className="app">
      <TopBar
        view={view} setView={setView}
        phase={phase} vendor={state.vendor}
        theme={t.theme} setTheme={setTheme}
        vendorCount={vendorCount}
        user={user}
      />

      {view === 'compare' && phase === 'input' && (
        <InputView
          state={state}
          setState={setState}
          onCompare={handleCompare}
          vendorRules={vendorRules}
        />
      )}
      {view === 'compare' && phase === 'compare' && state.invoiceA && state.invoiceB && (
        <CompareView
          state={state}
          vendorRules={vendorRules}
          setVendorRules={setVendorRules}
          onBack={handleBack}
          onStartNew={startNewComparison}
          onViewVendors={() => { setView('vendors'); window.scrollTo({ top: 0, behavior: 'smooth' }); }}
        />
      )}
      {view === 'vendors' && (
        <VendorsView
          vendorRules={vendorRules}
          setVendorRules={setVendorRules}
          onCompareWithVendor={compareWithVendor}
        />
      )}

      <TweaksPanel title="Tweaks">
        <TweakSection label="Appearance" />
        <TweakRadio label="Theme" value={t.theme}
                    options={['dark', 'light']}
                    onChange={(v) => setTweak('theme', v)} />
        <TweakRadio label="Density" value={t.density}
                    options={['compact', 'comfortable']}
                    onChange={(v) => setTweak('density', v)} />
        <TweakColor label="Accent" value={ACCENT_MAP[t.accent] || ACCENT_MAP.steel}
                    options={Object.values(ACCENT_MAP)}
                    onChange={(hex) => {
                      const entry = Object.entries(ACCENT_MAP).find(([, v]) => v === hex);
                      if (entry) setTweak('accent', entry[0]);
                    }} />

        <TweakSection label="Data" />
        <TweakToggle label="Seed vendor history" value={t.seedHistory}
                     onChange={(v) => setTweak('seedHistory', v)} />
        <TweakButton label="Load sample comparison" onClick={() => {
          setState({ invoiceA: INVOICE_A, invoiceB: INVOICE_B, vendor: 'Acme Industrial Supply' });
          setPhase('input'); setView('compare');
        }} />
        <TweakButton secondary label="Clear all" onClick={() => {
          setState({ invoiceA: null, invoiceB: null, vendor: '' });
          setPhase('input'); setView('compare');
        }} />
      </TweaksPanel>
    </div>
  );
}

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