/* Winst-overzicht: totaal, per platform, per product. Exported to window. */

function dedupeChannels(p, db) {
  const raw = (p.channels && p.channels.length) ? p.channels : db.PLATFORMS.map(pf => ({ name: pf.name, price: p.prices[pf.id] }));
  const byName = {};
  for (const c of raw) {
    if (c.price == null) { if (!byName[c.name]) byName[c.name] = { name: c.name, price: null, stock: 0 }; continue; }
    const stock = c.stock != null ? c.stock : 0;
    const cur = byName[c.name];
    if (!cur || cur.price == null || stock > (cur.stock || 0) || (stock === (cur.stock || 0) && c.price > cur.price)) {
      byName[c.name] = { name: c.name, price: c.price, stock };
    }
  }
  return byName;
}

function Winst({ db, onNav }) {
  const pt = db.profitTax();
  const [costOpen, setCostOpen] = React.useState(false);
  const period = db.period();
  const perLabel = (db.PERIODS.find(x => x.id === period) || {}).label || "30 dagen";
  const info = (p) => db.periodOf(p, period) || { q: 0, rev: 0, ch: {} };
  const available = !db.products.some(p => db.periodOf(p, period) == null) && (period !== "yesterday" || db.products.some(p => p.periods && p.periods.yesterday));
  const withCost = db.products.filter(p => db.effCost(p) != null && info(p).q > 0);
  const zonderCost = db.products.filter(p => db.effCost(p) == null && info(p).q > 0);

  // totalen (echte orderbedragen) + winst over producten met inkoopprijs
  const omzetTotal = db.products.reduce((s, p) => s + info(p).rev, 0);
  let winstProduct = 0;
  withCost.forEach(p => { const w = db.winstInfo(p, info(p)); if (w) winstProduct += w.voor; });
  // Maxeda vaste maandbijdrage (€38/mnd), geschaald naar de gekozen periode
  const PERIOD_DAYS = { today: 1, yesterday: 1, d7: 7, d30: 30, d90: 90, d180: 180, d365: 365 };
  const periodDays = PERIOD_DAYS[period] || 30;
  const maxedaMonthly = window.STORE.maxedaMonthly ? window.STORE.maxedaMonthly() : 0;
  const maxedaFee = maxedaMonthly * (periodDays / 30.44);
  // advertentiekosten (bol Ads) — aftrekbaar VÓÓR de winstbelasting
  const adCost = (available && db.adsHasData && db.adsHasData()) ? (db.adsTotal(period) || 0) : 0;
  const gadCost = (available && db.gadsHasData && db.gadsHasData()) ? (db.gadsTotal(period) || 0) : 0;
  // terugbetaalde retouren — ook vóór belasting verrekend
  const retImpact = (available && db.returnsImpact) ? db.returnsImpact(period) : { cost: 0, count: 0, qty: 0 };
  const retCost = retImpact.cost || 0;
  const fulfilPer = (window.STORE && window.STORE.fulfilmentPerOrder) ? window.STORE.fulfilmentPerOrder() : 0;
  const amperePer = (window.STORE && window.STORE.amperePerDay) ? window.STORE.amperePerDay() : 0;
  // Ampere haalt alleen op ma t/m vr — tel de werkdagen in de gekozen periode
  const countWeekdays = (n) => { let c = 0; const t = new Date(); for (let i = 0; i < n; i++) { const d = new Date(t.getFullYear(), t.getMonth(), t.getDate() - i); const wd = d.getDay(); if (wd >= 1 && wd <= 5) c++; } return c; };
  const isWeekday = (back) => { const t = new Date(); const d = new Date(t.getFullYear(), t.getMonth(), t.getDate() - back); const wd = d.getDay(); return wd >= 1 && wd <= 5; };
  let ampereDays;
  if (period === "today") ampereDays = isWeekday(0) ? 1 : 0;
  else if (period === "yesterday") ampereDays = isWeekday(1) ? 1 : 0;
  else ampereDays = countWeekdays(periodDays);
  const ampereCost = +(amperePer * ampereDays).toFixed(2);
  const realOrders = available && db.ordersIn ? db.ordersIn(period) : null;
  const orderEst = realOrders ? realOrders.o : (available ? db.products.reduce((s, p) => { const q = (db.periodOf(p, period) || {}).q || 0; return s + Math.ceil(q / Math.max(1, +p.perPackage || 1)); }, 0) : 0);
  const fulfilCost = +(fulfilPer * orderEst).toFixed(2);
  const winstVoor = winstProduct - maxedaFee - adCost - gadCost - retCost - fulfilCost - ampereCost;
  const winstNa = winstVoor > 0 ? winstVoor * (1 - pt / 100) : winstVoor;

  // Dagdoel: €200 winst na belasting VANDAAG (altijd op vandaag gebaseerd, los van de gekozen periode)
  const DAY_GOAL = 200;
  const showGoal = period === "today" || period === "yesterday";
  const isYesterday = period === "yesterday";
  let dayVoorProd = 0;
  if (showGoal) db.products.forEach(p => { if (db.effCost(p) == null) return; const di = db.periodOf(p, period); if (!di || !(di.q > 0)) return; const w = db.winstInfo(p, di); if (w) dayVoorProd += w.voor; });
  const dayAdCost = (showGoal && db.adsHasData && db.adsHasData()) ? (db.adsTotal(period) || 0) : 0;
  const dayGad = (showGoal && db.gadsHasData && db.gadsHasData()) ? (db.gadsTotal(period) || 0) : 0;
  const dayRet = (showGoal && db.returnsImpact) ? (db.returnsImpact(period).cost || 0) : 0;
  const dayOrders = showGoal ? (realOrders ? realOrders.o : db.products.reduce((s, p) => { const q = (db.periodOf(p, period) || {}).q || 0; return s + Math.ceil(q / Math.max(1, +p.perPackage || 1)); }, 0)) : 0;
  const dayVoor = dayVoorProd - maxedaMonthly * (1 / 30.44) - dayAdCost - dayGad - dayRet - (fulfilPer * dayOrders) - (ampereDays > 0 ? amperePer : 0);
  const dayNa = dayVoor > 0 ? dayVoor * (1 - pt / 100) : dayVoor;
  const goalValue = Math.max(0, dayNa);
  const goalPct = Math.max(0, Math.min(1, goalValue / DAY_GOAL));
  const goalDone = showGoal && goalValue >= DAY_GOAL;
  const goalHue = Math.round(8 + (148 - 8) * goalPct); // rood → groen naarmate de balk vult
  const goalColor = goalDone ? "#10c267" : `hsl(${goalHue} 70% 45%)`;
  const goalRef = React.useRef();
  const gkD = new Date(Date.now() - (isYesterday ? 86400000 : 0)); const goalKey = "goal:" + period + ":" + gkD.getFullYear() + "-" + String(gkD.getMonth() + 1).padStart(2, "0") + "-" + String(gkD.getDate()).padStart(2, "0");
  React.useEffect(() => { if (goalDone && goalRef.current) window.celebrate(goalRef.current, goalKey); }, [goalDone, goalKey]);

  // kostenopbouw (optelsom over producten met inkoopprijs)
  const cost = { netto: 0, btw: 0, inkoop: 0, verzending: 0, platform: 0 };
  withCost.forEach(p => {
    const b = db.costParts(p, info(p));
    if (!b) return;
    cost.netto += b.netto; cost.btw += b.btw; cost.inkoop += b.inkoop;
    cost.verzending += b.verzending; cost.platform += b.platform;
  });
  const omzetWithCost = cost.netto + cost.btw;
  const costRows = [
    { label: "Inkoop (inkoopprijs × aantal)", val: cost.inkoop, icon: "tag" },
    { label: "Verzendkosten", val: cost.verzending, icon: "truck" },
    { label: "Platform-kosten (bol + Maxeda)", val: cost.platform, icon: "plug" },
    { label: "Maxeda maandbijdrage", val: maxedaFee, icon: "euro" },
  ];
  if (adCost > 0) costRows.push({ label: "Advertentiekosten (bol Ads)", val: adCost, icon: "trending" });
  if (gadCost > 0) costRows.push({ label: "Advertentiekosten (Google Ads)", val: gadCost, icon: "search2" });
  if (retCost > 0) costRows.push({ label: "Retouren (terugbetaald, " + retImpact.count + "×)", val: retCost, icon: "truck" });
  if (fulfilCost > 0) costRows.push({ label: "Fulfilment (" + orderEst + " bestellingen" + (realOrders && realOrders.est ? ", deels geschat" : "") + " × " + fmtEur(fulfilPer) + ")", val: fulfilCost, icon: "boxes" });
  if (ampereCost > 0) costRows.push({ label: "Ophaalservice Ampere (" + ampereDays + (ampereDays === 1 ? " werkdag" : " werkdagen") + " × " + fmtEur(amperePer) + ")", val: ampereCost, icon: "truck" });
  const kostenTotaal = cost.inkoop + cost.verzending + cost.platform + maxedaFee + adCost + gadCost + retCost + fulfilCost + ampereCost;

  // per platform (benadering: verkochte aantallen × huidige kanaalprijs)
  const plat = {};
  withCost.forEach(p => {
    const chans = dedupeChannels(p, db);
    const byCh = info(p).ch || {};
    Object.keys(byCh).forEach(name => {
      const units = byCh[name];
      if (!units) return;
      const price = (chans[name] && chans[name].price) || p.prices.web || 0;
      const unitWinst = db.winstPer(p, price, name);
      const e = plat[name] = plat[name] || { name, units: 0, omzet: 0, winst: 0 };
      e.units += units;
      e.omzet += price * units;
      if (unitWinst != null) e.winst += unitWinst * units;
    });
  });
  const platforms = Object.values(plat).sort((a, b) => b.winst - a.winst);
  const maxWinst = Math.max(1, ...platforms.map(p => Math.abs(p.winst)));

  return (
    <div className="view">
      <div className="page-head">
        <div className="ph-row">
          <div>
            <h1>Winst</h1>
            <div className="ph-sub">Omzet, kosten en winst · {perLabel.toLowerCase()}. BTW {db.vat()}%{pt > 0 ? ` · winstbelasting ${pt}%` : ""}.</div>
          </div>
          <div className="seg" style={{ flexWrap: "wrap" }}>
            {db.PERIODS.map(per => (
              <button key={per.id} className={period === per.id ? "on" : ""} onClick={() => window.STORE.setPeriod(per.id)}>{per.label}</button>
            ))}
          </div>
        </div>
      </div>

      {showGoal && (
      <div ref={goalRef} className={"goalbar" + (goalDone ? " goalbar-done" : "")}>
        <div className="goalbar-top">
          <div>
            <div className="goalbar-title">{goalDone ? "🎉 Dagdoel gehaald — feest!" : (isYesterday ? "Dagdoel gisteren · winst na belasting" : "Dagdoel · winst na belasting")}</div>
            <div className="goalbar-sub">{goalDone
              ? (isYesterday
                  ? "Top team! Gisteren " + fmtEur(Math.round(goalValue)) + " winst na belasting gehaald."
                  : "Top team! Vandaag al " + fmtEur(Math.round(goalValue)) + " winst na belasting binnen.")
              : (isYesterday
                  ? "Het dagdoel voor gisteren was " + fmtEur(DAY_GOAL) + " winst na belasting."
                  : "Samen elke dag op naar " + fmtEur(DAY_GOAL) + " winst na belasting.")}</div>
          </div>
          <div className="goalbar-amount" style={{ color: goalDone ? "#0a8f48" : "var(--text)" }}>
            {fmtEur(Math.round(goalValue))}<span className="goalbar-goal"> / {fmtEur(DAY_GOAL)}</span>
          </div>
        </div>
        <div className="goalbar-track">
          <div className="goalbar-fill" style={{ width: (goalPct * 100) + "%", background: goalColor }}></div>
        </div>
        <div className="goalbar-foot">
          <span>{goalDone ? "Doel bereikt 💪" : (goalValue > 0 ? fmtEur(Math.round(DAY_GOAL - goalValue)) + (isYesterday ? " onder doel" : " te gaan") : (isYesterday ? "Geen winst geregistreerd" : "Nog te starten vandaag"))}</span>
          <span>{Math.round(goalPct * 100)}%</span>
        </div>
      </div>
      )}

      {!available && (
        <div className="att-item" style={{ marginBottom: "var(--space)", borderColor: "var(--warn-line)", background: "var(--warn-soft)" }}>
          <span className="att-ico" style={{ background: "#fff", color: "var(--warn)" }}><Icon name="info" size={18} /></span>
          <div className="att-body">
            <div className="att-title">Deze periode is nog niet beschikbaar</div>
            <div className="att-desc">Werk de datakraan bij naar de nieuwste versie; daarna bouwt de geschiedenis (3/6/12 maanden) zich automatisch op.</div>
          </div>
        </div>
      )}

      <div className="grid cols-4" style={{ marginBottom: "var(--space)" }}>
        <KPI icon="euro" iconBg="var(--accent-soft)" iconColor="var(--accent)" label={"Omzet · " + perLabel.toLowerCase()} value={available ? fmtEur(Math.round(omzetTotal)) : "—"} foot="incl. btw, uit verkopen" />
        <KPI icon="trending" iconBg="var(--ok-soft)" iconColor="var(--ok)" label={pt > 0 ? "Winst (vóór belasting)" : "Winst · " + perLabel.toLowerCase()} value={available ? fmtEur(Math.round(winstVoor)) : "—"} foot={"na btw, inkoop, verzending, platform" + (adCost > 0 ? ", advertenties" : "") + (retCost > 0 ? ", retouren" : "") + (fulfilCost > 0 ? ", fulfilment" : "") + (ampereCost > 0 ? ", ophaalservice" : "")} />
        <KPI icon="check" iconBg="var(--brand-soft)" iconColor="var(--brand)" label={pt > 0 ? "Winst na belasting" : "Nettomarge"} value={pt > 0 ? (available ? fmtEur(Math.round(winstNa)) : "—") : (omzetTotal > 0 ? Math.round(winstVoor / omzetTotal * 100) + "%" : "—")} foot={pt > 0 ? `na ${pt}% winstbelasting` : "winst ÷ omzet"} />
        <KPI icon="star" iconBg="var(--warn-soft)" iconColor="var(--warn)" label="Gem. marge" value={omzetTotal > 0 ? Math.round((pt > 0 ? winstNa : winstVoor) / omzetTotal * 100) + "%" : "—"} foot={`over ${withCost.length} producten met inkoop`} />
      </div>

      {maxedaMonthly > 0 && available && (
        <div className="muted" style={{ fontSize: 12, margin: "-6px 0 var(--space)", display: "flex", alignItems: "center", gap: 6 }}>
          <Icon name="info" size={13} style={{ color: "var(--text-3)" }} />
          Inclusief Maxeda-maandbijdrage {fmtEur(maxedaMonthly, 0)}/mnd (≈ {fmtEur(maxedaFee, 2)} over {perLabel.toLowerCase()}), afgetrokken van de totale winst. Aanpasbaar bij Instellingen → Kosten &amp; verzending.
        </div>
      )}

      {zonderCost.length > 0 && (
        <div className="att-item" style={{ marginBottom: "var(--space)", borderColor: "var(--warn-line)", background: "var(--warn-soft)" }}>
          <span className="att-ico" style={{ background: "#fff", color: "var(--warn)" }}><Icon name="info" size={18} /></span>
          <div className="att-body">
            <div className="att-title">{zonderCost.length} verkopende producten zonder inkoopprijs</div>
            <div className="att-desc">Hun winst telt nog niet mee. Vul de inkoopprijs in op de productpagina: {zonderCost.map(p => p.sku).join(", ")}.</div>
          </div>
        </div>
      )}

      {available && withCost.length > 0 && (
        <Card style={{ marginBottom: "var(--space)" }}>
          <button className="card-toggle" onClick={() => setCostOpen(o => !o)}>
            <span className="ch-ico" style={{ background: "var(--accent-soft)", color: "var(--accent)" }}><Icon name="euro" size={17} /></span>
            <span style={{ flex: 1, textAlign: "left" }}>
              <span className="ch-title">Wat kost alles?</span>
              <span className="ch-sub">{costOpen ? "Opbouw van omzet naar winst" : "Totale kosten " + fmtEur(Math.round(kostenTotaal)) + " · " + perLabel.toLowerCase()}</span>
            </span>
            <Icon name="chevronDown" size={18} style={{ color: "var(--text-3)", transform: costOpen ? "rotate(180deg)" : "none", transition: ".18s" }} />
          </button>
          {costOpen && (
          <div className="card-pad" style={{ display: "flex", flexDirection: "column", gap: 2, borderTop: "1px solid var(--border)" }}>
            <div className="cost-row total"><span>Omzet (incl. btw)</span><b className="tnum">{fmtEur(Math.round(omzetWithCost))}</b></div>
            <div className="cost-row sub"><span>− btw ({db.vat()}%)</span><span className="tnum">−{fmtEur(Math.round(cost.btw))}</span></div>
            <div className="cost-row"><span style={{ fontWeight: 600 }}>Netto-omzet</span><b className="tnum">{fmtEur(Math.round(cost.netto))}</b></div>
            <div className="cost-sep" />
            {costRows.map(r => (
              <div className="cost-row sub" key={r.label}><span style={{ display: "flex", alignItems: "center", gap: 7 }}><Icon name={r.icon} size={14} style={{ color: "var(--text-3)" }} />− {r.label}</span><span className="tnum">−{fmtEur(Math.round(r.val))}</span></div>
            ))}
            <div className="cost-row sub" style={{ color: "var(--text-3)" }}><span style={{ paddingLeft: 21 }}>Totale kosten</span><span className="tnum">−{fmtEur(Math.round(kostenTotaal))}</span></div>
            {period === "today" && adCost === 0 && gadCost === 0 && (db.adsHasData && db.adsHasData() || db.gadsHasData && db.gadsHasData()) && (
              <div className="cost-row sub" style={{ color: "var(--text-3)", fontSize: 12 }}><span style={{ paddingLeft: 21 }}>Advertentiekosten van vandaag komen met vertraging binnen (bol & Google werken 's nachts bij) — die zie je morgen terug.</span><span></span></div>
            )}
            <div className="cost-sep" />
            <div className="cost-row total" style={{ fontSize: 15 }}><span>{pt > 0 ? "Winst (vóór belasting)" : "Winst"}</span><b className="tnum" style={{ color: winstVoor >= 0 ? "var(--ok)" : "var(--danger)" }}>{fmtEur(Math.round(winstVoor))}</b></div>
            {pt > 0 && <div className="cost-row sub"><span>− winstbelasting ({pt}%)</span><span className="tnum">−{fmtEur(Math.round(winstVoor - winstNa))}</span></div>}
            {pt > 0 && <div className="cost-row total"><span>Winst na belasting</span><b className="tnum" style={{ color: "var(--ok)" }}>{fmtEur(Math.round(winstNa))}</b></div>}
          </div>
          )}
        </Card>
      )}

      <div className="grid col-7-5">
        <Card>
          <CardHead title="Winst per platform" icon="chart" sub="Benadering: verkochte aantallen × huidige prijs" />
          <div className="card-pad" style={{ display: "flex", flexDirection: "column", gap: 14 }}>
            {platforms.length === 0 && <Placeholder label="Nog geen winstdata" note="vul inkoopprijzen in en wacht op verkopen" height={120} />}
            {platforms.map(pl => {
              const marge = pl.omzet > 0 ? Math.round(pl.winst / pl.omzet * 100) : 0;
              return (
                <div key={pl.name}>
                  <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
                    <span style={{ fontWeight: 600, fontSize: 13.5, flex: 1 }}>{pl.name}</span>
                    <span className="muted tnum" style={{ fontSize: 12.5 }}>{pl.units} st · {fmtEur(pl.omzet)}</span>
                    <span className={"pill " + (pl.winst >= 0 ? "ok" : "danger")} style={{ minWidth: 92, justifyContent: "center" }}>{fmtEur(Math.round(pl.winst))} · {marge}%</span>
                  </div>
                  <div className="bar"><span style={{ width: Math.max(3, Math.abs(pl.winst) / maxWinst * 100) + "%", background: pl.winst >= 0 ? "var(--ok)" : "var(--danger)" }} /></div>
                </div>
              );
            })}
          </div>
        </Card>

        <Card>
          <CardHead title="Beste marges" icon="trending" sub="Per product" />
          <table className="tbl">
            <thead><tr><th>Product</th><th className="num">Winst</th><th className="num">Marge</th></tr></thead>
            <tbody>
              {withCost.map(p => {
                const inf = info(p);
                const w = db.winstInfo(p, inf); if (!w) return null;
                const val = pt > 0 ? w.na : w.voor;
                const marge = inf.rev > 0 ? Math.round(val / inf.rev * 100) : 0;
                return { p, val, marge };
              }).filter(Boolean).sort((a, b) => b.marge - a.marge).map(({ p, val, marge }) => (
                <tr key={p.id} className="row-click" onClick={() => onNav("producten", p.id)}>
                  <td><div className="prod"><ProductThumb p={p} size={30} /><span style={{ fontWeight: 600, fontSize: 13 }}>{p.name}</span></div></td>
                  <td className="num tnum" style={{ fontWeight: 600, color: val >= 0 ? "var(--ok)" : "var(--danger)" }}>{fmtEur(Math.round(val))}</td>
                  <td className="num tnum"><span className={"pill " + (marge >= 0 ? "ok" : "danger")} style={{ minWidth: 48, justifyContent: "center" }}>{marge}%</span></td>
                </tr>
              ))}
            </tbody>
          </table>
        </Card>
      </div>
    </div>
  );
}

window.Winst = Winst;
