// ============================================================================
//  modals.jsx — Add / Edit pour entrées (mot de passe + Wi-Fi).
//  Toutes les modifs passent par la callback onSave qui re-chiffre le coffre
//  côté app.jsx puis pousse via PUT /api.php?action=vault.
// ============================================================================

(function (global) {
  'use strict';

  const { useState, useMemo } = React;

  // ─── Modal de base : header + corps + footer + Esc/Backdrop ──────────────

  function ModalShell({ title, subtitle, children, onCancel, footer }) {
    React.useEffect(() => {
      const onKey = (e) => { if (e.key === 'Escape') onCancel(); };
      window.addEventListener('keydown', onKey);
      return () => window.removeEventListener('keydown', onKey);
    }, [onCancel]);

    return (
      <div className="cp-modal-bg" onClick={onCancel}>
        <div className="cp-modal cp-modal-form" onClick={(e) => e.stopPropagation()}>
          <button className="cp-modal-x" onClick={onCancel} aria-label="Fermer">✕</button>
          <div className="cp-modal-head">
            <div>
              <h2>{title}</h2>
              {subtitle && <p>{subtitle}</p>}
            </div>
          </div>
          <div className="cp-modal-body">
            {children}
          </div>
          <div className="cp-modal-foot">
            {footer}
          </div>
        </div>
      </div>
    );
  }

  // ─── Champ texte étiqueté ────────────────────────────────────────────────

  function TextField({ label, value, onChange, type = 'text', placeholder, autoFocus, required, mono }) {
    return (
      <label className="cp-form-field">
        <span>{label}{required && <em> *</em>}</span>
        <input
          className={mono ? 'cp-form-input cp-form-mono' : 'cp-form-input'}
          type={type}
          value={value}
          onChange={(e) => onChange(e.target.value)}
          placeholder={placeholder || ''}
          autoFocus={autoFocus}
          required={required}
        />
      </label>
    );
  }

  function Textarea({ label, value, onChange, placeholder, rows = 3 }) {
    return (
      <label className="cp-form-field">
        <span>{label}</span>
        <textarea
          className="cp-form-input cp-form-textarea"
          rows={rows}
          value={value}
          placeholder={placeholder || ''}
          onChange={(e) => onChange(e.target.value)}
        />
      </label>
    );
  }

  function SelectField({ label, value, onChange, options }) {
    return (
      <label className="cp-form-field">
        <span>{label}</span>
        <select
          className="cp-form-input"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        >
          {options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
        </select>
      </label>
    );
  }

  function Toggle({ label, value, onChange }) {
    return (
      <div className="cp-form-toggle">
        <span>{label}</span>
        <button type="button"
          className="twk-toggle"
          data-on={value ? '1' : '0'}
          onClick={() => onChange(!value)}
        ><i /></button>
      </div>
    );
  }

  // ─── Champ password avec toggle visibilité + générateur + force ───────────

  function PasswordField({ label, value, onChange, autoFocus }) {
    const [show, setShow] = useState(false);
    const [genOpen, setGenOpen] = useState(false);

    return (
      <div className="cp-form-field">
        <span>{label}</span>
        <div className="cp-form-pwd">
          <input
            className="cp-form-input cp-form-mono"
            type={show ? 'text' : 'password'}
            value={value}
            onChange={(e) => onChange(e.target.value)}
            autoFocus={autoFocus}
          />
          <button type="button" className="cp-form-pwd-btn" onClick={() => setShow(!show)} title={show ? 'Masquer' : 'Afficher'}>
            <Icon name={show ? 'eye-off' : 'eye'} size={13} />
          </button>
          <button type="button" className="cp-form-pwd-btn" onClick={() => setGenOpen(true)} title="Générer">
            <Icon name="sparkle" size={13} />
          </button>
        </div>
        <PwdStrengthBar value={value} />
        {genOpen && (
          <PwdGenerator
            onApply={(p) => { onChange(p); setGenOpen(false); }}
            onCancel={() => setGenOpen(false)}
          />
        )}
      </div>
    );
  }

  function PwdStrengthBar({ value }) {
    const s = CPCrypto.passwordStrength(value);
    const colors = { weak: '#EF4444', medium: '#F59E0B', strong: '#10B981' };
    const labels = { weak: 'Faible', medium: 'Moyen', strong: 'Fort' };
    if (!value) return null;
    return (
      <div className="cp-form-strength">
        <div className="cp-form-strength-bar">
          <div className="cp-form-strength-fill"
               style={{ width: `${(s.score / 6) * 100}%`, background: colors[s.level] }} />
        </div>
        <span style={{ color: colors[s.level] }}>{labels[s.level]}</span>
      </div>
    );
  }

  function PwdGenerator({ onApply, onCancel }) {
    const [length,    setLength]    = useState(20);
    const [upper,     setUpper]     = useState(true);
    const [lower,     setLower]     = useState(true);
    const [digits,    setDigits]    = useState(true);
    const [symbols,   setSymbols]   = useState(true);
    const [noAmbig,   setNoAmbig]   = useState(false);
    const [pwd, setPwd] = useState(() => CPCrypto.generatePassword({ length: 20 }));

    const regen = () => {
      try {
        setPwd(CPCrypto.generatePassword({ length, upper, lower, digits, symbols, noAmbiguous: noAmbig }));
      } catch (e) { setPwd(''); }
    };
    React.useEffect(regen, [length, upper, lower, digits, symbols, noAmbig]);

    return (
      <div className="cp-pwd-gen">
        <div className="cp-pwd-gen-out">
          <code>{pwd || '⚠ Choisissez au moins une catégorie'}</code>
          <button type="button" className="cp-block-icbtn" onClick={regen} title="Regénérer">
            <Icon name="refresh" size={12} />
          </button>
        </div>
        <div className="cp-pwd-gen-controls">
          <label className="cp-form-field">
            <span>Longueur : {length}</span>
            <input type="range" min={8} max={64} value={length} onChange={e => setLength(+e.target.value)} />
          </label>
          <div className="cp-pwd-gen-toggles">
            <Toggle label="Majuscules" value={upper}   onChange={setUpper} />
            <Toggle label="Minuscules" value={lower}   onChange={setLower} />
            <Toggle label="Chiffres"   value={digits}  onChange={setDigits} />
            <Toggle label="Symboles"   value={symbols} onChange={setSymbols} />
            <Toggle label="Éviter caractères ambigus (0/O/l/1)" value={noAmbig} onChange={setNoAmbig} />
          </div>
        </div>
        <div className="cp-pwd-gen-actions">
          <button type="button" className="cp-btn" onClick={onCancel}>Annuler</button>
          <button type="button" className="cp-btn cp-btn-soft" onClick={() => onApply(pwd)} disabled={!pwd}>
            Utiliser ce mot de passe
          </button>
        </div>
      </div>
    );
  }

  // ─── Helpers d'options ───────────────────────────────────────────────────

  function folderOptions(folders) {
    const opts = [{ value: '', label: '— Aucun —' }];
    folders.forEach(f => {
      opts.push({ value: f.id, label: f.name });
      (f.children || []).forEach(c => opts.push({ value: c.id, label: '  ' + f.name + ' › ' + c.name }));
    });
    return opts;
  }

  // ─── EntryModal (mot de passe) ────────────────────────────────────────────

  const EntryModal = ({ mode, target, folders, onSave, onCancel }) => {
    const isAdd = mode === 'add';
    const [name,     setName]     = useState(target?.name || '');
    const [domain,   setDomain]   = useState(target?.domain || '');
    const [folderId, setFolderId] = useState(target?.folderId || '');
    const [favorite, setFavorite] = useState(!!target?.favorite);
    const [shared,   setShared]   = useState(!!target?.shared);
    const [accounts, setAccounts] = useState(
      target?.accounts?.length
        ? target.accounts.map(a => ({ ...a }))
        : [{ id: CPCrypto.genId('a'), label: 'Principal', username: '', password: '', created: new Date().toLocaleDateString('fr-FR') }]
    );
    const [totps, setTotps] = useState(target?.totp ? target.totp.map(t => ({ ...t })) : []);
    const [notes, setNotes] = useState(target?.notes || '');
    const [error, setError] = useState('');
    const [busy, setBusy] = useState(false);

    const updateAccount = (i, patch) => {
      setAccounts(arr => arr.map((a, k) => k === i ? { ...a, ...patch } : a));
    };
    const addAccount = () => setAccounts(arr => [...arr, {
      id: CPCrypto.genId('a'), label: 'Compte ' + (arr.length + 1),
      username: '', password: '', created: new Date().toLocaleDateString('fr-FR'),
    }]);
    const removeAccount = (i) => setAccounts(arr => arr.length > 1 ? arr.filter((_, k) => k !== i) : arr);

    const updateTotp = (i, patch) =>
      setTotps(arr => arr.map((t, k) => k === i ? { ...t, ...patch } : t));
    const addTotp = () => setTotps(arr => [...arr, {
      id: CPCrypto.genId('t'), label: 'Authenticator', secret: '', period: 30,
    }]);
    const removeTotp = (i) => setTotps(arr => arr.filter((_, k) => k !== i));

    const submit = async (e) => {
      e.preventDefault();
      setError('');
      if (!name.trim()) return setError('Nom requis.');
      if (accounts.some(a => !a.username || !a.password))
        return setError('Chaque compte doit avoir un identifiant et un mot de passe.');
      // Validation Base32 des secrets TOTP
      for (const t of totps) {
        if (t.secret) {
          try { CPCrypto.base32Decode(t.secret); }
          catch { return setError(`Secret TOTP invalide pour "${t.label}" (Base32 attendu).`); }
        }
      }

      // Strength = niveau du compte le plus faible.
      const levels = accounts.map(a => CPCrypto.passwordStrength(a.password).level);
      const order = { weak: 0, medium: 1, strong: 2 };
      const worst = levels.reduce((acc, l) => order[l] < order[acc] ? l : acc, 'strong');

      const entry = {
        id: target?.id || CPCrypto.genId('e'),
        name: name.trim(),
        domain: domain.trim(),
        category: target?.category || 'other',
        folderId: folderId || null,
        favorite, shared,
        modified: 'à l\'instant',
        color: target?.color || CPCrypto.colorFor(name.trim()),
        strength: worst,
        accounts: accounts.map(a => ({
          id: a.id, label: a.label || 'Principal',
          username: a.username, password: a.password,
          created: a.created || new Date().toLocaleDateString('fr-FR'),
        })),
        totp: totps.map(t => ({
          id: t.id, label: t.label || 'Authenticator',
          secret: t.secret, period: +t.period || 30, code: '------', remaining: 30,
        })),
        notes,
      };

      setBusy(true);
      try { await onSave(entry); }
      catch (err) { setError(err.message || 'Échec de la sauvegarde'); setBusy(false); }
    };

    return (
      <ModalShell
        title={isAdd ? 'Nouveau mot de passe' : 'Modifier l’entrée'}
        subtitle={isAdd ? 'Toutes les données sont chiffrées localement avant envoi.' : null}
        onCancel={onCancel}
        footer={
          <>
            <button type="button" className="cp-btn" onClick={onCancel}>Annuler</button>
            <button type="submit" form="entry-form" className="cp-btn cp-btn-soft" disabled={busy}>
              {busy ? 'Sauvegarde…' : (isAdd ? 'Créer' : 'Enregistrer')}
            </button>
          </>
        }
      >
        <form id="entry-form" onSubmit={submit} className="cp-form">
          <div className="cp-form-row">
            <TextField label="Nom" value={name} onChange={setName} required autoFocus
              placeholder="Amazon, GitHub, Crédit Agricole…" />
            <TextField label="Domaine" value={domain} onChange={setDomain}
              placeholder="amazon.fr" />
          </div>

          <div className="cp-form-row">
            <SelectField label="Dossier" value={folderId || ''} onChange={setFolderId}
              options={folderOptions(folders)} />
            <div className="cp-form-toggles">
              <Toggle label="Favori"   value={favorite} onChange={setFavorite} />
              <Toggle label="Partagé"  value={shared}   onChange={setShared} />
            </div>
          </div>

          <div className="cp-form-section">
            <div className="cp-section-head">
              <h3>Comptes</h3>
              <span className="cp-section-count">{accounts.length}</span>
              <span className="cp-section-spacer" />
              <button type="button" className="cp-section-add" onClick={addAccount}>
                <Icon name="plus" size={11} /><span>Ajouter</span>
              </button>
            </div>
            {accounts.map((a, i) => (
              <div key={a.id} className="cp-block">
                <div className="cp-block-head">
                  <input
                    className="cp-form-inline"
                    value={a.label}
                    onChange={e => updateAccount(i, { label: e.target.value })}
                    placeholder="Étiquette"
                  />
                  {i === 0 && <span className="cp-block-tag">principal</span>}
                  <span className="cp-block-spacer" />
                  {accounts.length > 1 && (
                    <button type="button" className="cp-block-icbtn" onClick={() => removeAccount(i)} title="Supprimer ce compte">
                      <Icon name="trash" size={12} />
                    </button>
                  )}
                </div>
                <TextField label="Identifiant" value={a.username}
                  onChange={(v) => updateAccount(i, { username: v })} />
                <PasswordField label="Mot de passe" value={a.password}
                  onChange={(v) => updateAccount(i, { password: v })} />
              </div>
            ))}
          </div>

          <div className="cp-form-section">
            <div className="cp-section-head">
              <h3>Codes 2FA (TOTP)</h3>
              <span className="cp-section-count">{totps.length}</span>
              <span className="cp-section-spacer" />
              <button type="button" className="cp-section-add" onClick={addTotp}>
                <Icon name="plus" size={11} /><span>Ajouter</span>
              </button>
            </div>
            {totps.map((t, i) => (
              <div key={t.id} className="cp-block">
                <div className="cp-block-head">
                  <input
                    className="cp-form-inline"
                    value={t.label}
                    onChange={e => updateTotp(i, { label: e.target.value })}
                    placeholder="Étiquette"
                  />
                  <span className="cp-block-spacer" />
                  <button type="button" className="cp-block-icbtn" onClick={() => removeTotp(i)} title="Supprimer ce 2FA">
                    <Icon name="trash" size={12} />
                  </button>
                </div>
                <TextField label="Secret (Base32)" value={t.secret} mono
                  onChange={(v) => updateTotp(i, { secret: v.replace(/\s+/g, '').toUpperCase() })}
                  placeholder="JBSWY3DPEHPK3PXP" />
                <SelectField label="Période" value={String(t.period || 30)}
                  onChange={(v) => updateTotp(i, { period: +v })}
                  options={[{ value: '30', label: '30 secondes' }, { value: '60', label: '60 secondes' }]} />
              </div>
            ))}
          </div>

          <Textarea label="Notes" value={notes} onChange={setNotes}
            placeholder="Informations annexes (codes de récupération, instructions…)" />

          {error && <div className="cp-form-error"><Icon name="alert" size={12} /><span>{error}</span></div>}
        </form>
      </ModalShell>
    );
  };

  // ─── WifiModal ────────────────────────────────────────────────────────────

  const WifiModal = ({ mode, target, folders, onSave, onCancel }) => {
    const isAdd = mode === 'add';
    const [name,     setName]     = useState(target?.name || '');
    const [ssid,     setSsid]     = useState(target?.ssid || '');
    const [password, setPassword] = useState(target?.password || '');
    const [security, setSecurity] = useState(target?.security || 'WPA2');
    const [hidden,   setHidden]   = useState(!!target?.hidden);
    const [folderId, setFolderId] = useState(target?.folderId || '');
    const [favorite, setFavorite] = useState(!!target?.favorite);
    const [shared,   setShared]   = useState(!!target?.shared);
    const [notes,    setNotes]    = useState(target?.notes || '');
    const [error,    setError]    = useState('');
    const [busy,     setBusy]     = useState(false);

    const submit = async (e) => {
      e.preventDefault();
      setError('');
      if (!name.trim()) return setError('Nom requis.');
      if (!ssid.trim()) return setError('SSID requis.');

      const strength = CPCrypto.passwordStrength(password).level;
      const entry = {
        id: target?.id || CPCrypto.genId('w'),
        type: 'wifi',
        name: name.trim(),
        ssid: ssid.trim(),
        domain: ssid.trim(),
        security, hidden,
        password,
        folderId: folderId || null,
        favorite, shared,
        modified: 'à l\'instant',
        color: target?.color || CPCrypto.colorFor(ssid.trim() || name.trim()),
        strength,
        accounts: [{ id: (target?.id || 'w') + '-a', label: 'SSID', username: ssid.trim(), password, created: '' }],
        totp: [],
        notes,
      };

      setBusy(true);
      try { await onSave(entry); }
      catch (err) { setError(err.message || 'Échec de la sauvegarde'); setBusy(false); }
    };

    return (
      <ModalShell
        title={isAdd ? 'Nouveau réseau Wi-Fi' : 'Modifier le réseau Wi-Fi'}
        onCancel={onCancel}
        footer={
          <>
            <button type="button" className="cp-btn" onClick={onCancel}>Annuler</button>
            <button type="submit" form="wifi-form" className="cp-btn cp-btn-soft" disabled={busy}>
              {busy ? 'Sauvegarde…' : (isAdd ? 'Créer' : 'Enregistrer')}
            </button>
          </>
        }
      >
        <form id="wifi-form" onSubmit={submit} className="cp-form">
          <div className="cp-form-row">
            <TextField label="Nom" value={name} onChange={setName} required autoFocus
              placeholder="Maison, Bureau…" />
            <TextField label="SSID (nom du réseau)" value={ssid} onChange={setSsid} required
              placeholder="Martin-Fibre-5G" />
          </div>
          <PasswordField label="Mot de passe Wi-Fi" value={password} onChange={setPassword} />
          <div className="cp-form-row">
            <SelectField label="Sécurité" value={security} onChange={setSecurity}
              options={[
                { value: 'WPA2', label: 'WPA2' },
                { value: 'WPA3', label: 'WPA3' },
                { value: 'WPA2-Enterprise', label: 'WPA2-Enterprise' },
                { value: 'WEP',  label: 'WEP (déconseillé)' },
                { value: 'nopass', label: 'Ouvert (aucune)' },
              ]} />
            <Toggle label="SSID caché" value={hidden} onChange={setHidden} />
          </div>
          <div className="cp-form-row">
            <SelectField label="Dossier" value={folderId || ''} onChange={setFolderId}
              options={folderOptions(folders)} />
            <div className="cp-form-toggles">
              <Toggle label="Favori"  value={favorite} onChange={setFavorite} />
              <Toggle label="Partagé" value={shared}   onChange={setShared} />
            </div>
          </div>
          <Textarea label="Notes" value={notes} onChange={setNotes} />
          {error && <div className="cp-form-error"><Icon name="alert" size={12} /><span>{error}</span></div>}
        </form>
      </ModalShell>
    );
  };

  global.EntryModal = EntryModal;
  global.WifiModal  = WifiModal;
})(window);
