/* =====================================================================
 * Connexion, changement de mot de passe et initialisation du serveur.
 * ===================================================================== */

function PasswordInput({ value, onChange, autoFocus, placeholder, autoComplete = 'current-password', visible: forcedVisible }) {
  const [visible, setVisible] = useState(false);
  const shown = forcedVisible || visible;
  return (
    <div className="relative">
      <input
        type={shown ? 'text' : 'password'}
        className="input pr-10"
        value={value}
        autoFocus={autoFocus}
        placeholder={placeholder}
        autoComplete={autoComplete}
        onChange={(e) => onChange(e.target.value)}
      />
      <button
        type="button"
        tabIndex={-1}
        onClick={() => setVisible((v) => !v)}
        className="absolute inset-y-0 right-2 flex items-center px-1 text-slate-400 hover:text-slate-600"
        title={shown ? 'Masquer' : 'Afficher'}
      >
        <Eye className="h-4 w-4" />
      </button>
    </div>
  );
}

function FullScreenMessage({ children }) {
  return (
    <div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-slate-900 via-slate-800 to-red-900 p-4 text-center text-white">
      <div>{children}</div>
    </div>
  );
}

function LoginScreen() {
  const { login, session } = useApp();
  const [identifiant, setIdentifiant] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);
  const shownError = error || session.error;

  const submit = async (e) => {
    e.preventDefault();
    setBusy(true);
    const err = await login(identifiant, password);
    setError(err || '');
    if (err) setPassword('');
    setBusy(false);
  };

  return (
    <div className="flex min-h-screen items-center justify-center bg-gradient-to-br from-slate-900 via-slate-800 to-red-900 p-4">
      <form onSubmit={submit} className="w-full max-w-sm rounded-2xl bg-white p-8 shadow-2xl">
        <div className="mb-6 flex flex-col items-center text-center">
          <div className="mb-3 flex h-14 w-14 items-center justify-center rounded-2xl bg-red-600 text-white shadow-lg shadow-red-600/30">
            <Siren className="h-8 w-8" />
          </div>
          <h1 className="text-xl font-bold text-slate-900">SAP Manager</h1>
          <p className="text-sm text-slate-500">{session.centre}</p>
        </div>

        <div className="space-y-4">
          <Field label="Identifiant ou email">
            <TextInput value={identifiant} onChange={setIdentifiant} autoFocus autoComplete="username" placeholder="prenom.nom" />
          </Field>
          <Field label="Mot de passe">
            <PasswordInput value={password} onChange={setPassword} />
          </Field>
          {shownError && (
            <p className="flex items-center gap-2 rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">
              <AlertTriangle className="h-4 w-4 shrink-0" /> {shownError}
            </p>
          )}
          <button
            type="submit"
            disabled={busy || !identifiant || !password}
            className="flex w-full items-center justify-center gap-2 rounded-lg bg-red-600 px-4 py-3 font-semibold text-white shadow-sm transition hover:bg-red-700 disabled:opacity-50"
          >
            <LockIcon className="h-4 w-4" />
            {busy ? 'Connexion…' : 'Se connecter'}
          </button>
        </div>
        <p className="mt-6 text-center text-xs text-slate-400">Mot de passe oublié : contactez un administrateur.</p>
      </form>
    </div>
  );
}

/** Changement de son propre mot de passe (obligatoire si `forced`). */
function ChangePasswordModal({ forced, onClose }) {
  const { changeOwnPassword, notify, logout } = useApp();
  const [current, setCurrent] = useState('');
  const [next, setNext] = useState('');
  const [confirm, setConfirm] = useState('');
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);

  const save = async () => {
    const err = passwordError(next, confirm);
    if (err) return setError(err);
    if (next === current) return setError("Le nouveau mot de passe doit être différent de l'actuel.");
    setBusy(true);
    try {
      await changeOwnPassword(current, next);
      notify('Mot de passe modifié');
      if (onClose) onClose();
    } catch (e) {
      setError(e.message);
      setBusy(false);
    }
  };

  return (
    <Modal
      open
      size="sm"
      icon={LockIcon}
      title={forced ? 'Définissez votre mot de passe' : 'Changer mon mot de passe'}
      subtitle={forced ? 'Le mot de passe initial doit être remplacé avant de continuer.' : undefined}
      onClose={forced ? undefined : onClose}
      footer={
        <Fragment>
          <Button variant="secondary" onClick={forced ? logout : onClose}>
            {forced ? 'Se déconnecter' : 'Annuler'}
          </Button>
          <Button icon={Save} onClick={save} disabled={busy || !current || !next || !confirm}>
            {busy ? 'Enregistrement…' : 'Enregistrer'}
          </Button>
        </Fragment>
      }
    >
      <div className="space-y-4">
        <Field label="Mot de passe actuel">
          <PasswordInput value={current} onChange={setCurrent} autoFocus />
        </Field>
        <Field label="Nouveau mot de passe" hint={`${PASSWORD_MIN_LENGTH} caractères minimum. Une phrase de passe est plus sûre et plus facile à retenir.`}>
          <PasswordInput value={next} onChange={setNext} autoComplete="new-password" />
        </Field>
        <Field label="Confirmer le nouveau mot de passe">
          <PasswordInput value={confirm} onChange={setConfirm} autoComplete="new-password" />
        </Field>
        {error && <p className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">{error}</p>}
      </div>
    </Modal>
  );
}

