/* Auth, roles, branding + Login =====================================
   "Relay" — multi-platform ad command. Authentication and all team /
   connection data now live in the MySQL backend (see /api). This file
   keeps the role matrix (mirrored server-side), the login screen, and
   shared identity UI. Theme + branding still persist to localStorage
   (cosmetic only).
=================================================================== */

/* ---------- localStorage (cosmetic prefs only) -------------------- */
const LS = {
  theme: 'relay_theme_v1',
  brand: 'relay_brand_v1',
};
function loadLS(key, fallback){
  try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : fallback; }
  catch(e){ return fallback; }
}
function saveLS(key, val){
  try { localStorage.setItem(key, JSON.stringify(val)); } catch(e){}
}

/* ---------- Roles & permissions (UI mirror of server rbac.php) ----- */
const ROLES = {
  super_admin: {
    label:'Super Admin', tone:'#8351ff', rank:5,
    blurb:'Full control. Manage users, roles, integrations and every account.',
    perms:['*'],
  },
  admin: {
    label:'Admin', tone:'#2f7bff', rank:4,
    blurb:'Manage integrations & accounts and act on campaigns. Cannot manage users.',
    perms:['integrations.manage','accounts.manage','campaigns.edit','automations.manage','reallocate.apply','columns.build','settings.manage','mediaplan.manage','reports.build','view'],
  },
  manager: {
    label:'Manager', tone:'#10b981', rank:3,
    blurb:'Edit campaigns, run automations and reallocate budget on assigned accounts.',
    perms:['campaigns.edit','automations.manage','reallocate.apply','columns.build','reports.build','view'],
  },
  analyst: {
    label:'Analyst', tone:'#06b6d4', rank:2,
    blurb:'View performance and build reports / custom columns. No live edits.',
    perms:['columns.build','reports.build','view'],
  },
  viewer: {
    label:'Viewer', tone:'#8b8b80', rank:1,
    blurb:'Read-only access to assigned accounts.',
    perms:['view'],
  },
  reporter: {
    label:'Reporter', tone:'#f59e0b', rank:1,
    blurb:'Report Builder only — build, export and import report data for assigned accounts. No dashboards or settings.',
    perms:['reports.build','data.import'],
  },
};
const ROLE_ORDER = ['super_admin','admin','manager','analyst','viewer','reporter'];

function can(user, perm){
  if (!user || user.status === 'suspended') return false;
  const perms = (ROLES[user.role] || {}).perms || [];
  return perms.includes('*') || perms.includes(perm);
}
/* Accounts a user may see. '*' = all. */
function accessibleAccounts(user){
  if (!user) return [];
  if (user.accounts === '*' || (Array.isArray(user.accounts) && user.accounts.includes('*')))
    return ACCOUNTS;
  return ACCOUNTS.filter(a => (user.accounts||[]).includes(a.id));
}

const AVATAR_TONES = ['#8351ff','#2f7bff','#10b981','#06b6d4','#f59e0b','#ec4899','#ef4444','#6366f1'];

/* ---------- Audit metadata (icons/verbs for the activity log) ------ */
const AUDIT_META = {
  'auth.signin':            { icon:'zap',        tone:'#06b6d4', verb:'signed in' },
  'auth.signout':           { icon:'link-break', tone:'#8b8b80', verb:'signed out' },
  'user.create':            { icon:'plus',       tone:'#10b981', verb:'invited' },
  'user.update':            { icon:'settings',   tone:'#2f7bff', verb:'updated' },
  'user.delete':            { icon:'x',          tone:'#ef4444', verb:'removed' },
  'account.create':         { icon:'plus',       tone:'#10b981', verb:'added account' },
  'account.update':         { icon:'settings',   tone:'#2f7bff', verb:'updated account' },
  'account.delete':         { icon:'x',          tone:'#ef4444', verb:'removed account' },
  'integration.update':     { icon:'settings',   tone:'#8351ff', verb:'updated connection' },
  'integration.connect':    { icon:'zap',        tone:'#10b981', verb:'connected' },
  'integration.disconnect': { icon:'link-break', tone:'#f59e0b', verb:'disconnected' },
  'integration.test':       { icon:'play',       tone:'#06b6d4', verb:'tested' },
  'data.import':            { icon:'plus',       tone:'#10b981', verb:'imported data to' },
};

