// ============================================================
// Monarch — Simulateurs : Plus-value immobilière (IS) · Cession de titres (holding)
// Requiert window.MSC (simcore.jsx) et window.__mscShared (simulators2.jsx).
// ============================================================

(function () {
  const { useState, useEffect } = React;
  const M = window.MSC;
  const { C, SERIF, BODY, fmt, pct, CountEuro, injectCore, useReveal,
    Eyebrow, Label, MoneyInput, Shell, InputsCard, Doctrine, Alert, CTAEmail, ProsCons } = M;
  function shared() { return window.__mscShared; }

  // abattement plus-value des particuliers (IR + PS) selon durée
  function abattementIR(d) {
    if (d <= 5) return 0;
    if (d >= 22) return 1;
    return Math.min(1, (Math.min(d, 21) - 5) * 0.06 + (d >= 22 ? 0.04 : 0));
  }
  function abattementPS(d) {
    if (d <= 5) return 0;
    if (d >= 30) return 1;
    let a = 0;
    a += Math.max(0, Math.min(d, 21) - 5) * 0.0165;
    if (d >= 22) a += 0.016;
    if (d > 22) a += Math.min(d, 30) - 22 ? (Math.min(d, 30) - 22) * 0.09 : 0;
    return Math.min(1, a);
  }

  // =====================================================
  // 9. PLUS-VALUE IMMOBILIÈRE — le piège de l'amortissement
  // =====================================================
  function RealEstateCapitalGainSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap } = shared();
    const [achat, setAchat] = useState(500000);
    const [revente, setRevente] = useState(800000);
    const [duree, setDuree] = useState(15);
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const P = Math.max(0, Number(achat) || 0);
    const R = Math.max(0, Number(revente) || 0);
    const D = Math.max(1, Math.min(40, Number(duree) || 1));
    const pvBrute = Math.max(0, R - P);
    // Particulier / SCI IR
    const baseIR = pvBrute * (1 - abattementIR(D));
    const basePS = pvBrute * (1 - abattementPS(D));
    const impotParticulier = baseIR * 0.19 + basePS * 0.172;
    // IS : amortissement ~3 %/an plafonné à 100 %
    const tauxAmort = Math.min(1, 0.03 * D);
    const vnc = P * (1 - tauxAmort);
    const baseIS = Math.max(0, R - vnc);
    const impotIS = (baseIS <= 42500 ? baseIS * 0.15 : 42500 * 0.15 + (baseIS - 42500) * 0.25);

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };
    const maxBase = Math.max(baseIR, basePS, baseIS, 1);

    return (
      <Shell eyebrow="Protection d'actifs · Plus-value immobilière"
        title="L'IS capitalise admirablement l'immobilier — et le piège à la revente."
        intro="Comparez la plus-value d'un particulier (abattement par durée) au mur fiscal d'une société à l'IS qui a amorti le bien.">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Calculer la plus-value">
            <div><Label>Prix d'acquisition</Label><MoneyInput value={achat} onChange={setAchat} min={50000} max={10000000} step={10000} /></div>
            <div><Label>Prix de revente estimé</Label><MoneyInput value={revente} onChange={setRevente} min={50000} max={20000000} step={10000} /></div>
            <div style={{ gridColumn: "1 / -1" }}>
              <Label>Durée de détention</Label>
              <div style={{ fontFamily: SERIF, fontSize: 30, fontWeight: 500, color: C.encre }}>{D} ans</div>
              <input type="range" min="1" max="35" step="1" value={D} onChange={(e) => setDuree(Number(e.target.value))} style={{ width: "100%", marginTop: 8, accentColor: C.sauge }} />
            </div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Acquisition", fmt(P)], ["Revente", fmt(R)], ["Détention", D + " ans"], ["PV brute", fmt(pvBrute)]]} onEdit={() => setDone(false)} />

            <div style={{ marginTop: 16, border: `1px solid ${C.trait}`, background: C.blanc, padding: "clamp(22px,3vw,32px)" }}>
              <Eyebrow>Deux impôts qui évoluent en sens inverse</Eyebrow>
              <h3 style={{ fontFamily: SERIF, fontSize: "clamp(20px,2.4vw,28px)", fontWeight: 500, letterSpacing: "-0.01em", margin: "10px 0 22px" }}>Deux assiettes en sens inverse</h3>

              <div style={{ marginBottom: 26 }}>
                <ViseRow label="Sphère privée (particulier / SCI à l'IR)" sub={`Assiette érodée par l'abattement (détention ${D} ans)`} taxLabel="Imposition personnelle" tax={impotParticulier} base={baseIR} max={maxBase} run={reveal} color={C.ardoiseF} />
              </div>
              <ViseRow label="Sphère IS (SCI à l'IS / société commerciale)" sub="Assiette gonflée par la réintégration des amortissements (VNC)" taxLabel="Le piège de la VNC — imposition IS" tax={impotIS} base={baseIS} max={maxBase} run={reveal} color={C.encre} danger />
              <p style={{ fontFamily: BODY, fontSize: 12.5, color: C.grisC, lineHeight: 1.6, margin: "18px 0 0" }}>VNC ≈ {fmt(vnc)} (amortissement {Math.round(tauxAmort * 100)} %). Base IS = revente − VNC = {fmt(baseIS)}. Calcul indicatif (taux réduit 19 % sur l'immobilier non retenu).</p>
            </div>

            <Doctrine open={reveal} eyebrow="À retenir" title="L'IS fait grossir le capital, mais coûte cher à la revente" accent={C.sauge}>
              <p style={{ margin: 0 }}>L'IS est un formidable outil de capitalisation immobilière, mais un désastre à la revente. La majorité des SCI à l'IS sont créées sans stratégie de sortie. L'ingénierie du cabinet anticipe cette friction dès l'acquisition (OBO immobilier, dissociation des flux, calendrier de cession) pour éviter l'impasse fiscale lors de la liquidation de l'actif.</p>
            </Doctrine>

            <ProsCons open={reveal}
              pour={["À l'IS, l'amortissement réduit fortement l'impôt pendant la détention.", "Le capital grossit plus vite dans la société.", "Cadre idéal pour accumuler et réinvestir sur le long terme."]}
              contre={["À la revente, l'impôt est nettement plus lourd (amortissements repris).", "Sans stratégie de sortie prévue, la facture finale peut surprendre.", "Comptabilité et formalisme d'une société à l'IS."]} />

            <CTAEmail />
          </div>}
      </Shell>);
  }

  function ViseRow({ label, sub, taxLabel, tax, base, max, run, color, danger }) {
    const [w, setW] = useState(false);
    useEffect(() => { if (run) { const id = setTimeout(() => setW(true), 80); return () => clearTimeout(id); } else setW(false); }, [run]);
    return (
      <div>
        <div style={{ fontFamily: BODY, fontSize: 12.5, letterSpacing: "0.1em", textTransform: "uppercase", color: danger ? C.encre : C.ardoise, fontWeight: 600, marginBottom: 8 }}>{label}</div>
        <div style={{ position: "relative", height: 22, background: C.albatre, border: `1px solid ${C.trait}`, overflow: "hidden" }}>
          <div style={{ height: "100%", width: w ? pct(base, max) + "%" : 0, transition: "width 1.2s cubic-bezier(.2,.7,.3,1)", backgroundColor: danger ? "rgba(27,29,28,.10)" : "rgba(91,124,153,.10)", backgroundImage: `repeating-linear-gradient(135deg, ${danger ? "rgba(27,29,28,.5)" : "rgba(91,124,153,.45)"} 0, ${danger ? "rgba(27,29,28,.5)" : "rgba(91,124,153,.45)"} 1.5px, transparent 1.5px, transparent 6px)` }} />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginTop: 10, flexWrap: "wrap", gap: 8 }}>
          <span style={{ fontFamily: BODY, fontSize: 13, color: C.gris }}>{sub} · base {fmt(base)}</span>
          <span style={{ display: "inline-flex", alignItems: "baseline", gap: 8 }}>
            <span style={{ fontFamily: BODY, fontSize: 12.5, color: C.gris }}>{taxLabel}</span>
            <CountEuro value={tax} run={run} style={{ fontFamily: SERIF, fontSize: "clamp(22px,2.8vw,32px)", fontWeight: 500, color: color, letterSpacing: "-0.01em" }} />
          </span>
        </div>
      </div>);
  }

  // =====================================================
  // 10. CESSION DE TITRES — puissance de la holding
  // =====================================================
  function SecuritiesCapitalGainSimulator() {
    useEffect(injectCore, []);
    const { ParamRecap } = shared();
    const [acq, setAcq] = useState(10000);
    const [cession, setCession] = useState(3000000);
    const [done, setDone] = useState(false);
    const [busy, setBusy] = useState(false);
    const reveal = useReveal(done, 250);

    const A = Math.max(0, Number(acq) || 0);
    const V = Math.max(0, Number(cession) || 0);
    const pv = Math.max(0, V - A);
    const flat = pv * 0.314;
    const resteDirect = V - flat;
    const qpfc = pv * 0.12 * 0.25; // 12 % réintégrés, taxés IS 25 % ≈ 3 %
    const resteHolding = V - qpfc;
    const tauxEff = pv > 0 ? (qpfc / pv) * 100 : 0;

    const go = () => { setBusy(true); setDone(false); setTimeout(() => { setBusy(false); setDone(true); }, 700); };

    return (
      <Shell eyebrow="Cession de titres · Régime des titres de participation"
        title="Vendre une filiale détenue par votre holding : ~3 % de friction."
        intro="Comparez une cession en nom propre soumise à la Flat Tax à une cession par holding (titres de participation, +2 ans).">
        {!done &&
          <InputsCard onCompute={go} computing={busy} label="Comparer les cessions">
            <div><Label>Prix d'acquisition / capital initial</Label><MoneyInput value={acq} onChange={setAcq} min={0} max={5000000} step={5000} /></div>
            <div><Label>Valorisation de cession</Label><MoneyInput value={cession} onChange={setCession} min={50000} max={50000000} step={100000} /></div>
          </InputsCard>}

        {done &&
          <div style={{ marginTop: 36 }}>
            <ParamRecap items={[["Acquisition", fmt(A)], ["Cession", fmt(V)], ["Plus-value", fmt(pv)]]} onEdit={() => setDone(false)} />

            <div className="msc-grid2" style={{ marginTop: 16 }}>
              <Reservoir tone="leak" title="Cession en nom propre" eyebrow="Flat Tax 31,4 %"
                reste={resteDirect} perte={flat} base={V} reveal={reveal}
                lossLabel="Déperdition fiscale immédiate" resteLabel="Reste pour réinvestir" />
              <Reservoir tone="sealed" title="Cession par la holding" eyebrow="La doctrine — titres de participation"
                reste={resteHolding} perte={qpfc} base={V} reveal={reveal}
                lossLabel={`Frottement (QPFC) — taux effectif ${tauxEff.toFixed(1).replace(".", ",")} %`} resteLabel="Conservé dans la holding pour réinvestir" good />
            </div>

            <Doctrine open={reveal} eyebrow="À retenir" title="Environ 3 % d'impôt, et l'argent réinvesti librement" accent={C.sauge}>
              <p style={{ margin: 0 }}>Beaucoup confondent ce mécanisme avec l'apport-cession (150-0 B ter), qui contraint vos réinvestissements pendant 24 mois. Vendre une filiale que votre holding détient depuis plus de deux ans vous offre une <b style={{ color: "#fff" }}>liberté totale d'allocation du capital</b>, avec un taux effectif d'environ 3 %. L'organisation précoce de votre groupe sanctuarise le fruit de votre travail futur.</p>
            </Doctrine>

            <ProsCons open={reveal}
              pour={["Impôt limité à environ 3 % quand la holding détient les titres depuis 2 ans.", "Liberté totale pour réinvestir l'argent, sans contrainte de délai.", "Le capital reste mobilisable dans le groupe."]}
              contre={["Il faut avoir logé les titres dans la holding au moins 2 ans avant la vente.", "L'argent reste dans la société : le sortir personnellement sera taxé.", "Nécessite d'avoir structuré son groupe en amont."]} />

            <CTAEmail />
          </div>}
      </Shell>);
  }

  function Reservoir({ tone, title, eyebrow, reste, perte, base, reveal, lossLabel, resteLabel, good }) {
    const leak = tone === "leak";
    const fillH = pct(reste, base); // % conservé
    return (
      <div style={{ border: leak ? `1px solid ${C.trait}` : `1px solid ${C.saugeF}`, background: leak ? C.blanc : C.encre, color: leak ? C.encre : "#fff", padding: "clamp(22px,3vw,32px)", display: "flex", flexDirection: "column" }}>
        <Eyebrow color={leak ? C.ardoise : C.sauge}>{eyebrow}</Eyebrow>
        <h3 style={{ fontFamily: SERIF, fontSize: 22, fontWeight: 500, margin: "10px 0 18px", letterSpacing: "-0.01em", color: leak ? C.encre : "#fff" }}>{title}</h3>
        <div style={{ display: "flex", gap: 20, alignItems: "flex-end" }}>
          <svg viewBox="0 0 90 130" width="90" height="130" style={{ flex: "0 0 auto" }} aria-hidden="true">
            <rect x="14" y="10" width="62" height="108" fill="none" stroke={leak ? C.encre : "#fff"} strokeWidth={leak ? 1.4 : 2.4} />
            <rect x="16" y={12 + (104 * (100 - fillH) / 100)} width="58" height={104 * fillH / 100} fill={leak ? "rgba(91,124,153,.18)" : "rgba(92,111,92,.5)"} />
            {leak ?
              <g>
                <line className={"msc-line" + (reveal ? " on" : "")} style={{ strokeDasharray: 40, strokeDashoffset: reveal ? 0 : 40, transitionDelay: ".4s" }} x1="45" y1="118" x2="45" y2="130" stroke={C.ardoise} strokeWidth="1.4" />
                <circle className={"msc-soft" + (reveal ? " on" : "")} style={{ transitionDelay: "1s" }} cx="45" cy="128" r="2" fill={C.ardoise} />
              </g>
              :
              <line className={"msc-line" + (reveal ? " on" : "")} style={{ strokeDasharray: 60, strokeDashoffset: reveal ? 0 : 60, transitionDelay: ".4s" }} x1="14" y1="118" x2="76" y2="118" stroke={C.sauge} strokeWidth="2.4" />}
          </svg>
          <div>
            <div style={{ fontFamily: BODY, fontSize: 12.5, color: leak ? C.gris : "#9ea7a0", marginBottom: 4 }}>{resteLabel}</div>
            <CountEuro value={reste} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(24px,3.2vw,38px)", fontWeight: 500, color: leak ? C.encre : "#fff", letterSpacing: "-0.01em", lineHeight: 1 }} />
            <div style={{ fontFamily: BODY, fontSize: 13, color: good ? C.sauge : "#a23b3b", fontWeight: 600, marginTop: 12 }}>{lossLabel}</div>
            <CountEuro value={perte} run={reveal} style={{ fontFamily: SERIF, fontSize: "clamp(18px,2.2vw,24px)", fontWeight: 500, color: leak ? "#a23b3b" : C.sauge, letterSpacing: "-0.01em" }} />
          </div>
        </div>
      </div>);
  }

  window.RealEstateCapitalGainSimulator = RealEstateCapitalGainSimulator;
  window.SecuritiesCapitalGainSimulator = SecuritiesCapitalGainSimulator;
})();
