/* global React, ReactDOM, TweaksPanel, useTweaks, TweakRadio, HorusAuth */
const { useState, useEffect, useRef } = React;

/* ============================================================
   SVG icon marks
   ============================================================ */

function ArrowIcon({ size = 16 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M5 12h14" />
      <path d="M13 5l7 7-7 7" />
    </svg>
  );
}

function LogoutIcon({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
      <polyline points="16 17 21 12 16 7" />
      <line x1="21" y1="12" x2="9" y2="12" />
    </svg>
  );
}

function SunIcon({ size = 16 }) {
  return (
    <svg width={size} height={size} 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>
  );
}

function MoonIcon({ size = 16 }) {
  return (
    <svg width={size} height={size} 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>
  );
}

function ThemeToggle({ theme, onToggle, floating }) {
  const isDark = theme === 'dark';
  return (
    <button
      className={`theme-toggle ${floating ? 'theme-toggle--floating' : ''}`}
      onClick={() => onToggle(isDark ? 'light' : 'dark')}
      title={isDark ? 'Bytt til lyst tema' : 'Bytt til mørkt tema'}
      aria-label={isDark ? 'Bytt til lyst tema' : 'Bytt til mørkt tema'}
    >
      {isDark ? <SunIcon /> : <MoonIcon />}
    </button>
  );
}

/* Custom mark for the KPI tool — abstract "summit / target" reading,
   echoing the dot-inside-the-o motif of the horus logo */
function KpiMark() {
  return (
    <svg width="44" height="44" viewBox="0 0 44 44" fill="none">
      {/* ascending bars */}
      <rect x="6"  y="26" width="6" height="12" rx="2" fill="currentColor" opacity="0.45" />
      <rect x="16" y="20" width="6" height="18" rx="2" fill="currentColor" opacity="0.70" />
      <rect x="26" y="12" width="6" height="26" rx="2" fill="currentColor" />
      {/* peak dot */}
      <circle cx="29" cy="9"  r="3.5" fill="currentColor" />
      <circle cx="29" cy="9"  r="6.5" stroke="currentColor" strokeOpacity="0.35" strokeWidth="1.4" />
    </svg>
  );
}

/* Custom mark for the Linear Reporting tool — stacked rounded lines
   reminiscent of an issue tracker timeline, without copying Linear's mark */
function LinearMark() {
  return (
    <svg width="44" height="44" viewBox="0 0 44 44" fill="none">
      <rect x="6"  y="10" width="32" height="5" rx="2.5" fill="currentColor" opacity="0.40" />
      <rect x="6"  y="19.5" width="24" height="5" rx="2.5" fill="currentColor" opacity="0.70" />
      <rect x="6"  y="29" width="18" height="5" rx="2.5" fill="currentColor" />
      <circle cx="36" cy="31.5" r="3" fill="currentColor" />
    </svg>
  );
}

function MicrosoftSquares() {
  return (
    <span className="btn-ms__ms" aria-hidden="true">
      <span></span><span></span><span></span><span></span>
    </span>
  );
}

/* ============================================================
   Login screen
   ============================================================ */

function Login({ onSignIn, errorMode, signingIn, signInError, theme, onToggleTheme }) {
  const [showError, setShowError] = useState(errorMode);

  useEffect(() => { setShowError(errorMode); }, [errorMode]);

  return (
    <div className="login" data-screen-label="Login">
      <div className="login__glow" aria-hidden="true"></div>

      <ThemeToggle theme={theme} onToggle={onToggleTheme} floating />

      <div className="login__shell">
        <div className="login__panel">
          <img src="assets/logo-horus.png" alt="Horus" className="login__logo" />

          <div className="login__label mono-label">
            <span>Portal</span><span className="slash">/</span><span>Logg inn</span>
          </div>

          <h1 className="login__title">
            <em>Internverktøy.</em>
          </h1>

          <p className="login__sub">
            Logg inn med Microsoft-jobbkontoen din for å åpne internverktøyene.
          </p>

          <button className="btn-ms" onClick={onSignIn} disabled={signingIn}>
            {signingIn ? <span className="spinner" aria-hidden="true" /> : <MicrosoftSquares />}
            <span>{signingIn ? 'Logger inn…' : 'Logg inn med Microsoft'}</span>
          </button>

          <div className="login__fineprint">
            Bare kontoer på <code>@horus.no</code> har tilgang til denne portalen.
          </div>

          {signInError && !showError && (
            <div className="login__error" role="alert">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, marginTop: 1 }}>
                <circle cx="12" cy="12" r="10" />
                <line x1="12" y1="8" x2="12" y2="12" />
                <line x1="12" y1="16" x2="12.01" y2="16" />
              </svg>
              <div>
                <strong style={{ color: 'inherit', fontWeight: 600 }}>Innlogging feilet.</strong>{' '}
                {signInError}
              </div>
            </div>
          )}

          {showError && (
            <div className="login__error" role="alert">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, marginTop: 1 }}>
                <circle cx="12" cy="12" r="10" />
                <line x1="12" y1="8" x2="12" y2="12" />
                <line x1="12" y1="16" x2="12.01" y2="16" />
              </svg>
              <div>
                <strong style={{ color: 'inherit', fontWeight: 600 }}>Ingen tilgang.</strong>{' '}
                Den Microsoft-kontoen tilhører ikke Horus-tenanten. Ta kontakt med administrator hvis du tror dette er feil.
              </div>
            </div>
          )}
        </div>
      </div>

      <div className="login__footer">
        <span>Horus of Norway AS</span>
        <span>horus-tools.no</span>
      </div>
    </div>
  );
}