/** Définition du mot de passe d'un autre compte par un administrateur. */
function AdminPasswordModal({ user, onClose }) {
  const { setUserPassword, notify } = useApp();
  const [next, setNext] = useState('');
  const [confirm, setConfirm] = useState('');
  const [mustChange, setMustChange] = useState(true);
  const [generated, setGenerated] = useState(false);
  const [error, setError] = useState('');
  const [busy, setBusy] = useState(false);

  const generate = () => {
    const pw = generatePassword();
    setNext(pw);
    setConfirm(pw);
    setGenerated(true);
  };

  const save = async () => {
    const err = passwordError(next, confirm);
    if (err) return setError(err);
    setBusy(true);
    try {
      await setUserPassword(user.id, next, mustChange);
      notify(`Mot de passe défini pour ${user.prenom} ${user.nom}`);
      onClose();
    } catch (e) {
      setError(e.message);
      setBusy(false);
    }
  };

  return (
    <Modal
      open
      size="sm"
      icon={LockIcon}
      title="Définir le mot de passe"
      subtitle={`${user.prenom} ${user.nom} — identifiant « ${user.identifiant} »`}
      onClose={onClose}
      footer={
        <Fragment>
          <Button variant="secondary" onClick={onClose}>
            Annuler
          </Button>
          <Button icon={Save} onClick={save} disabled={busy || !next || !confirm}>
            {busy ? 'Enregistrement…' : 'Enregistrer'}
          </Button>
        </Fragment>
      }
    >
      <div className="space-y-4">
        <Field label="Nouveau mot de passe" hint={`${PASSWORD_MIN_LENGTH} caractères minimum`}>
          <PasswordInput value={next} onChange={(v) => { setNext(v); setGenerated(false); }} autoFocus autoComplete="new-password" visible={generated} />
        </Field>
        <Field label="Confirmer">
          <PasswordInput value={confirm} onChange={(v) => { setConfirm(v); setGenerated(false); }} autoComplete="new-password" visible={generated} />
        </Field>
        <Button variant="secondary" size="sm" icon={RotateCcw} onClick={generate}>
          Générer un mot de passe
        </Button>
        {generated && (
          <p className="rounded-lg bg-amber-50 px-3 py-2 text-sm text-amber-800">
            Communiquez ce mot de passe à l'utilisateur de façon sûre (en main propre, pas par message).
          </p>
        )}
        <Checkbox checked={mustChange} onChange={setMustChange} label="Demander à l'utilisateur de le changer à la prochaine connexion" />
        {error && <p className="rounded-lg bg-red-50 px-3 py-2 text-sm text-red-700">{error}</p>}
      </div>
    </Modal>
  );
}

/** Premier démarrage : choix des données envoyées au serveur. */
function SetupModal() {
  const { completeSetup, legacyAvailable, notify } = useApp();
  const [busy, setBusy] = useState(false);
  const legacy = useMemo(() => (legacyAvailable ? readLegacyData() : null), [legacyAvailable]);
  const count = (list) => (Array.isArray(list) ? list.length : 0);

  const run = async (useLegacy) => {
    setBusy(true);
    try {
      await completeSetup(useLegacy);
      notify('Serveur initialisé');
    } catch (e) {
      notify(e.message, 'red');
      setBusy(false);
    }
  };

  return (
    <Modal open size="md" icon={Package} title="Initialisation du serveur" subtitle="Première connexion administrateur">
      <div className="space-y-4 text-sm text-slate-600">
        <p>Les données sont désormais enregistrées sur le serveur et partagées entre tous les comptes.</p>
        {legacy ? (
          <Fragment>
            <p>
              Ce navigateur contient des données de l'ancienne version : <strong>{count(legacy.bilans)} bilan(s)</strong>,{' '}
              <strong>{count(legacy.jsp)} JSP</strong>, <strong>{count(legacy.stock)} pièces de stock</strong> et{' '}
              <strong>{count(legacy.users)} compte(s)</strong>. Les comptes repris n'auront pas de mot de passe : vous les définirez dans
              « Gestion accès ».
            </p>
            <div className="flex flex-col gap-2 sm:flex-row">
              <Button icon={Upload} disabled={busy} onClick={() => run(true)}>
                Transférer ces données
              </Button>
              <Button variant="secondary" disabled={busy} onClick={() => run(false)}>
                Démarrer avec la section JSP de référence
              </Button>
            </div>
          </Fragment>
        ) : (
          <Fragment>
            <p>Le serveur va être initialisé avec la section JSP de référence (22 JSP et leur stock).</p>
            <Button icon={CheckCircle2} disabled={busy} onClick={() => run(false)}>
              Initialiser
            </Button>
          </Fragment>
        )}
      </div>
    </Modal>
  );
}
