/* Mandera Portal — Auth (sessions + login) over MData.
   Roles: master (owner/admin), team (sub-master), client. */

const MA_SESSION = 'mandera_portal_session_v2';

const MAuth = {
  accounts() { return window.MData.get('accounts'); },
  byEmail(email) { return MAuth.accounts().find((a) => a.email === (email || '').trim().toLowerCase()); },
  login(email, pw) {
    const em = (email || '').trim().toLowerCase();
    const matches = MAuth.accounts().filter((a) => a.email === em);
    if (!matches.length) return { error: 'Those details don’t match an account.' };
    // If several accounts share an email, prefer the one whose password matches
    // (so a duplicate can never shadow the real account, e.g. a master).
    const a = matches.find((x) => x.password === pw) || matches[0];
    if (a.password !== pw) return { error: 'Those details don’t match an account.' };
    if (a.status === 'suspended') return { error: 'This account is suspended. Contact your Mandera lead.' };
    localStorage.setItem(MA_SESSION, a.id);
    return { account: a };
  },
  current() { const id = localStorage.getItem(MA_SESSION); return MAuth.accounts().find((a) => a.id === id) || null; },
  signOut() { localStorage.removeItem(MA_SESSION); },
  markOnboarded() {
    const a = MAuth.current(); if (!a) return;
    window.MData.update('accounts', a.id, { onboarded: true });
  },

  /* passwords */
  changePassword(id, current, next) {
    const a = MAuth.accounts().find((x) => x.id === id);
    if (!a) return { error: 'Account not found.' };
    if (a.password !== current) return { error: 'Your current password is incorrect.' };
    if (!next || next.length < 6) return { error: 'New password must be at least 6 characters.' };
    window.MData.update('accounts', id, { password: next, mustSetPassword: false });
    return { ok: true };
  },
  setOwnPassword(id, next) {
    if (!next || next.length < 6) return { error: 'Password must be at least 6 characters.' };
    window.MData.update('accounts', id, { password: next, mustSetPassword: false });
    return { ok: true };
  },
  resetByEmail(email, next) {
    const a = MAuth.byEmail(email);
    if (!a) return { error: 'No account uses that email.' };
    if (!next || next.length < 6) return { error: 'New password must be at least 6 characters.' };
    window.MData.update('accounts', a.id, { password: next, mustSetPassword: false });
    return { ok: true, account: a };
  },

  /* account admin (used by master/team) */
  create({ role, name, email, password, brand, clientId }) {
    const db = window.MData.load();
    let cid = clientId || null;
    if (role === 'client' && !cid) {
      const existing = db.clients.find((c) => c.brand.toLowerCase() === (brand || '').trim().toLowerCase());
      if (existing) cid = existing.id;
      else { const c = window.MData.add('clients', { brand: (brand || name).trim(), industry: '', contact: name, email: (email || '').trim().toLowerCase(), manager: 'Mandera', status: 'active' }); cid = c.id; }
    }
    // Clients must choose their own password on first sign-in.
    return window.MData.add('accounts', { role, name: name.trim(), email: (email || '').trim().toLowerCase(), password, status: 'active', onboarded: role !== 'client', clientId: cid, mustSetPassword: role === 'client' });
  },
  remove(id) {
    const a = window.MData.get('accounts').find((x) => x.id === id);
    window.MData.del('accounts', id);
    // If this was a client's sign-in and no other account is tied to that
    // client, remove the whole client workspace + data too — so deleting
    // the account genuinely deletes the client.
    if (a && a.role === 'client' && a.clientId) {
      const stillLinked = window.MData.get('accounts').some((x) => x.clientId === a.clientId);
      if (!stillLinked) window.MData.deleteClient(a.clientId);
    }
  },
  suspend(id, on) { window.MData.update('accounts', id, { status: on ? 'suspended' : 'active' }); },
  resetPassword(id, pw) { window.MData.update('accounts', id, { password: pw, mustSetPassword: true }); },
};

/* shared password input */
function PwInput({ value, onChange, placeholder, err }) {
  const [show, setShow] = React.useState(false);
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, height: 46, padding: '0 14px', background: 'var(--surface-sunken)', border: `1px solid ${err ? 'var(--critical)' : 'var(--border-default)'}`, borderRadius: 'var(--radius-md)' }}>
      <window.PIcon n="lock" s={16} color="var(--text-muted)" />
      <input type={show ? 'text' : 'password'} placeholder={placeholder || '••••••••'} value={value} onChange={onChange}
        style={{ flex: 1, minWidth: 0, height: '100%', border: 'none', outline: 'none', background: 'transparent', color: 'var(--text-strong)', fontFamily: 'var(--font-sans)', fontSize: 15 }} />
      <button type="button" onClick={() => setShow((s) => !s)} style={{ appearance: 'none', border: 'none', background: 'none', cursor: 'pointer', color: 'var(--text-muted)', display: 'inline-flex', padding: 0 }}>
        <window.PIcon n={show ? 'eye-off' : 'eye'} s={16} />
      </button>
    </div>
  );
}