/* ============================================================
   Setup modal — Azure Entra ID configuration
   ============================================================ */

function CopyRow({ value }) {
  const [done, setDone] = useState(false);
  return (
    <div className="copy-row">
      <code>{value}</code>
      <button
        className={`copy-btn ${done ? 'copy-btn--done' : ''}`}
        onClick={async () => {
          try { await navigator.clipboard.writeText(value); } catch (_) {}
          setDone(true);
          setTimeout(() => setDone(false), 1600);
        }}
      >
        {done ? 'Kopiert' : 'Kopier'}
      </button>
    </div>
  );
}

function SetupModal({ open, onClose, onSaved, onCleared }) {
  const initial = (typeof HorusAuth !== 'undefined') ? HorusAuth.getConfig() : { clientId: '', tenantId: '' };
  const [clientId, setClientId] = useState(initial.clientId);
  const [tenantId, setTenantId] = useState(initial.tenantId);
  const redirect = (typeof HorusAuth !== 'undefined') ? HorusAuth.redirectUri() : '';
  const wasConfigured = !!initial.clientId && !!initial.tenantId;

  useEffect(() => {
    if (open) {
      const c = HorusAuth.getConfig();
      setClientId(c.clientId);
      setTenantId(c.tenantId);
    }
  }, [open]);

  if (!open) return null;

  const canSave = clientId.trim().length > 10 && tenantId.trim().length > 10;

  const handleSave = () => {
    HorusAuth.setConfig(clientId, tenantId);
    onSaved && onSaved();
  };

  const handleClear = () => {
    HorusAuth.clearConfig();
    setClientId(''); setTenantId('');
    onCleared && onCleared();
  };

  return (
    <div className="modal-backdrop" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal" role="dialog" aria-modal="true">
        <button className="modal__close" onClick={onClose} aria-label="Lukk">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
          </svg>
        </button>

        <div className="modal__label mono-label">
          <span>Oppsett</span><span className="slash">/</span><span>Microsoft Entra ID</span>
        </div>

        <h2 className="modal__title">Koble portalen til Horus-tenanten.</h2>
        <p className="modal__lede">
          Registrer en SPA-app i Entra ID, lim inn ID-ene under, og innloggingsknappen bruker ekte Microsoft-innlogging. PKCE — ingen klient-hemmelighet, ingen server.
        </p>

        <ol className="steps">
          <li className="step">
            <span>
              <strong>Åpne Entra admin center</strong> → Applications → App registrations → New registration.
            </span>
          </li>
          <li className="step">
            <span>
              <strong>Navn:</strong> <code>Horus Tools Portal</code> ·
              <strong> Supported account types:</strong> <em>Accounts in this organizational directory only (Single tenant)</em>.
            </span>
          </li>
          <li className="step">
            <span>
              <strong>Platform:</strong> velg <em>Single-page application</em> og lim inn denne <em>Redirect URI</em>:
              <CopyRow value={redirect} />
            </span>
          </li>
          <li className="step">
            <span>
              <strong>API permissions:</strong> <code>openid</code>, <code>profile</code>, <code>email</code>, <code>User.Read</code> (delegated). Klikk <em>Grant admin consent</em>.
            </span>
          </li>
          <li className="step">
            <span>
              Kopier <strong>Application (client) ID</strong> og <strong>Directory (tenant) ID</strong> fra app-oversikten og lim dem inn under.
            </span>
          </li>
        </ol>

        <div className="fields-grid">
          <div className="field">
            <label htmlFor="clientId">Application (client) ID</label>
            <input
              id="clientId"
              type="text"
              autoComplete="off"
              spellCheck="false"
              placeholder="00000000-0000-0000-0000-000000000000"
              value={clientId}
              onChange={(e) => setClientId(e.target.value)}
            />
          </div>
          <div className="field">
            <label htmlFor="tenantId">Directory (tenant) ID</label>
            <input
              id="tenantId"
              type="text"
              autoComplete="off"
              spellCheck="false"
              placeholder="00000000-0000-0000-0000-000000000000"
              value={tenantId}
              onChange={(e) => setTenantId(e.target.value)}
            />
          </div>
        </div>

        <div className="modal__actions">
          {wasConfigured ? (
            <button className="btn-ghost btn-ghost--danger" onClick={handleClear}>Koble fra</button>
          ) : <span />}
          <div style={{ display: 'flex', gap: 10 }}>
            <button className="btn-ghost" onClick={onClose}>Avbryt</button>
            <button className="btn-primary" disabled={!canSave} onClick={handleSave}>
              Lagre og bruk
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Landing — top bar + two tool cards
   ============================================================ */

function TopBar({ user, onLogout, theme, onToggleTheme }) {
  const initials = user.name.split(' ').map(p => p[0]).join('').slice(0, 2).toUpperCase();

  return (
    <header className="topbar">
      <img src="assets/logo-horus.png" alt="Horus" className="topbar__logo" />

      <div className="topbar__user">
        <ThemeToggle theme={theme} onToggle={onToggleTheme} />
        <div className="avatar" aria-hidden="true">{initials}</div>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', lineHeight: 1.25 }}>
          <span className="user-name">{user.name}</span>
          <span className="user-email">{user.email}</span>
        </div>
        <button className="logout-btn" onClick={onLogout}>
          <LogoutIcon /> Logg ut
        </button>
      </div>
    </header>
  );
}

function ToolCard({ index, title, desc, url, mark, onActivate }) {
  return (
    <a className="card" href="#" onClick={(e) => { e.preventDefault(); onActivate(); }} data-screen-label={`Card: ${title}`}>
      <span className="card__index">{index}</span>
      <div className="card__mark" style={{ color: 'var(--brand)' }}>{mark}</div>

      <h2 className="card__title">{title}</h2>
      <p className="card__desc">{desc}</p>

      <div className="card__footer">
        <span className="card__url">{url}</span>
        <span className="card__arrow"><ArrowIcon /></span>
      </div>
    </a>
  );
}

function Landing({ user, onLogout, onOpenTool, theme, onToggleTheme }) {
  return (
    <div className="landing" data-screen-label="Landing">
      <TopBar user={user} onLogout={onLogout} theme={theme} onToggleTheme={onToggleTheme} />

      <main className="landing__main">
        <div className="landing__band" aria-hidden="true"></div>

        <div className="landing__heading-block">
          <div className="mono-label">
            <span>001</span><span className="slash">/</span><span>Verktøy</span>
          </div>
          <h1 className="landing__heading">
            Horus <em>verktøy.</em>
          </h1>
          <p className="landing__sub">
            To interne verktøy, lukket for <code style={{ fontFamily: 'var(--font-mono)', fontSize: 14, color: 'var(--fg)' }}>@horus.no</code>. Velg ett for å fortsette.
          </p>
        </div>

        <div className="cards">
          <ToolCard
            index="01 / KPI"
            title="KPI-verktøy"
            desc="Følg månedlige nøkkeltall på tvers av virksomheten. Oppdater én gang og se snapshot-et for styret, banken og deg selv."
            url="kpi.horus-tools.no →"
            mark={<KpiMark />}
            onActivate={() => onOpenTool('kpi')}
          />
          <ToolCard
            index="02 / Linear"
            title="Linear-rapportering"
            desc="Lag ukentlige og månedlige statusrapporter fra Linear-prosjekter. Klare til å lime inn i en styrepakke."
            url="linear.horus-tools.no →"
            mark={<LinearMark />}
            onActivate={() => onOpenTool('linear')}
          />
        </div>
      </main>
    </div>
  );
}

/* Simple "you would now be redirected" subdomain stub */
function RedirectStub({ tool, onBack }) {
  const meta = tool === 'kpi'
    ? { url: 'kpi.horus-tools.no', name: 'KPI-verktøy' }
    : { url: 'linear.horus-tools.no', name: 'Linear-rapportering' };

  return (
    <div className="login" data-screen-label={`Redirect: ${meta.name}`}>
      <div className="login__glow" aria-hidden="true" style={{ opacity: 0.15 }}></div>
      <div className="login__shell">
        <div className="login__panel">
          <div className="login__label mono-label">
            <span>Sender deg videre</span><span className="slash">/</span><span>{meta.name}</span>
          </div>
          <h1 className="login__title" style={{ fontSize: 36 }}>
            Sender deg til<br /><em>{meta.url}</em>
          </h1>
          <p className="login__sub">
            I produksjon videresender dette til subdomenet. Den delte økt-informasjonskapselen tar med innloggingen på tvers av <code style={{ fontFamily: 'var(--font-mono)' }}>*.horus-tools.no</code>.
          </p>
          <button className="btn-ms" onClick={onBack}>
            <span style={{ transform: 'rotate(180deg)', display: 'inline-flex' }}><ArrowIcon /></span>
            <span>Tilbake til portalen</span>
          </button>
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   Root app — flow state + Tweaks
   ============================================================ */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "hoverStyle": "lift"
}/*EDITMODE-END*/;

const DEMO_USER = {
  name: 'Christian Erichsen',
  email: 'christian@horus.no'
};

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [screen, setScreen] = useState('login'); // 'login' | 'landing' | 'redirect' | 'login-rejected'
  const [redirectTool, setRedirectTool] = useState(null);
  const [user, setUser] = useState(null);
  const [signingIn, setSigningIn] = useState(false);
  const [signInError, setSignInError] = useState(null);
  const sessionChecked = useRef(false);

  // Reflect tweaks on <html> so theme + hover style cascade
  useEffect(() => {
    document.documentElement.dataset.theme = t.theme;
    document.documentElement.dataset.hover = t.hoverStyle;
  }, [t.theme, t.hoverStyle]);

  // On first mount, restore the session if any
  useEffect(() => {
    if (sessionChecked.current) return;
    sessionChecked.current = true;
    if (typeof HorusAuth === 'undefined' || !HorusAuth.isConfigured()) return;
    HorusAuth.getCurrent().then(u => {
      if (u) { setUser(u); setScreen('landing'); }
    });
  }, []);

  const handleSignIn = async () => {
    setSignInError(null);
    setSigningIn(true);
    try {
      const u = await HorusAuth.signIn();
      setUser(u);
      setScreen('landing');
    } catch (e) {
      if (e && e.code === 'NON_HORUS_ACCOUNT') {
        setScreen('login-rejected');
      } else if (e && e.errorCode === 'user_cancelled') {
        // user dismissed the popup, no message
      } else {
        setSignInError(e && e.message ? e.message : 'Ukjent feil.');
      }
    } finally {
      setSigningIn(false);
    }
  };

  const handleLogout = async () => {
    try { await HorusAuth.signOut(); } catch (_) {}
    setUser(null);
    setScreen('login');
  };

  let content;
  if (screen === 'login' || screen === 'login-rejected') {
    content = (
      <Login
        errorMode={screen === 'login-rejected'}
        onSignIn={handleSignIn}
        signingIn={signingIn}
        signInError={signInError}
        theme={t.theme}
        onToggleTheme={(v) => setTweak('theme', v)}
      />
    );
  } else if (screen === 'redirect') {
    content = <RedirectStub tool={redirectTool} onBack={() => setScreen('landing')} />;
  } else {
    content = (
      <Landing
        user={user || { name: '—', email: '' }}
        onLogout={handleLogout}
        onOpenTool={(tool) => { setRedirectTool(tool); setScreen('redirect'); }}
        theme={t.theme}
        onToggleTheme={(v) => setTweak('theme', v)}
      />
    );
  }

  return (
    <>
      {content}

      <TweaksPanel title="Tweaks">
        <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
          <TweakRadio
            label="Tema"
            value={t.theme}
            options={[
              { value: 'dark',  label: 'Mørk' },
              { value: 'light', label: 'Lys' },
            ]}
            onChange={(v) => setTweak('theme', v)}
          />
          <TweakRadio
            label="Kort-hover"
            value={t.hoverStyle}
            options={[
              { value: 'lift',    label: 'Løft' },
              { value: 'glow',    label: 'Glød' },
              { value: 'outline', label: 'Ramme' },
            ]}
            onChange={(v) => setTweak('hoverStyle', v)}
          />

          <div style={{ borderTop: '1px solid var(--border)', paddingTop: 14, display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.12em', color: 'var(--fg-dim)', fontFamily: 'var(--font-mono)' }}>
              Gå til skjerm
            </div>
            <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
              {[
                ['login',          'Logg inn'],
                ['login-rejected', 'Avvist'],
                ['landing',        'Portal'],
              ].map(([key, label]) => (
                <button
                  key={key}
                  onClick={() => setScreen(key)}
                  style={{
                    fontSize: 12,
                    fontFamily: 'var(--font-display)',
                    padding: '6px 10px',
                    borderRadius: 999,
                    border: '1px solid ' + (screen === key ? 'var(--brand)' : 'var(--border-strong)'),
                    background: screen === key ? 'var(--brand-soft)' : 'transparent',
                    color: screen === key ? 'var(--brand)' : 'var(--fg-muted)',
                    cursor: 'pointer',
                  }}
                >
                  {label}
                </button>
              ))}
            </div>
          </div>
        </div>
      </TweaksPanel>
    </>
  );
}

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