// InstantDevis — Auth artisan V1 (email + code 6 chiffres + session opaque)

const AF_AUTH_STORAGE_KEY = 'instantdevis_auth_session';
const AF_AUTH_PENDING_CHALLENGE_KEY = 'instantdevis_auth_pending_challenge';

function _authWorkerBase() {
  const fromIntegration = (typeof AF_INTEGRATION !== 'undefined' && AF_INTEGRATION && AF_INTEGRATION.workersBase)
    ? String(AF_INTEGRATION.workersBase).trim()
    : '';
  if (fromIntegration) return fromIntegration.replace(/\/$/, '');
  const p = (typeof AF_PROFILE_STORE !== 'undefined' && AF_PROFILE_STORE && AF_PROFILE_STORE.get)
    ? AF_PROFILE_STORE.get()
    : {};
  const fromProfile = p && p.workersBaseUrl ? String(p.workersBaseUrl).trim() : '';
  if (fromProfile) return fromProfile.replace(/\/$/, '');
  return 'https://instantdevis-agents.sciencezvousyt.workers.dev';
}

function _maskEmail(email) {
  const s = String(email || '').trim().toLowerCase();
  const i = s.indexOf('@');
  if (i <= 1) return '***';
  const name = s.slice(0, i);
  const dom = s.slice(i + 1);
  const d0 = dom.split('.')[0] || '';
  return `${name.slice(0, 1)}***@${d0.slice(0, 2)}***`;
}

function _readSession() {
  try {
    const raw = localStorage.getItem(AF_AUTH_STORAGE_KEY);
    if (!raw) return null;
    const v = JSON.parse(raw);
    if (!v || typeof v !== 'object') return null;
    if (!v.sessionToken || !v.expiresAt) return null;
    return v;
  } catch (_e) {
    return null;
  }
}

function _saveSession(v) {
  const token = String(v && v.sessionToken ? v.sessionToken : '').trim();
  const expiresAt = String(v && v.expiresAt ? v.expiresAt : '').trim();
  if (!token || !expiresAt) return null;
  const next = {
    sessionToken: token,
    expiresAt,
    accountId: String(v && v.accountId ? v.accountId : '').trim(),
    emailMasked: String(v && v.emailMasked ? v.emailMasked : '').trim(),
    workspaceId: String(v && v.workspaceId ? v.workspaceId : '').trim(),
  };
  try { localStorage.setItem(AF_AUTH_STORAGE_KEY, JSON.stringify(next)); } catch (_e) {}
  return next;
}

function _clearSession() {
  try { localStorage.removeItem(AF_AUTH_STORAGE_KEY); } catch (_e) {}
}

function _readPendingChallenge() {
  try {
    const raw = localStorage.getItem(AF_AUTH_PENDING_CHALLENGE_KEY);
    if (!raw) return null;
    const v = JSON.parse(raw);
    if (!v || typeof v !== 'object') return null;
    const email = String(v.email || '').trim().toLowerCase();
    const challengeId = String(v.challengeId || '').trim();
    const expiresAt = String(v.expiresAt || '').trim();
    if (!email || !challengeId) return null;
    return { email, challengeId, expiresAt };
  } catch (_e) {
    return null;
  }
}

function _savePendingChallenge(v) {
  const email = String(v && v.email ? v.email : '').trim().toLowerCase();
  const challengeId = String(v && v.challengeId ? v.challengeId : '').trim();
  const expiresAt = String(v && v.expiresAt ? v.expiresAt : '').trim();
  if (!email || !challengeId) return null;
  const next = { email, challengeId, expiresAt };
  try { localStorage.setItem(AF_AUTH_PENDING_CHALLENGE_KEY, JSON.stringify(next)); } catch (_e) {}
  return next;
}

function _clearPendingChallenge() {
  try { localStorage.removeItem(AF_AUTH_PENDING_CHALLENGE_KEY); } catch (_e) {}
}

function getToken() {
  const s = _readSession();
  if (!s) return '';
  return String(s.sessionToken || '');
}

async function _post(path, body, opts) {
  const headers = { 'Content-Type': 'application/json' };
  if (opts && opts.bearer) headers.Authorization = `Bearer ${opts.bearer}`;
  const r = await fetch(`${_authWorkerBase()}${path}`, {
    method: 'POST',
    headers,
    body: JSON.stringify(body || {}),
  });
  const data = await r.json().catch(() => ({}));
  if (!r.ok) {
    const err = new Error((data && data.message) || 'auth_error');
    err.status = r.status;
    err.data = data || {};
    throw err;
  }
  return data || {};
}

async function startEmailAuth(email) {
  const normalized = String(email || '').trim().toLowerCase();
  const data = await _post('/v1/auth/email/start', { email: normalized, purpose: 'login' });
  _savePendingChallenge({
    email: normalized,
    challengeId: data && data.challengeId,
    expiresAt: data && data.expiresAt ? data.expiresAt : '',
  });
  return data;
}

async function verifyEmailCode({ email, challengeId, code, deviceLabel }) {
  const pending = _readPendingChallenge();
  const normalizedEmail = String(email || (pending && pending.email) || '').trim().toLowerCase();
  const resolvedChallengeId = String(challengeId || (pending && pending.challengeId) || '').trim();
  const normalizedCode = String(code || '').trim().replace(/\s+/g, '').replace(/\D+/g, '').slice(0, 6);
  if (!/^\d{6}$/.test(normalizedCode)) {
    const err = new Error('invalid_or_expired_code');
    err.status = 400;
    throw err;
  }
  const data = await _post('/v1/auth/email/verify', {
    email: normalizedEmail,
    challengeId: resolvedChallengeId,
    code: normalizedCode,
    deviceLabel: String(deviceLabel || '').trim().slice(0, 80),
  });
  if (data && data.sessionToken && data.expiresAt) {
    _saveSession({
      sessionToken: data.sessionToken,
      expiresAt: data.expiresAt,
      accountId: data.account && data.account.id,
      emailMasked: data.account && data.account.emailMasked,
      workspaceId: data.workspace && data.workspace.id,
    });
    _clearPendingChallenge();
  }
  return data;
}

