// Carte — miroir mobile du flow web (mêmes données ui_kits/shared/carte.js,
// même visuel partagé CardVisual.jsx — pas de re-conception, format téléphone).
// Verrouillage réversible, réglages instantanés, plafonds, opérations avec
// états, PIN à appui maintenu, opposition → remplacement. BottomSheets.
// window.OryzeApp.CarteScreen
(function () {
  const { Card, Amount, Button, StatusBadge, Avatar, Tabs, Toggle, ProgressRing, Input, BottomSheet, Tag, IconButton } = window.OryzeDesignSystem_78c60a;
  const Ic = window.OryzeIcons;

  const CARTE = window.OryzeCarte.card;
  const OPERATIONS = window.OryzeCarte.operations;
  const STATUT_CARTE = window.OryzeCarte.statutCarte;
  const CardVisual = window.OryzeShared.CardVisual;
  const { NewCardFlow, PinChangeFlow, ClosureVerify, DeliveryInfoPanel } = window.OryzeShared;

  function SettingRow({ icon, label, sub, checked, onChange, disabled, first }) {
    return (
      <div style={{ display: "flex", alignItems: "center", gap: 11, padding: "11px 14px", borderTop: first ? "none" : "1px solid var(--line-divider)", opacity: disabled ? 0.45 : 1 }}>
        <span style={{ width: 30, height: 30, borderRadius: 8, background: "var(--surface-sunken)", border: "var(--border-hair) solid var(--line-divider)", display: "inline-flex", alignItems: "center", justifyContent: "center", flex: "none", color: "var(--text-body)" }}>{icon}</span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600 }}>{label}</div>
          <div style={{ fontSize: 11, color: "var(--text-subtle)", marginTop: 1 }}>{sub}</div>
        </div>
        <Toggle checked={checked} onChange={onChange} disabled={disabled} />
      </div>
    );
  }

  function OpRow({ op, onOpen }) {
    return (
      <div onClick={onOpen} style={{ display: "flex", alignItems: "center", gap: 10, padding: "11px 14px", borderBottom: "1px solid var(--line-divider)", cursor: "pointer" }}>
        <Avatar initials={op.init} tone={op.tone} size={30} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{op.label}</div>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: op.status === "failed" ? "var(--fin-negative)" : "var(--text-subtle)", marginTop: 2 }}>
            {op.date.slice(0, 5)} · {op.status === "failed" ? "Refusé" : op.status === "pending" ? "Pré-autorisé" : op.cat}
          </div>
        </div>
        <Amount cents={op.cents} size="sm" tone={op.status === "failed" ? "muted" : "default"} />
        <Ic.chevronRight size={15} style={{ color: "var(--text-subtle)", flex: "none" }} />
      </div>
    );
  }

  function CarteScreen({ go }) {
    const [statut, setStatut] = React.useState("active"); // active | locked | opposed
    const [prefs, setPrefs] = React.useState({ nfc: true, online: true, abroad: false });
    const [revealed, setRevealed] = React.useState(false);
    const [tab, setTab] = React.useState("all");
    const [limits, setLimits] = React.useState(window.OryzeCarte.limitsDefault);
    const [sheet, setSheet] = React.useState(null); // {type:'pin'|'pinchange'|'oppo'|'limits'|'op'|'new'|'delivery', op?}
    const [held, setHeld] = React.useState(false);
    const [oppoPhase, setOppoPhase] = React.useState("edit"); // edit | verify | done
    const [pay, setPay] = React.useState("3 000");
    const [cash, setCash] = React.useState("500");
    const [limErr, setLimErr] = React.useState(null);

    const opposed = statut === "opposed";
    const st = STATUT_CARTE[statut];
    const failed = OPERATIONS.filter((o) => o.status === "failed");
    const spentPay = -OPERATIONS.filter((o) => o.type === "paiement" && o.status === "executed").reduce((a, o) => a + o.cents, 0);
    const spentCash = -OPERATIONS.filter((o) => o.type === "retrait" && o.status === "executed").reduce((a, o) => a + o.cents, 0);
    const list = OPERATIONS.filter((o) =>
      tab === "all" ? true : tab === "failed" ? o.status === "failed" : o.type === tab && o.status !== "failed");

    const openLimits = () => {
      setPay((limits.pay / 100).toLocaleString("fr-FR"));
      setCash((limits.cash / 100).toLocaleString("fr-FR"));
      setLimErr(null);
      setSheet({ type: "limits" });
    };
    const parse = (s) => Math.round((parseFloat(String(s).replace(/[\s\u202F]/g, "").replace(",", ".")) || 0) * 100);
    const saveLimits = () => {
      const p = parse(pay), c = parse(cash);
      if (p < 10000 || p > 1000000) { setLimErr("Plafond paiements : entre 100 € et 10 000 €."); return; }
      if (c < 5000 || c > 200000) { setLimErr("Plafond retraits : entre 50 € et 2 000 €."); return; }
      setLimits({ pay: p, cash: c });
      setSheet(null);
    };

    const gauge = (title, spent, limit) => {
      const pct = Math.min(100, Math.round((spent / limit) * 100));
      return (
        <div style={{ display: "flex", alignItems: "center", gap: 12, flex: 1, minWidth: 0 }}>
          <ProgressRing value={pct} size={46} thickness={6.5} label={<span style={{ fontFamily: "var(--font-mono)", fontSize: 10, fontWeight: 700 }}>{pct}%</span>} />
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: 12.5, fontWeight: 600 }}>{title}</div>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, color: "var(--text-subtle)", marginTop: 2, whiteSpace: "nowrap" }}>
              {(spent / 100).toLocaleString("fr-FR")} € / {(limit / 100).toLocaleString("fr-FR")} €
            </div>
          </div>
        </div>
      );
    };

    return (
      <div style={{ padding: "14px 16px 26px", display: "flex", flexDirection: "column", gap: 14 }}>
        {/* En-tête écran */}
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <IconButton size="sm" variant="ghost" label="Retour" icon={<Ic.chevronLeft size={20} />} onClick={() => go && go("dashboard")} />
          <div style={{ fontWeight: 700, fontSize: 20, letterSpacing: "-0.02em", flex: 1 }}>Carte</div>
          <StatusBadge size="sm" status={st.status} label={st.label} />
        </div>

        {/* Visuel partagé — même objet que le web */}
        <CardVisual statut={statut} revealed={revealed && !opposed} style={{ maxWidth: "100%" }} />

        <div style={{ display: "flex", gap: 8 }}>
          <Button size="sm" variant="secondary" disabled={opposed} style={{ flex: 1 }}
            iconLeft={revealed ? <Ic.eyeOff size={15} /> : <Ic.eye size={15} />} onClick={() => setRevealed((r) => !r)}>
            {revealed ? "Masquer" : "Voir le numéro"}
          </Button>
          <Button size="sm" variant="ghost" disabled={opposed} style={{ flex: 1 }}
            iconLeft={<Ic.lock size={15} />} onClick={() => { setHeld(false); setSheet({ type: "pin" }); }}>Code PIN</Button>
        </div>
        <Button size="sm" variant="ghost" iconLeft={<Ic.plus size={15} />} onClick={() => setSheet({ type: "new" })}>Commander une nouvelle carte</Button>

        {statut === "locked" && (
          <div style={{ fontSize: 12, fontWeight: 600, color: "var(--oryze-butter-ink)", background: "var(--oryze-butter)", border: "var(--border-thin) solid var(--line-keyline)", borderRadius: "var(--radius-md)", padding: "8px 12px" }}>
            Carte verrouillée — tout paiement sera refusé jusqu'au déverrouillage.
          </div>
        )}
        {opposed && (
          <div style={{ fontSize: 12, fontWeight: 600, color: "var(--oryze-coral-ink)", background: "var(--oryze-coral)", border: "var(--border-thin) solid var(--line-keyline)", borderRadius: "var(--radius-md)", padding: "8px 12px" }}>
            Opposition enregistrée — carte définitivement désactivée. Remplacement en préparation.
          </div>
        )}

        {/* Réglages instantanés */}
        <Card variant="flat" padding="0">
          <SettingRow first icon={<Ic.lock size={15} />} label="Verrouiller la carte" sub="Blocage instantané, réversible"
            checked={statut === "locked"} disabled={opposed} onChange={(v) => setStatut(v ? "locked" : "active")} />
          <SettingRow icon={<Ic.contactless size={15} />} label="Sans contact" sub="Paiements NFC en magasin"
            checked={prefs.nfc} disabled={opposed} onChange={(v) => setPrefs((p) => ({ ...p, nfc: v }))} />
          <SettingRow icon={<Ic.bag size={15} />} label="Paiements en ligne" sub="E-commerce · 3-D Secure actif"
            checked={prefs.online} disabled={opposed} onChange={(v) => setPrefs((p) => ({ ...p, online: v }))} />
          <SettingRow icon={<Ic.globe size={15} />} label="Paiements à l'étranger" sub="Hors zone euro"
            checked={prefs.abroad} disabled={opposed} onChange={(v) => setPrefs((p) => ({ ...p, abroad: v }))} />
        </Card>

        {/* Plafonds */}
        <Card variant="flat" padding="14px">
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 12 }}>
            <div style={{ fontWeight: 700, fontSize: 14.5 }}>Plafonds</div>
            <Button size="sm" variant="ghost" onClick={openLimits}>Modifier</Button>
          </div>
          <div style={{ display: "flex", gap: 12 }}>
            {gauge("Paiements · 30 j", spentPay, limits.pay)}
            {gauge("Retraits · 7 j", spentCash, limits.cash)}
          </div>
        </Card>

        {/* Opérations */}
        <Card variant="flat" padding="0">
          <div style={{ padding: "12px 14px 8px", borderBottom: "1.5px solid var(--line-keyline)" }}>
            <div style={{ fontWeight: 700, fontSize: 14.5, marginBottom: 8 }}>Opérations</div>
            <Tabs className="hscroll" size="sm" value={tab} onChange={setTab} tabs={[
              { value: "all", label: "Toutes" },
              { value: "paiement", label: "Paiements" },
              { value: "retrait", label: "Retraits" },
              { value: "failed", label: "Refusées", count: failed.length }]} />
          </div>
          {list.map((op) => <OpRow key={op.id} op={op} onOpen={() => setSheet({ type: "op", op })} />)}
          {list.length === 0 && <div style={{ padding: "28px", textAlign: "center", color: "var(--text-muted)", fontSize: 13 }}>Aucune opération dans cet état.</div>}
        </Card>

        {/* Sécurité */}
        <Card variant="flat" padding="0">
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "12px 14px", borderBottom: "1px solid var(--line-divider)" }}>
            <div>
              <div style={{ fontSize: 13.5, fontWeight: 600 }}>3-D Secure</div>
              <div style={{ fontSize: 11, color: "var(--text-subtle)", marginTop: 1 }}>Confirmation forte e-commerce</div>
            </div>
            <Tag tone="paid" dot>Actif</Tag>
          </div>
          <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "12px 14px" }}>
            <div>
              <div style={{ fontSize: 13.5, fontWeight: 600 }}>Perte ou vol</div>
              <div style={{ fontSize: 11, color: "var(--text-subtle)", marginTop: 1 }}>Opposition immédiate et définitive</div>
            </div>
            {opposed
              ? <StatusBadge size="sm" status="rejected" label="Opposée" />
              : <Button size="sm" variant="secondary" iconLeft={<Ic.shield size={14} />} onClick={() => { setOppoPhase("edit"); setSheet({ type: "oppo" }); }}>Faire opposition</Button>}
          </div>
        </Card>

        {opposed && (
          <Card variant="flat" padding="14px">
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10 }}>
              <div style={{ fontWeight: 700, fontSize: 14.5 }}>Carte de remplacement</div>
              <StatusBadge size="sm" status="pending" label="En préparation" />
            </div>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--text-subtle)", marginTop: 5 }}>{CARTE.replacement} · expédition sous 5 j ouvrés</div>
            <div style={{ fontSize: 12.5, color: "var(--text-body)", marginTop: 7, lineHeight: 1.5 }}>Plafonds et réglages repris à l'activation. Rien à faire de votre côté.</div>
            <Button size="sm" variant="secondary" iconLeft={<Ic.send size={14} />} style={{ marginTop: 10 }} onClick={() => setSheet({ type: "delivery" })}>Suivi de livraison</Button>
          </Card>
        )}

        {/* ---- Bottom sheets ---- */}
        <BottomSheet absolute open={!!(sheet && sheet.type === "pin")} onClose={() => setSheet(null)} title="Code PIN" subtitle="Carte •••• 4827">
          <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 14, padding: "6px 0 10px", textAlign: "center" }}>
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 30, fontWeight: 600, letterSpacing: "0.35em", padding: "12px 20px 12px calc(20px + 0.35em)", background: "var(--surface-sunken)", border: "var(--border-thin) solid var(--line-keyline)", borderRadius: "var(--radius-md)" }}>
              {held ? "4921" : "••••"}
            </div>
            <div style={{ display: "flex", flexWrap: "wrap", justifyContent: "center", gap: 8, maxWidth: "100%" }}>
              <Button size="sm" variant="secondary"
                onPointerDown={() => setHeld(true)} onPointerUp={() => setHeld(false)} onPointerLeave={() => setHeld(false)}
                iconLeft={<Ic.eye size={15} />}>Maintenir pour afficher</Button>
              <Button size="sm" variant="ghost" onClick={() => setSheet({ type: "pinchange" })}>Changer le PIN</Button>
            </div>
            <div style={{ fontSize: 11.5, color: "var(--text-subtle)", lineHeight: 1.5, maxWidth: 250 }}>
              Ne le communiquez jamais. On ne vous le demandera jamais — ni par téléphone, ni par e-mail.
            </div>
          </div>
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "oppo")} onClose={() => setSheet(null)} title="Perte ou vol"
          subtitle={oppoPhase === "done" ? "Mode démo — carte fictive" : oppoPhase === "verify" ? "Vérification — étape 2/2" : "Opposition immédiate et définitive"}>
          {oppoPhase === "done" ? (
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12, padding: "8px 0 10px", textAlign: "center" }}>
              <StatusBadge status="rejected" label="Opposée" />
              <div style={{ fontWeight: 700, fontSize: 17, letterSpacing: "-0.02em" }}>Carte opposée</div>
              <div style={{ fontSize: 13, color: "var(--text-body)", lineHeight: 1.55 }}>
                Une carte de remplacement <span style={{ fontFamily: "var(--font-mono)" }}>{CARTE.replacement}</span> arrive sous 5 j ouvrés — plafonds et réglages repris à l'activation.
              </div>
              <Button size="sm" variant="secondary" onClick={() => setSheet(null)}>Fermer</Button>
            </div>
          ) : oppoPhase === "verify" ? (
            <div style={{ paddingBottom: 6 }}>
              <ClosureVerify onCancel={() => setSheet(null)} onVerified={() => { setStatut("opposed"); setRevealed(false); setOppoPhase("done"); }} />
            </div>
          ) : (
            <div style={{ display: "flex", flexDirection: "column", gap: 12, paddingBottom: 6 }}>
              <div style={{ fontSize: 13, color: "var(--text-body)", lineHeight: 1.55 }}>
                L'opposition désactive définitivement la carte <span style={{ fontFamily: "var(--font-mono)" }}>•••• 4827</span>. Une carte de remplacement est expédiée automatiquement.
              </div>
              <div style={{ fontSize: 12, fontWeight: 600, color: "var(--oryze-butter-ink)", background: "var(--oryze-butter)", border: "var(--border-thin) solid var(--line-keyline)", borderRadius: "var(--radius-md)", padding: "9px 12px", lineHeight: 1.5 }}>
                Simple doute ? Verrouillez plutôt la carte — c'est réversible à tout moment.
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                <Button variant="ghost" size="md" style={{ flex: 1 }} onClick={() => setSheet(null)}>Annuler</Button>
                <Button size="md" style={{ flex: 1 }} iconLeft={<Ic.shield size={15} />}
                  onClick={() => setOppoPhase("verify")}>Faire opposition</Button>
              </div>
            </div>
          )}
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "limits")} onClose={() => setSheet(null)} title="Modifier les plafonds" subtitle="Prise en compte immédiate — mode démo">
          <div style={{ display: "flex", flexDirection: "column", gap: 12, paddingBottom: 6 }}>
            <Input label="Paiements · 30 jours glissants" value={pay} onChange={(e) => setPay(e.target.value)} mono suffix="€" />
            <Input label="Retraits · 7 jours glissants" value={cash} onChange={(e) => setCash(e.target.value)} mono suffix="€" />
            {limErr && <div style={{ fontSize: 12.5, color: "var(--fin-negative)", fontWeight: 600 }}>{limErr}</div>}
            <div style={{ display: "flex", gap: 8 }}>
              <Button variant="ghost" size="md" style={{ flex: 1 }} onClick={() => setSheet(null)}>Annuler</Button>
              <Button size="md" style={{ flex: 1 }} iconLeft={<Ic.check size={15} />} onClick={saveLimits}>Enregistrer</Button>
            </div>
          </div>
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "op")} onClose={() => setSheet(null)}
          title={sheet && sheet.op ? sheet.op.label : ""} subtitle={sheet && sheet.op ? "Carte •••• 4827 · " + sheet.op.date : ""}>
          {sheet && sheet.op && (
            <div style={{ display: "flex", flexDirection: "column", gap: 13, paddingBottom: 6 }}>
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12 }}>
                <Amount cents={sheet.op.cents} size="xl" tone={sheet.op.status === "failed" ? "muted" : "default"} />
                <StatusBadge status={sheet.op.status} label={sheet.op.status === "failed" ? "Refusé" : sheet.op.status === "pending" ? "Pré-autorisé" : "Réglé"} />
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 7, padding: "12px 13px", background: "var(--surface-sunken)", border: "var(--border-hair) solid var(--line-divider)", borderRadius: "var(--radius-md)" }}>
                {[["Type", sheet.op.type === "retrait" ? "Retrait" : "Paiement carte"], ["Catégorie", sheet.op.cat], ["Mode", sheet.op.type === "retrait" ? "Distributeur" : "Sans contact"]].concat(sheet.op.note ? [[sheet.op.status === "failed" ? "Motif du refus" : "Note", sheet.op.note]] : []).map(([k, v]) => (
                  <div key={k} style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 12 }}>
                    <span style={{ fontSize: 12.5, color: "var(--text-muted)", whiteSpace: "nowrap" }}>{k}</span>
                    <span style={{ fontSize: 12.5, fontWeight: 600, textAlign: "right", minWidth: 0 }}>{v}</span>
                  </div>
                ))}
              </div>
              {sheet.op.status === "pending" && (
                <div style={{ fontSize: 11.5, color: "var(--text-subtle)", lineHeight: 1.5 }}>Montant réservé par le commerçant — débité à la facturation, sous 7 jours en général.</div>
              )}
            </div>
          )}
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "new")} onClose={() => setSheet(null)} title="Nouvelle carte" subtitle="Carte physique — mode démo, aucune commande réelle">
          {sheet && sheet.type === "new" && <div style={{ paddingBottom: 6 }}><NewCardFlow onCancel={() => setSheet(null)} onDone={() => setSheet(null)} /></div>}
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "pinchange")} onClose={() => setSheet(null)} title="Changer le PIN" subtitle="Carte •••• 4827">
          {sheet && sheet.type === "pinchange" && <div style={{ paddingBottom: 6 }}><PinChangeFlow onClose={() => setSheet(null)} /></div>}
        </BottomSheet>

        <BottomSheet absolute open={!!(sheet && sheet.type === "delivery")} onClose={() => setSheet(null)} title="Suivi de livraison" subtitle="Mode démo — expédition fictive">
          {sheet && sheet.type === "delivery" && <div style={{ paddingBottom: 6 }}><DeliveryInfoPanel /></div>}
        </BottomSheet>
      </div>
    );
  }

  window.OryzeApp = window.OryzeApp || {};
  window.OryzeApp.CarteScreen = CarteScreen;
})();