/* ==================================================================== */
function Login({ go }) {
  const { Button, Input, Checkbox } = window.ManderaDesignSystem_8327ce;
  const [view, setView] = React.useState('signin'); // signin | forgot | setpw
  const [email, setEmail] = React.useState('');
  const [pw, setPw] = React.useState('');
  const [err, setErr] = React.useState('');
  const [pending, setPending] = React.useState(null); // account that must set password
  const [np1, setNp1] = React.useState('');
  const [np2, setNp2] = React.useState('');
  const [notice, setNotice] = React.useState('');
  const [checking, setChecking] = React.useState(false);
  const [sending, setSending] = React.useState(false);

  const proceed = (a) => {
    if (a.role === 'master' || a.role === 'team') { go('admin'); return; }
    go(a.onboarded ? 'app' : 'welcome');
  };

  const submitSignin = async (e) => {
    e.preventDefault();
    let res = MAuth.login(email, pw);
    // The account may have been created on another device and not yet synced
    // to this browser — pull the latest from the server and try once more
    // before telling the user it doesn't exist.
    if (res.error && res.error.indexOf('suspended') === -1) {
      setChecking(true);
      try { await window.MData.sync(); } catch (_) {}
      setChecking(false);
      res = MAuth.login(email, pw);
    }
    if (res.error) { setErr(res.error); return; }
    setErr('');
    if (res.account.mustSetPassword) { setPending(res.account); setNp1(''); setNp2(''); setView('setpw'); return; }
    proceed(res.account);
  };

  const submitSetpw = (e) => {
    e.preventDefault();
    if (np1 !== np2) { setErr('The two passwords don’t match.'); return; }
    const res = MAuth.setOwnPassword(pending.id, np1);
    if (res.error) { setErr(res.error); return; }
    setErr('');
    proceed(MAuth.current() || pending);
  };

  const submitForgot = async (e) => {
    e.preventDefault();
    if (!email.trim()) { setErr('Enter your account email.'); return; }
    setErr(''); setSending(true);
    // Server generates a one-time token and emails a reset link. It always
    // responds the same way so the form can't reveal which emails exist.
    try {
      await fetch('../api/portal-mail.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'request_reset', email: email.trim() }) });
    } catch (_) {}
    setSending(false);
    setNotice('If an account uses that email, we’ve sent a password reset link. Check your inbox (and spam folder).');
    setPw(''); setView('signin');
  };

  const Panel = (
    <div className="mp-login-panel" style={{ position: 'relative', overflow: 'hidden', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: '48px 56px', borderRight: '1px solid var(--border-subtle)' }}>
      <div style={{ position: 'absolute', inset: 0, background: 'var(--grad-hero)' }} />
      <window.MarkWash opacity={0.2} size={680} pos={{ bottom: '-220px', left: '-160px' }} />
      <div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
        <window.PLogo height={24} />
        <a href="../index.html" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, textDecoration: 'none', fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--text-muted)' }}
          onMouseEnter={(e) => e.currentTarget.style.color = 'var(--text-strong)'} onMouseLeave={(e) => e.currentTarget.style.color = 'var(--text-muted)'}>
          <window.PIcon n="arrow-left" s={14} /> Main website
        </a>
      </div>
      <div style={{ position: 'relative' }}>
        <span className="mandera-eyebrow">Client Portal</span>
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 52, lineHeight: 1.08, letterSpacing: '-0.015em', color: 'var(--text-strong)', margin: '14px 0 16px' }}>
          Your work,<br /><span style={{ fontStyle: 'italic', color: 'var(--accent-text)' }}>always in view.</span>
        </h1>
        <p style={{ fontFamily: 'var(--font-sans)', fontSize: 16, color: 'var(--text-secondary)', maxWidth: 360, lineHeight: 1.6, margin: 0 }}>
          Schedules, shoot and posting times, content and a direct line to your team — all in one place.
        </p>
      </div>
      <div style={{ position: 'relative', fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--text-faint)' }}>© 2026 Mandera Marketing Agency</div>
    </div>
  );

  let formBody;
  if (view === 'signin') {
    formBody = (
      <form onSubmit={submitSignin} style={{ width: '100%', maxWidth: 380, display: 'flex', flexDirection: 'column', gap: 20 }}>
        <div>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 32, color: 'var(--text-strong)', margin: 0 }}>Sign in</h2>
          <p style={{ fontFamily: 'var(--font-sans)', fontSize: 14.5, color: 'var(--text-muted)', margin: '8px 0 0' }}>Use the details your Mandera contact sent you.</p>
        </div>
        {notice && <div style={{ padding: '10px 14px', borderRadius: 'var(--radius-md)', background: 'var(--positive-soft)', border: '1px solid rgba(76,195,138,0.4)', fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--positive)' }}>{notice}</div>}
        <Input label="Email" type="email" placeholder="you@brand.com" value={email} onChange={(e) => { setEmail(e.target.value); setErr(''); setNotice(''); }} iconLeft={<window.PIcon n="mail" s={16} />} />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <label style={{ fontFamily: 'var(--font-sans)', fontSize: 13.5, fontWeight: 600, color: 'var(--text-secondary)' }}>Password</label>
            <button type="button" onClick={() => { setView('forgot'); setErr(''); setNp1(''); setNp2(''); }} style={{ appearance: 'none', border: 'none', background: 'none', cursor: 'pointer', fontFamily: 'var(--font-sans)', fontSize: 12.5, color: 'var(--accent-text)' }}>Forgot password?</button>
          </div>
          <PwInput value={pw} onChange={(e) => { setPw(e.target.value); setErr(''); }} err={err} />
          {err && <span style={{ fontFamily: 'var(--font-sans)', fontSize: 12.5, color: 'var(--critical)' }}>{err}</span>}
        </div>
        <Checkbox label="Keep me signed in" defaultChecked />
        <Button variant="primary" size="lg" type="submit" fullWidth disabled={checking} iconRight={<window.PIcon n="arrow-right" s={18} color="var(--ink-950)" />}>{checking ? 'Checking…' : 'Sign in'}</Button>
      </form>
    );
  } else if (view === 'setpw') {
    formBody = (
      <form onSubmit={submitSetpw} style={{ width: '100%', maxWidth: 380, display: 'flex', flexDirection: 'column', gap: 20 }}>
        <div>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 30, color: 'var(--text-strong)', margin: 0 }}>Choose your password</h2>
          <p style={{ fontFamily: 'var(--font-sans)', fontSize: 14.5, color: 'var(--text-muted)', margin: '8px 0 0' }}>Welcome, {pending && pending.name.split(' ')[0]}. Set a password you’ll remember — you’ll use it every time you sign in.</p>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          <label style={{ fontFamily: 'var(--font-sans)', fontSize: 13.5, fontWeight: 600, color: 'var(--text-secondary)' }}>New password</label>
          <PwInput value={np1} onChange={(e) => { setNp1(e.target.value); setErr(''); }} placeholder="At least 6 characters" err={err} />
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
          <label style={{ fontFamily: 'var(--font-sans)', fontSize: 13.5, fontWeight: 600, color: 'var(--text-secondary)' }}>Confirm password</label>
          <PwInput value={np2} onChange={(e) => { setNp2(e.target.value); setErr(''); }} err={err} />
          {err && <span style={{ fontFamily: 'var(--font-sans)', fontSize: 12.5, color: 'var(--critical)' }}>{err}</span>}
        </div>
        <Button variant="primary" size="lg" type="submit" fullWidth iconRight={<window.PIcon n="arrow-right" s={18} color="var(--ink-950)" />}>Set password & continue</Button>
      </form>
    );
  } else { // forgot
    formBody = (
      <form onSubmit={submitForgot} style={{ width: '100%', maxWidth: 380, display: 'flex', flexDirection: 'column', gap: 20 }}>
        <div>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 30, color: 'var(--text-strong)', margin: 0 }}>Reset password</h2>
          <p style={{ fontFamily: 'var(--font-sans)', fontSize: 14.5, color: 'var(--text-muted)', margin: '8px 0 0' }}>Enter your account email and we’ll send you a secure link to set a new password. The link expires in 1 hour.</p>
        </div>
        <Input label="Account email" type="email" placeholder="you@brand.com" value={email} onChange={(e) => { setEmail(e.target.value); setErr(''); }} iconLeft={<window.PIcon n="mail" s={16} />} />
        {err && <span style={{ fontFamily: 'var(--font-sans)', fontSize: 12.5, color: 'var(--critical)' }}>{err}</span>}
        <div style={{ display: 'flex', gap: 12 }}>
          <Button variant="ghost" onClick={() => { setView('signin'); setErr(''); }} iconLeft={<window.PIcon n="arrow-left" s={16} />}>Back</Button>
          <Button variant="primary" type="submit" disabled={sending} style={{ flex: 1 }} iconRight={<window.PIcon n="send" s={16} color="var(--ink-950)" />}>{sending ? 'Sending…' : 'Send reset link'}</Button>
        </div>
      </form>
    );
  }

  return (
    <div className="mp-login" style={{ position: 'relative', minHeight: '100vh', overflow: 'hidden', background: 'var(--bg-canvas)', display: 'grid', gridTemplateColumns: '1.1fr 1fr' }}>
      {Panel}
      <div className="mp-login-form" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '48px 56px', gap: 28 }}>
        {formBody}
        <a href="../index.html" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, textDecoration: 'none', fontFamily: 'var(--font-sans)', fontSize: 13, color: 'var(--text-faint)' }}
          onMouseEnter={(e) => e.currentTarget.style.color = 'var(--text-secondary)'} onMouseLeave={(e) => e.currentTarget.style.color = 'var(--text-faint)'}>
          <window.PIcon n="globe" s={14} /> Back to manderamarketing.com
        </a>
      </div>
    </div>
  );
}

Object.assign(window, { MAuth, Login, PwInput });