/* ---------- Branding (cosmetic, localStorage) --------------------- */
const BRAND_DEFAULT = { name:'Relay', tag:'MCP', accent:'#8351ff', logo:null };
function loadBranding(){ return { ...BRAND_DEFAULT, ...(loadLS(LS.brand, {})||{}) }; }
function saveBranding(b){ saveLS(LS.brand, b); return b; }

/* Which platforms have a live (connected) feed, per integrations. */
function connectedPlatforms(integrations){
  const set = {};
  (integrations||[]).forEach(i => {
    if (i.status === 'connected') (i.platforms||[]).forEach(p => { set[p] = i.health || 'healthy'; });
  });
  return set;
}

/* ---------- Avatar ------------------------------------------------- */
function initialsOf(name){
  return String(name||'?').trim().split(/\s+/).map(s=>s[0]).slice(0,2).join('').toUpperCase();
}
function Avatar({ user, size=36, ring=false }){
  if (!user) return null;
  const tone = user.tone || '#8351ff';
  return (
    <span className="inline-flex items-center justify-center rounded-xl font-bold font-mono text-white flex-shrink-0 relative"
      style={{
        width:size, height:size, fontSize:size*0.36,
        background:`linear-gradient(135deg, ${tone}, ${tone}b3)`,
        boxShadow: ring ? `0 0 0 2px rgba(255,255,255,0.9), 0 0 0 4px ${tone}55` : 'none',
      }}>
      {initialsOf(user.name)}
      {user.status==='suspended' && (
        <span className="absolute -bottom-0.5 -right-0.5 w-3 h-3 rounded-full bg-rose-500 border-2 border-white dark:border-ink-900"/>
      )}
    </span>
  );
}

function RoleBadge({ role, size='md' }){
  const r = ROLES[role] || ROLES.viewer;
  const cls = size==='sm' ? 'text-[10px] px-1.5 py-0.5' : 'text-[11px] px-2 py-0.5';
  return (
    <span className={`inline-flex items-center gap-1 rounded-full font-medium ${cls}`}
      style={{ background:`${r.tone}1a`, color:r.tone }}>
      <span className="w-1.5 h-1.5 rounded-full" style={{ background:r.tone }}/>
      {r.label}
    </span>
  );
}

/* ===================================================================
   Login screen
=================================================================== */
function RelayMark({ size=34, tone='#8351ff' }){
  const s = size;
  return (
    <svg width={s} height={s} viewBox="0 0 40 40" fill="none">
      <line x1="8" y1="10" x2="20" y2="20" stroke={tone} strokeWidth="2" strokeLinecap="round" opacity="0.55"/>
      <line x1="8" y1="30" x2="20" y2="20" stroke={tone} strokeWidth="2" strokeLinecap="round" opacity="0.55"/>
      <line x1="32" y1="20" x2="20" y2="20" stroke={tone} strokeWidth="2" strokeLinecap="round" opacity="0.55"/>
      <circle cx="8"  cy="10" r="3.4" fill={tone} opacity="0.8"/>
      <circle cx="8"  cy="30" r="3.4" fill={tone} opacity="0.8"/>
      <circle cx="32" cy="20" r="3.4" fill={tone} opacity="0.8"/>
      <circle cx="20" cy="20" r="5.2" fill={tone}/>
      <circle cx="20" cy="20" r="5.2" fill="none" stroke={tone} strokeWidth="2">
        <animate attributeName="r" values="5.2;9;5.2" dur="2.4s" repeatCount="indefinite"/>
        <animate attributeName="opacity" values="0.6;0;0.6" dur="2.4s" repeatCount="indefinite"/>
      </circle>
    </svg>
  );
}

function BrandLogo({ brand, size=32 }){
  const b = brand || loadBranding();
  if (b.logo) return <img src={b.logo} alt="logo" width={size} height={size} style={{ width:size, height:size, objectFit:'contain', borderRadius:8 }}/>;
  return <RelayMark size={size} tone={b.accent||'#8351ff'}/>;
}

