/* global React, PORTAL */
const { useState, useEffect, useCallback } = React;

// base64url helpers for WebAuthn ceremony
function b64url(buf) {
  const bytes = new Uint8Array(buf instanceof ArrayBuffer ? buf : buf.buffer || buf);
  return btoa(String.fromCharCode(...bytes)).replace(/\+/g,'-').replace(/\//g,'_').replace(/=/g,'');
}
function toBuffer(s) {
  s = s.replace(/-/g,'+').replace(/_/g,'/');
  while (s.length % 4) s += '=';
  return Uint8Array.from(atob(s), c=>c.charCodeAt(0)).buffer;
}

async function apiFetch(method, path, body) {
  const opts = { method, credentials: 'same-origin' };
  if (body) { opts.headers={'Content-Type':'application/json'}; opts.body=JSON.stringify(body); }
  const res = await fetch(`/api/portal${path}`, opts);
  if (res.status === 204) return null;
  return res.json();
}

function PasskeyRow({ cred, onDelete }) {
  const fmtDate = d => d ? new Date(d).toLocaleDateString('nl-NL',{day:'2-digit',month:'short',year:'numeric'}) : '—';
  return (
    <div style={{display:'flex',alignItems:'center',gap:12,padding:'10px 0',borderBottom:'1px solid var(--border)'}}>
      <div style={{fontSize:18,lineHeight:1}}>🔑</div>
      <div style={{flex:1}}>
        <div style={{fontSize:13,fontWeight:500}}>{cred.name || 'Passkey'}</div>
        <div style={{fontSize:11,color:'var(--fg-subtle)'}}>
          Added {fmtDate(cred.created_at)} · Last used {fmtDate(cred.last_used_at)}
        </div>
      </div>
      <button className="btn btn--danger btn--sm" style={{fontSize:11}} onClick={() => onDelete(cred)}>Remove</button>
    </div>
  );
}

function Profile() {
  const [form, setForm]         = useState({ name:'', email:'', phone:'' });
  const [busy, setBusy]         = useState(false);
  const [saved, setSaved]       = useState(false);
  const [passkeys, setPasskeys] = useState([]);
  const [pkBusy, setPkBusy]     = useState(false);
  const [pkError, setPkError]   = useState('');
  const hasWebAuthn = typeof window !== 'undefined' && !!window.PublicKeyCredential && !!navigator.credentials?.create;

  useEffect(() => {
    PORTAL.get('/profile').then(setForm).catch(()=>{});
  }, []);

  const loadPasskeys = useCallback(() => {
    apiFetch('GET', '/passkey').then(r => setPasskeys(r||[])).catch(()=>{});
  }, []);
  useEffect(() => { loadPasskeys(); }, [loadPasskeys]);

  const f = k => e => setForm(p=>({...p,[k]:e.target.value}));

  async function save(e) {
    e.preventDefault(); setBusy(true); setSaved(false);
    await PORTAL.put('/profile', form).catch(()=>{});
    setSaved(true); setBusy(false);
  }

  async function registerPasskey() {
    setPkError(''); setPkBusy(true);
    try {
      // Step 1: Get registration options
      const options = await apiFetch('GET', '/passkey/register-options');

      // Step 2: Convert options for browser API
      const publicKey = {
        challenge: toBuffer(options.challenge),
        rp: options.rp,
        user: { ...options.user, id: toBuffer(options.user.id) },
        pubKeyCredParams: options.pubKeyCredParams,
        timeout: options.timeout,
        attestation: options.attestation,
        authenticatorSelection: options.authenticatorSelection,
        excludeCredentials: (options.excludeCredentials||[]).map(c => ({type:'public-key',id:toBuffer(c.id)})),
      };

      // Step 3: Browser creates credential (Face ID / Touch ID / security key prompt)
      const cred = await navigator.credentials.create({ publicKey });

      // Step 4: Choose a name for this passkey
      const name = prompt('Name this passkey (e.g. "MacBook Touch ID"):', navigator.platform || 'My device') || null;

      // Step 5: Send to server
      await apiFetch('POST', '/passkey/register-verify', {
        id: cred.id,
        rawId: b64url(cred.rawId),
        type: cred.type,
        name,
        response: {
          attestationObject: b64url(cred.response.attestationObject),
          clientDataJSON:    b64url(cred.response.clientDataJSON),
        },
      });

      loadPasskeys();
    } catch (ex) {
      if (ex?.name === 'NotAllowedError') setPkError('Registration cancelled.');
      else setPkError(ex?.error || ex?.message || 'Registration failed');
    } finally { setPkBusy(false); }
  }

  async function deletePasskey(cred) {
    if (!confirm(`Remove passkey "${cred.name || 'Passkey'}"? You can still log in with a magic link.`)) return;
    await apiFetch('DELETE', `/passkey/${cred.id}`);
    loadPasskeys();
  }

  return (
    <div>
      <h1 className="page-title">My profile</h1>
      <div className="page-subtitle">Your contact details</div>

      <div className="card" style={{maxWidth:480}}>
        <form onSubmit={save}>
          <div className="card-body">
            {saved && <div className="alert" style={{background:'rgba(82,183,136,0.1)',border:'1px solid var(--ok)',color:'var(--ok)',marginBottom:12}}>Saved</div>}
            <div className="form-grid">
              <div className="field field--full">
                <label className="field-label">Full name</label>
                <input className="field-input" value={form.name||''} onChange={f('name')} />
              </div>
              <div className="field field--full">
                <label className="field-label">Email address</label>
                <input className="field-input" type="email" value={form.email||''} disabled style={{opacity:0.6}} />
              </div>
              <div className="field field--full">
                <label className="field-label">Phone</label>
                <input className="field-input" type="tel" value={form.phone||''} onChange={f('phone')} />
              </div>
            </div>
          </div>
          <div style={{padding:'12px 20px',borderTop:'1px solid var(--border)',display:'flex',justifyContent:'flex-end'}}>
            <button type="submit" className="btn btn--primary" disabled={busy}>{busy?'Saving…':'Save'}</button>
          </div>
        </form>
      </div>

      {hasWebAuthn && (
        <div className="card" style={{maxWidth:480,marginTop:16}}>
          <div className="card-head">
            <span className="card-title">Passkeys</span>
            <button className="btn btn--ghost btn--sm" disabled={pkBusy} onClick={registerPasskey}>
              {pkBusy ? 'Waiting…' : '+ Add passkey'}
            </button>
          </div>
          <div style={{padding:'0 20px 12px'}}>
            {pkError && <div className="alert alert--error" style={{margin:'8px 0'}}>{pkError}</div>}
            {passkeys.length === 0 && (
              <div style={{fontSize:12,color:'var(--fg-subtle)',padding:'12px 0'}}>
                No passkeys registered. Add one to sign in with Face ID, Touch ID, or a security key.
              </div>
            )}
            {passkeys.map(p => <PasskeyRow key={p.id} cred={p} onDelete={deletePasskey} />)}
          </div>
        </div>
      )}
    </div>
  );
}
window.Profile = Profile;
