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

const PM_TYPES = [
  { value: 'bank_transfer',    label: 'Bank account' },
  { value: 'creditcard',       label: 'Creditcard' },
  { value: 'paypal',           label: 'PayPal' },
  { value: 'ideal',            label: 'iDEAL' },
  { value: 'sepa_direct_debit',label: 'SEPA direct debit' },
  { value: 'wallet',           label: 'Digital wallet' },
  { value: 'cash',             label: 'Cash' },
  { value: 'other',            label: 'Other' },
];
const TYPE_LABEL = Object.fromEntries(PM_TYPES.map(t => [t.value, t.label]));

const ACCOUNT_HINT = {
  bank_transfer: 'IBAN — e.g. NL89 INGB 0001 2345 67',
  creditcard: 'Last 4 digits — e.g. •••• 4321',
  paypal: 'Email address',
  ideal: 'Bank — e.g. ING, Rabobank',
  sepa_direct_debit: 'Mandate reference or IBAN',
  wallet: 'Account name or identifier',
  cash: 'Optional note',
  other: 'Optional reference',
};

function MethodModal({ method, onSave, onClose }) {
  const isNew = !method?.id;
  const [form, setForm] = useState({
    name: '', type: 'bank_transfer', account_ref: '', is_default: 0,
    ...(method || {}),
  });
  const [busy, setBusy] = useState(false);
  const { toast } = useApp();
  const f = k => e => setForm(p => ({ ...p, [k]: e.target.value }));

  async function save() {
    if (!form.name.trim()) return;
    setBusy(true);
    try {
      if (isNew) {
        await API.post('/payment_methods', form);
      } else {
        await API.put(`/payment_methods/${method.id}`, form);
      }
      toast(isNew ? 'Payment method added' : 'Payment method updated');
      onSave();
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setBusy(false); }
  }

  return (
    <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
      <div className="modal" style={{ maxWidth: 480 }}>
        <div className="modal-head">
          <span className="modal-title">{isNew ? 'Add payment method' : 'Edit payment method'}</span>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <div className="form-grid">
            <div className="field field--full">
              <label className="field-label">Name *</label>
              <input
                className="field-input" autoFocus
                placeholder="e.g. ING betaalrekening, Revolut Visa, PayPal personal"
                value={form.name} onChange={f('name')}
                onKeyDown={e => e.key === 'Enter' && save()}
              />
            </div>
            <div className="field">
              <label className="field-label">Type</label>
              <select className="field-select" value={form.type} onChange={f('type')}>
                {PM_TYPES.map(t => <option key={t.value} value={t.value}>{t.label}</option>)}
              </select>
            </div>
            <div className="field">
              <label className="field-label">Account reference</label>
              <input
                className="field-input"
                placeholder={ACCOUNT_HINT[form.type] || 'Optional'}
                value={form.account_ref} onChange={f('account_ref')}
              />
            </div>
            <div className="field field--full" style={{ display:'flex', alignItems:'center', gap:10 }}>
              <input
                type="checkbox" id="pm-default"
                checked={!!form.is_default}
                onChange={e => setForm(p => ({ ...p, is_default: e.target.checked ? 1 : 0 }))}
              />
              <label htmlFor="pm-default" className="field-label" style={{ margin:0, cursor:'pointer' }}>
                Set as default payment method
              </label>
            </div>
          </div>
        </div>
        <div className="modal-foot">
          <button className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn--primary" onClick={save} disabled={busy || !form.name.trim()}>
            {isNew ? 'Add method' : 'Save'}
          </button>
        </div>
      </div>
    </div>
  );
}