async function validateSession() {
  const s = _readSession();
  if (!s) return { ok: false, reason: 'no_session' };
  try {
    const data = await _post('/v1/auth/session', {}, { bearer: s.sessionToken });
    const next = _saveSession({
      sessionToken: s.sessionToken,
      expiresAt: data && data.session && data.session.expiresAt ? data.session.expiresAt : s.expiresAt,
      accountId: data && data.account && data.account.id,
      emailMasked: data && data.account && data.account.emailMasked,
      workspaceId: data && data.workspace && data.workspace.id,
    });
    return { ok: true, session: next || s, data };
  } catch (_e) {
    _clearSession();
    return { ok: false, reason: 'invalid' };
  }
}

async function logout(opts) {
  const s = _readSession();
  if (!s) { _clearSession(); _clearPendingChallenge(); return { ok: true, skipped: true }; }
  try {
    await _post('/v1/auth/logout', { allDevices: !!(opts && opts.allDevices) }, { bearer: s.sessionToken });
  } catch (_e) {}
  _clearSession();
  _clearPendingChallenge();
  return { ok: true };
}

function getSession() { return _readSession(); }

function isLoggedIn() {
  const s = _readSession();
  if (!s) return false;
  const exp = Date.parse(String(s.expiresAt || ''));
  if (Number.isFinite(exp) && exp <= Date.now()) return false;
  return !!String(s.sessionToken || '');
}

function authFetch(input, init) {
  const s = _readSession();
  const headers = new Headers((init && init.headers) || {});
  if (s && s.sessionToken) headers.set('Authorization', `Bearer ${s.sessionToken}`);
  return fetch(input, { ...(init || {}), headers });
}

function AuthVerifyPage() {
  const t = (typeof afTokens !== 'undefined') ? afTokens.light : {
    bg: '#F1EFEB', text: '#15202B', textMuted: '#5A6772', primary: '#0B3D5C', border: 'rgba(21,32,43,0.12)',
  };
  const qp = new URLSearchParams(window.location.search || '');
  const [email, setEmail] = React.useState(() => {
    const pending = _readPendingChallenge();
    return (pending && pending.email) || qp.get('email') || '';
  });
  const [code, setCode] = React.useState('');
  const [state, setState] = React.useState('idle');
  const [msg, setMsg] = React.useState('');

  const submit = async () => {
    if (state === 'loading') return;
    setState('loading');
    setMsg('');
    try {
      await verifyEmailCode({ email, code, deviceLabel: navigator.userAgent.slice(0, 80) });
      setState('ok');
      setMsg('Connexion validée. Retour à l’application…');
      setTimeout(() => { window.location.href = '/app'; }, 700);
    } catch (_e) {
      setState('error');
      setMsg('Code invalide ou expiré.');
    }
  };

  return (
    <div style={{ minHeight: '100dvh', background: t.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
      <div style={{ width: '100%', maxWidth: 480, background: '#fff', border: `1px solid ${t.border}`, borderRadius: 12, padding: 16, display: 'flex', flexDirection: 'column', gap: 10 }}>
        <div style={{ fontSize: 20, fontWeight: 800, color: t.primary }}>Vérification du code</div>
        <div style={{ fontSize: 12, color: t.textMuted, lineHeight: 1.45 }}>
          Saisissez le code à 6 chiffres reçu par e-mail pour finaliser votre connexion artisan.
        </div>
        <input value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" style={{ height: 44, borderRadius: 8, border: `1px solid ${t.border}`, padding: '0 12px', fontSize: 14 }} />
        <input value={code} onChange={(e) => setCode(String(e.target.value || '').replace(/\D+/g, '').slice(0, 6))} placeholder="Code 6 chiffres" style={{ height: 44, borderRadius: 8, border: `1px solid ${t.border}`, padding: '0 12px', fontSize: 18, letterSpacing: 4, fontFamily: 'monospace' }} />
        {!!msg && <div style={{ fontSize: 12, color: state === 'ok' ? '#0f766e' : '#b91c1c' }}>{msg}</div>}
        <button onClick={submit} disabled={state === 'loading' || !email || code.length !== 6} style={{ height: 46, borderRadius: 8, border: 'none', background: t.primary, color: '#fff', fontSize: 14, fontWeight: 800, opacity: (state === 'loading' || !email || code.length !== 6) ? 0.7 : 1 }}>
          {state === 'loading' ? 'Vérification…' : 'Valider le code'}
        </button>
        <button onClick={() => { window.location.href = '/app'; }} style={{ height: 42, borderRadius: 8, border: `1px solid ${t.border}`, background: '#fff', color: t.text, fontSize: 13, fontWeight: 700 }}>
          Retour à l’app
        </button>
      </div>
    </div>
  );
}

const AF_AUTH_SESSION = {
  startEmailAuth,
  verifyEmailCode,
  validateSession,
  logout,
  getSession,
  isLoggedIn,
  getToken,
  authFetch,
  clearSession: _clearSession,
  maskEmail: _maskEmail,
};

Object.assign(window, { AF_AUTH_SESSION, AuthVerifyPage });

// Validation session au démarrage (silencieuse)
validateSession().catch(() => {});