function Wordmark({ light=false, size=18, brand }){
  const b = brand || loadBranding();
  const accent = b.accent || '#8351ff';
  return (
    <span className="inline-flex items-baseline gap-1.5 font-semibold tracking-tight"
      style={{ fontSize:size, color: light ? '#fff' : undefined }}>
      {b.name || 'Relay'}
      {b.tag && <span className="font-mono font-medium px-1.5 py-0.5 rounded text-[0.6em] tracking-wider"
        style={{ background: light?'rgba(255,255,255,0.14)':accent+'1f', color: light?'#fff':accent }}>
        {b.tag}
      </span>}
    </span>
  );
}

/* onSignIn(email, password, remember) → Promise (rejects with {message} on failure). */
function LoginScreen({ onSignIn, brand }){
  const _brand = brand || loadBranding();
  const [email, setEmail]       = useState('');
  const [password, setPassword] = useState('');
  const [show, setShow]         = useState(false);
  const [error, setError]       = useState('');
  const [busy, setBusy]         = useState(false);
  const [remember, setRemember] = useState(true);

  const submit = (e) => {
    e && e.preventDefault();
    setError('');
    if (!email.trim() || !password) { setError('Enter your email and password.'); return; }
    setBusy(true);
    Promise.resolve(onSignIn(email.trim(), password, remember))
      .catch(err => { setError((err && err.message) || 'Sign-in failed. Try again.'); })
      .finally(() => setBusy(false));
  };

  return (
    <div className="relative min-h-screen w-full overflow-hidden bg-ink-900 text-white grid lg:grid-cols-[1.05fr_0.95fr]">
      <div className="pointer-events-none absolute inset-0 login-mesh"/>
      <div className="pointer-events-none absolute inset-0 login-grain opacity-[0.5]"/>

      {/* Left — brand / atmosphere */}
      <div className="relative hidden lg:flex flex-col justify-between p-12 xl:p-16">
        <div className="flex items-center gap-3">
          <BrandLogo brand={_brand} size={38}/>
          <Wordmark light size={22} brand={_brand}/>
        </div>

        <div className="relative">
          <div className="inline-flex items-center gap-2 text-[12px] font-mono text-accent-200/90 mb-5">
            <LiveDot tone="#9b74ff" size={7}/> MCP PIPELINE · LIVE
          </div>
          <h1 className="text-[42px] xl:text-[56px] leading-[1.0] font-semibold tracking-tight max-w-[14ch]">
            Every ad platform,<br/>wired through<br/><span className="text-accent-300">one relay.</span>
          </h1>
          <p className="mt-5 text-[15px] text-white/55 max-w-[44ch] leading-relaxed">
            Meta, Google, TikTok, Snap and X stream into a single command surface — via MCP, direct API, or manual import. Drill, reallocate and automate without leaving the page.
          </p>

          <div className="mt-9 relative flex items-center gap-2.5">
            <div className="login-signal pointer-events-none absolute left-4 right-12 top-1/2 h-px -translate-y-1/2 z-0"/>
            {['facebook','instagram','google','ga','tiktok','snapchat','x'].map((g,i)=>(
              <span key={i} className="relay-node relative z-10 inline-flex items-center justify-center w-9 h-9 rounded-xl bg-white/[0.06] border border-white/10 text-white/80"
                style={{ animationDelay:`${i*0.16}s`, transform:`translateY(${i%2===0?-2:2}px)` }}><BrandIcon name={g} size={18}/></span>
            ))}
            <span className="mx-1 relative z-10 text-white/25 font-mono text-[18px]">→</span>
            <span className="relative z-10 inline-flex items-center justify-center w-10 h-10 rounded-xl bg-accent-500/20 border border-accent-400/40 text-accent-200">
              <RelayMark size={22} tone="#b497ff"/>
            </span>
          </div>
        </div>

        <div className="text-[11.5px] font-mono text-white/30">
          {_brand.name} · secured workspace
        </div>
      </div>

      {/* Right — auth card */}
      <div className="relative flex items-center justify-center p-6 sm:p-10">
        <div className="w-full max-w-[400px]">
          <div className="lg:hidden flex items-center gap-2.5 mb-8 justify-center">
            <BrandLogo brand={_brand} size={32}/><Wordmark light size={20} brand={_brand}/>
          </div>

          <div className="rounded-2xl border border-white/10 bg-white/[0.04] backdrop-blur-xl p-7 shadow-float">
            <h2 className="text-[20px] font-semibold tracking-tight">Sign in to your workspace</h2>
            <p className="text-[13px] text-white/50 mt-1">Authenticate to open the live dashboard.</p>

            <form onSubmit={submit} className="mt-5 space-y-3">
              <label className="block">
                <span className="text-[12px] font-medium text-white/70">Email</span>
                <input type="email" value={email} autoFocus autoComplete="username"
                  onChange={e=>{ setEmail(e.target.value); setError(''); }}
                  placeholder="you@company.com"
                  className="mt-1.5 w-full h-11 px-3.5 rounded-xl bg-white/[0.04] border border-white/12 text-[14px] text-white placeholder-white/30 transition focus:outline-none hover:border-white/20 focus:border-accent-400/70 focus:ring-2 focus:ring-accent-500/25 focus:-translate-y-px"/>
              </label>

              <label className="block">
                <span className="text-[12px] font-medium text-white/70">Password</span>
                <div className="relative mt-1.5">
                  <input type={show?'text':'password'} value={password} autoComplete="current-password"
                    onChange={e=>{ setPassword(e.target.value); setError(''); }}
                    placeholder="••••••••"
                    className="w-full h-11 px-3.5 pr-11 rounded-xl bg-white/[0.04] border border-white/12 text-[14px] text-white placeholder-white/30 transition focus:outline-none hover:border-white/20 focus:border-accent-400/70 focus:ring-2 focus:ring-accent-500/25 focus:-translate-y-px"/>
                  <button type="button" onClick={()=>setShow(s=>!s)} title={show?'Hide password':'Show password'}
                    className="absolute right-1.5 top-1/2 -translate-y-1/2 h-8 w-8 grid place-items-center rounded-lg text-white/40 hover:text-white/80 hover:bg-white/10 transition">
                    <Icon name={show?'eye-off':'eye'} size={15}/>
                  </button>
                </div>
              </label>

              {error && (
                <div className="flex items-start gap-2 text-[12.5px] text-rose-300 bg-rose-500/10 border border-rose-500/25 rounded-lg px-3 py-2 animate-fadein">
                  <Icon name="alert" size={14} className="mt-0.5 flex-shrink-0"/>
                  <span>{error}</span>
                </div>
              )}

              <div className="flex items-center justify-between pt-0.5">
                <label className="inline-flex items-center gap-2 text-[12.5px] text-white/55 cursor-pointer select-none">
                  <input type="checkbox" checked={remember} onChange={e=>setRemember(e.target.checked)} className="accent-accent-500 w-3.5 h-3.5"/>
                  Keep me signed in
                </label>
                <span className="text-[12px] text-accent-300/80 hover:text-accent-200 cursor-pointer">Forgot password?</span>
              </div>

              <div className="relative group pt-0.5">
                <div className="absolute -inset-1 rounded-xl bg-accent-500/45 blur-md opacity-0 group-hover:opacity-100 transition-opacity duration-300 pointer-events-none"/>
                <button type="submit" disabled={busy}
                  className="relative w-full h-11 rounded-xl bg-accent-500 hover:bg-accent-400 disabled:opacity-70 text-white font-semibold text-[14px] transition flex items-center justify-center gap-2 shadow-[0_8px_24px_-6px_rgba(131,81,255,0.6)]">
                  {busy ? (<><span className="w-4 h-4 rounded-full border-2 border-white/40 border-t-white animate-spin"/> Signing in…</>) : (<>Sign in <Icon name="chev-right" size={16}/></>)}
                </button>
              </div>
            </form>
          </div>

          <div className="mt-4 text-center text-[11.5px] text-white/35 font-mono">
            Secured workspace · access provisioned by your admin
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  LS, loadLS, saveLS, ROLES, ROLE_ORDER, AVATAR_TONES, can, accessibleAccounts,
  AUDIT_META, connectedPlatforms, initialsOf, Avatar, RoleBadge,
  RelayMark, Wordmark, BrandLogo, LoginScreen, loadBranding, saveBranding, BRAND_DEFAULT,
});