function Settings() {
  const [methods, setMethods]       = useState([]);
  const [modal, setModal]           = useState(null);
  const [addingKey, setAddingKey]   = useState(false);
  const [whitelist, setWhitelist]   = useState([]);
  const [wlEmail, setWlEmail]       = useState('');
  const [wlLabel, setWlLabel]       = useState('');
  const [wlBusy, setWlBusy]         = useState(false);
  const [accessToken, setAccessToken] = useState(null);
  const [tokenVisible, setTokenVisible] = useState(false);
  const [tokenBusy, setTokenBusy]   = useState(false);
  const { toast } = useApp();

  const load = useCallback(() => {
    API.get('/payment_methods').then(setMethods).catch(() => {});
  }, []);

  const loadWl = useCallback(() => {
    API.get('/whitelist').then(setWhitelist).catch(() => {});
  }, []);

  const loadToken = useCallback(() => {
    API.get('/site-config').then(d => setAccessToken(d.token)).catch(() => {});
  }, []);

  useEffect(() => { load(); loadWl(); loadToken(); }, [load, loadWl, loadToken]);

  async function rotateToken() {
    if (!confirm('Rotate the access token? The current token will stop working immediately.')) return;
    setTokenBusy(true);
    try {
      const d = await API.post('/site-config');
      setAccessToken(d.token);
      setTokenVisible(true);
      toast('Access token rotated');
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setTokenBusy(false); }
  }

  function copyToken() {
    navigator.clipboard.writeText(accessToken || '').then(() => toast('Copied to clipboard'));
  }

  async function addToWhitelist() {
    if (!wlEmail.trim()) return;
    setWlBusy(true);
    try {
      await API.post('/whitelist', { email: wlEmail.trim(), label: wlLabel.trim() || null });
      toast(`${wlEmail.trim()} added to whitelist`);
      setWlEmail(''); setWlLabel('');
      loadWl();
    } catch (e) { toast(e.error || 'Error', 'error'); }
    finally { setWlBusy(false); }
  }

  async function removeFromWhitelist(entry) {
    if (!confirm(`Remove ${entry.email} from the whitelist?`)) return;
    await API.del(`/whitelist/${entry.id}`).catch(e => toast(e.error || 'Error', 'error'));
    toast('Removed from whitelist'); loadWl();
  }

  async function addPasskey() {
    setAddingKey(true);
    try {
      const { challenge } = await API.post('/auth/challenge');
      const credential = await navigator.credentials.create({
        publicKey: {
          challenge: API.fromb64url(challenge),
          rp: { id: location.hostname.replace(/^admin\./, ''), name: 'Lake-Project Admin' },
          user: { id: new Uint8Array(16), name: 'alexander', displayName: 'Alexander van der Plas' },
          pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
          authenticatorSelection: { authenticatorAttachment: 'platform', requireResidentKey: true, userVerification: 'required' },
          attestation: 'none',
          timeout: 60000,
        },
      });
      await API.post('/auth/register', {
        challenge,
        id: credential.id,
        rawId: API.b64url(credential.rawId),
        response: {
          attestationObject: API.b64url(credential.response.attestationObject),
          clientDataJSON: API.b64url(credential.response.clientDataJSON),
        },
      });
      toast('New passkey registered successfully');
    } catch (e) {
      toast(e.error || e.message || 'Registration failed', 'error');
    } finally { setAddingKey(false); }
  }

  async function del(m) {
    if (!confirm(`Remove "${m.name}"? Existing invoice links are kept.`)) return;
    await API.del(`/payment_methods/${m.id}`).catch(e => toast(e.error || 'Error', 'error'));
    toast('Removed'); load();
  }

  async function setDefault(m) {
    await API.put(`/payment_methods/${m.id}`, { ...m, is_default: 1 })
      .catch(e => toast(e.error || 'Error', 'error'));
    load();
  }

  return (
    <div className="page">
      <div className="page-header">
        <div>
          <h1 className="page-title">Settings</h1>
          <div className="page-subtitle">Payment methods and preferences</div>
        </div>
      </div>

      {/* Payment methods */}
      <div className="card" style={{ margin: 0 }}>
        <div className="card-head">
          <span className="card-title">Payment methods</span>
          <button className="btn btn--primary btn--sm" onClick={() => setModal({})}>+ Add method</button>
        </div>

        {methods.length === 0 ? (
          <div style={{ padding: '40px 20px' }}>
            <div className="empty-state">
              No payment methods yet — add your personal bank accounts, cards, and wallets
            </div>
          </div>
        ) : (
          <div className="table-wrap">
            <table className="data-table">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Type</th>
                  <th>Account reference</th>
                  <th>Default</th>
                  <th></th>
                </tr>
              </thead>
              <tbody>
                {methods.map(m => (
                  <tr key={m.id}>
                    <td style={{ fontWeight: 500 }}>
                      {m.name}
                    </td>
                    <td><span className="badge">{TYPE_LABEL[m.type] || m.type}</span></td>
                    <td>
                      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--fg-subtle)' }}>
                        {m.account_ref || '—'}
                      </span>
                    </td>
                    <td>
                      {m.is_default
                        ? <span style={{ color: 'var(--signal)', fontSize: 12, fontFamily: 'var(--font-mono)' }}>default</span>
                        : <button className="btn btn--ghost btn--sm" style={{ fontSize: '0.68rem' }} onClick={() => setDefault(m)}>Set default</button>}
                    </td>
                    <td>
                      <div className="row-actions">
                        <button className="btn btn--ghost btn--sm" onClick={() => setModal(m)}>Edit</button>
                        <button className="btn btn--danger btn--sm" onClick={() => del(m)}>Remove</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        <div style={{ padding: '12px 20px', borderTop: '1px solid var(--border)', fontSize: 11, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>
          Removing a method hides it from new selections but keeps historical invoice links intact.
        </div>
      </div>

      {/* Magic link whitelist */}
      <div className="card" style={{ margin: 0 }}>
        <div className="card-head">
          <span className="card-title">Magic link whitelist</span>
        </div>

        {whitelist.length === 0 ? (
          <div style={{ padding: '32px 20px' }}>
            <div className="empty-state">No addresses on the whitelist yet</div>
          </div>
        ) : (
          <div className="table-wrap">
            <table className="data-table">
              <thead><tr><th>Email</th><th>Name / label</th><th>Added</th><th></th></tr></thead>
              <tbody>
                {whitelist.map(e => (
                  <tr key={e.id}>
                    <td style={{ fontFamily:'var(--font-mono)', fontSize:12 }}>{e.email}</td>
                    <td style={{ color:'var(--fg-subtle)', fontSize:12 }}>{e.label || '—'}</td>
                    <td style={{ fontFamily:'var(--font-mono)', fontSize:11, color:'var(--fg-subtle)' }}>
                      {new Date(e.created_at).toLocaleDateString('nl-NL')}
                    </td>
                    <td>
                      <button className="btn btn--danger btn--sm" onClick={() => removeFromWhitelist(e)}>Remove</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}

        {/* Add email */}
        <div style={{ padding:'14px 20px', borderTop:'1px solid var(--border)', display:'flex', gap:8, alignItems:'flex-end', flexWrap:'wrap' }}>
          <div className="field" style={{ margin:0, flex:'1 1 200px', minWidth:0 }}>
            <label className="field-label">Email address</label>
            <input className="field-input" type="email" placeholder="someone@example.com"
              value={wlEmail} onChange={e => setWlEmail(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && addToWhitelist()} />
          </div>
          <div className="field" style={{ margin:0, flex:'1 1 140px', minWidth:0 }}>
            <label className="field-label">Label (optional)</label>
            <input className="field-input" placeholder="e.g. Alexander"
              value={wlLabel} onChange={e => setWlLabel(e.target.value)}
              onKeyDown={e => e.key === 'Enter' && addToWhitelist()} />
          </div>
          <button className="btn btn--primary" onClick={addToWhitelist}
            disabled={wlBusy || !wlEmail.trim()} style={{ flexShrink:0, marginBottom:0 }}>
            Add
          </button>
        </div>
        <div style={{ padding:'8px 20px 12px', fontSize:11, color:'var(--fg-subtle)', fontFamily:'var(--font-mono)' }}>
          Only addresses on this list can receive a magic link sign-in email.
        </div>
      </div>

      {/* Access token */}
      <div className="card" style={{ margin: 0 }}>
        <div className="card-head">
          <span className="card-title">Access token</span>
        </div>
        <div style={{ padding: '16px 20px' }}>
          <div style={{ fontSize: 12, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)', marginBottom: 12 }}>
            Emergency one-time login token. After use it auto-rotates — the new token appears here when you're back in.
          </div>
          {accessToken ? (
            <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
              <div style={{
                flex: 1, minWidth: 0,
                fontFamily: 'var(--font-mono)', fontSize: 12,
                padding: '8px 12px',
                background: 'var(--surface-raised)',
                border: '1px solid var(--border)',
                borderRadius: 6,
                letterSpacing: tokenVisible ? 1 : 4,
                filter: tokenVisible ? 'none' : 'blur(6px)',
                userSelect: tokenVisible ? 'text' : 'none',
                color: 'var(--fg)',
                overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                cursor: tokenVisible ? 'text' : 'pointer',
                transition: 'filter 0.2s',
              }}
                onClick={() => !tokenVisible && setTokenVisible(true)}
                title={tokenVisible ? '' : 'Click to reveal'}
              >
                {accessToken}
              </div>
              <button className="btn btn--ghost btn--sm" onClick={() => setTokenVisible(v => !v)}>
                {tokenVisible ? 'Hide' : 'Reveal'}
              </button>
              <button className="btn btn--ghost btn--sm" onClick={copyToken} disabled={!tokenVisible}>
                Copy
              </button>
              <button className="btn btn--danger btn--sm" onClick={rotateToken} disabled={tokenBusy}>
                Rotate
              </button>
            </div>
          ) : (
            <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
              <div style={{ flex: 1, fontSize: 12, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>
                No token set yet.
              </div>
              <button className="btn btn--primary btn--sm" onClick={rotateToken} disabled={tokenBusy}>
                Generate token
              </button>
            </div>
          )}
        </div>
      </div>

      {/* Passkeys */}
      <div className="card" style={{ margin: 0 }}>
        <div className="card-head">
          <span className="card-title">Passkeys</span>
        </div>
        <div style={{ padding: '16px 20px', display: 'flex', alignItems: 'center', gap: 16 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, marginBottom: 4 }}>Add this device</div>
            <div style={{ fontSize: 11, color: 'var(--fg-subtle)', fontFamily: 'var(--font-mono)' }}>
              Register a new passkey for the current device or hardware key. You must already be signed in.
            </div>
          </div>
          <button className="btn btn--ghost" onClick={addPasskey} disabled={addingKey} style={{ flexShrink: 0 }}>
            {addingKey ? 'Waiting for passkey…' : '+ Add passkey'}
          </button>
        </div>
      </div>

      {modal !== null && (
        <MethodModal
          method={modal?.id ? modal : null}
          onSave={() => { load(); setModal(null); }}
          onClose={() => setModal(null)}
        />
      )}
    </div>
  );
}
window.Settings = Settings;
