// ═══════════════════════════════════════════════════════════════
//  movements.jsx — Движения: единна хронология на всички пари
//  (приходи · разходи · тегления · данъци) + Сверка с извлечение.
//  Сверката парсва ДСК файл (parseStatement от bank.jsx) и сравнява
//  БЕЗ да внася: точен мач по bank_tx_id, после приблизителен
//  (посока + сума ±1 € + дата ±5 дни). Показва разминаванията.
// ═══════════════════════════════════════════════════════════════
const { useState: useStateM, useMemo: useMemoM } = React;

const MOV_KINDS = [
  { v: "", l: "Всички" },
  { v: "income", l: "Приходи" },
  { v: "expense", l: "Разходи" },
  { v: "withdrawal", l: "Тегления" },
  { v: "tax", l: "Данъци" },
  { v: "offset", l: "Прихващания" },
];
const MOV_BG_M = ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"];
const movTaxLabel = (t) => {
  const n = { profit: "Данък печалба", dividend: "Данък дивидент", vat: "ДДС" }[t.type] || t.type;
  return `${n} · ${t.period}`;
};

function MovementsView({ T, incomes, expenses, withdrawals, taxPayments, onNavigate }) {
  const isMobile = useIsMobile();
  const [year, setYear] = useStateM(YEAR);
  const [kind, setKind] = useStateM("");

  // ─── единна лента ───
  const all = useMemoM(() => {
    const rows = [];
    (incomes || []).forEach(e => rows.push({
      key: "i" + e.id, date: e.date, kind: e.account === "offset" ? "offset" : "income",
      label: e.payer || "—", sub: e.source === "invoice" ? `№ ${e.invoiceNum}` : sourceDef(e.source).l,
      amt: toEUR(e.amount, e.currency), dir: 1, bank: !!e.bankTxId, cash: e.account !== "offset", nav: "income",
    }));
    (expenses || []).forEach(e => rows.push({
      key: "e" + e.id, date: e.date, kind: "expense",
      label: e.vendor || e.description || "—", sub: e.vendor && e.description ? e.description : (e.category || "разход"),
      amt: toEUR((Number(e.amount) || 0) + (Number(e.vat) || 0), e.currency), dir: -1, bank: !!e.bank_tx_id, cash: true, nav: "expenses",
    }));
    (withdrawals || []).forEach(w => rows.push({
      key: "w" + w.id, date: w.date, kind: "withdrawal",
      label: w.note || "Теглене", sub: "теглене · дивидент",
      amt: toEUR(w.amount, w.currency), dir: -1, bank: !!w.bank_tx_id, cash: true, nav: "finance",
    }));
    (taxPayments || []).forEach(t => {
      const a = Number(t.amount) || 0;
      rows.push({
        key: "t" + t.id, date: t.paid_date, kind: "tax",
        label: movTaxLabel(t), sub: a < 0 ? "приспаднат / възстановен (без движение)" : "платен към НАП",
        amt: Math.abs(a), dir: a < 0 ? 1 : -1, bank: false, cash: a >= 0, nav: "finance",
      });
    });
    return rows.filter(r => r.date).sort((a, b) => b.date.localeCompare(a.date) || b.key.localeCompare(a.key));
  }, [incomes, expenses, withdrawals, taxPayments]);

  const years = useMemoM(() => {
    const s = new Set([YEAR]);
    all.forEach(r => { const y = r.date.slice(0, 4); if (y) s.add(y); });
    return [...s].sort().reverse();
  }, [all]);

  const filtered = useMemoM(() => all
    .filter(r => r.date.startsWith(year))
    .filter(r => !kind || r.kind === kind), [all, year, kind]);

  // месечни групи с кешови суми (прихващания и приспадания не са пари)
  const byMonth = useMemoM(() => {
    const map = {};
    filtered.forEach(r => {
      const mm = r.date.slice(0, 7);
      (map[mm] = map[mm] || { rows: [], inc: 0, out: 0 }).rows.push(r);
      if (r.cash) { if (r.dir > 0) map[mm].inc += r.amt; else map[mm].out += r.amt; }
    });
    return Object.entries(map).sort((a, b) => b[0].localeCompare(a[0]));
  }, [filtered]);

  const yIn = byMonth.reduce((s, [, m]) => s + m.inc, 0);
  const yOut = byMonth.reduce((s, [, m]) => s + m.out, 0);

  const kindBadge = (r) => {
    const def = {
      income: { l: "приход", c: T.sage }, expense: { l: "разход", c: T.danger },
      withdrawal: { l: "теглене", c: "#C9912B" }, tax: { l: "данък", c: T.blue },
      offset: { l: "прихващане", c: T.faint },
    }[r.kind];
    return <span style={{ fontSize: 9.5, fontWeight: 700, textTransform: "uppercase", color: def.c, background: `${def.c}1A`, padding: "3px 8px", borderRadius: 5, whiteSpace: "nowrap" }}>{def.l}</span>;
  };

  // ─── Сверка ───
  const [rec, setRec] = useStateM(null);
  const [recMsg, setRecMsg] = useStateM("");

  const reconcile = (bankRows) => {
    const recs = [];
    (incomes || []).forEach(e => { if (e.account === "dsk") recs.push({ key: "i" + e.id, date: e.date, amt: toEUR(e.amount, e.currency), dir: 1, tx: e.bankTxId || "", label: `Приход · ${e.payer || "—"}${e.invoiceNum ? ` · № ${e.invoiceNum}` : ""}` }); });
    (expenses || []).forEach(e => recs.push({ key: "e" + e.id, date: e.date, amt: toEUR((Number(e.amount) || 0) + (Number(e.vat) || 0), e.currency), dir: -1, tx: e.bank_tx_id || "", label: `Разход · ${e.vendor || e.description || "—"}` }));
    (withdrawals || []).forEach(w => recs.push({ key: "w" + w.id, date: w.date, amt: toEUR(w.amount, w.currency), dir: -1, tx: w.bank_tx_id || "", label: `Теглене · ${w.note || ""}` }));
    (taxPayments || []).forEach(t => { const a = Number(t.amount) || 0; if (a > 0) recs.push({ key: "t" + t.id, date: t.paid_date, amt: a, dir: -1, tx: "", label: `Данък · ${movTaxLabel(t)}` }); });

    const used = new Set();
    // 1-ви пас: точни съвпадения по bank_tx_id
    const staged = bankRows.map(r => {
      const m = recs.find(x => !used.has(x.key) && x.tx && x.tx === r.tx_id);
      if (m) { used.add(m.key); return { ...r, status: "ok", match: m.label }; }
      return { ...r, status: "pending" };
    });
    // 2-ри пас: приблизителни (посока + сума ±1 + дата ±5 дни, най-близката дата печели)
    const rows = staged.map(r => {
      if (r.status !== "pending") return r;
      const amt = Math.abs(r.amount), dir = r.direction === "in" ? 1 : -1;
      const cand = recs
        .filter(x => !used.has(x.key) && x.dir === dir && Math.abs(x.amt - amt) <= 1 && Math.abs(daysBetween(x.date, r.date)) <= 5)
        .sort((a, b) => Math.abs(daysBetween(a.date, r.date)) - Math.abs(daysBetween(b.date, r.date)) || Math.abs(a.amt - amt) - Math.abs(b.amt - amt))[0];
      if (cand) { used.add(cand.key); return { ...r, status: "fuzzy", match: cand.label }; }
      return { ...r, status: "missing" };
    });
    const dates = bankRows.map(r => r.date).filter(Boolean).sort();
    const from = dates[0] || "", to = dates[dates.length - 1] || "";
    const extra = recs.filter(x => !used.has(x.key) && x.date >= from && x.date <= to);
    return {
      rows, from, to, extra,
      ok: rows.filter(r => r.status === "ok").length,
      fuzzy: rows.filter(r => r.status === "fuzzy").length,
      missing: rows.filter(r => r.status === "missing").length,
    };
  };

  const handleRecFiles = (e) => {
    const files = [...(e.target.files || [])];
    if (!files.length) return;
    setRecMsg("");
    Promise.all(files.map(f => f.text().then(t => parseStatement(t))))
      .then(lists => {
        const bankRows = [].concat(...lists);
        if (!bankRows.length) { setRec(null); setRecMsg("Файлът не съдържа разпознаваеми транзакции."); return; }
        setRec(reconcile(bankRows));
      })
      .catch(err => { console.error("[reconcile]", err); setRec(null); setRecMsg("Грешка при четене: " + err.message); });
    e.target.value = "";
  };

  const chip = (label, value, color) => (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 11, fontWeight: 700, fontFamily: MONO, color: color, background: `${color}14`, border: `1px solid ${color}33`, padding: "5px 10px", borderRadius: 8 }}>
      {label} {value}
    </span>
  );

  const recRow = (r, i) => (
    <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 12px", background: T.field, border: `1px solid ${r.status === "missing" ? `${T.danger}55` : T.line}`, borderRadius: 8, flexWrap: "wrap" }}>
      <span style={{ fontSize: 11, color: T.faint, fontFamily: MONO, minWidth: 70 }}>{fmtDate(r.date)}</span>
      <span style={{ fontSize: 12, flex: 1, minWidth: 140, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.name}{r.info ? ` · ${r.info}` : ""}</span>
      <span style={{ fontFamily: MONO, fontWeight: 700, fontSize: 12.5, color: r.direction === "in" ? T.sage : T.danger }}>{r.direction === "in" ? "+" : "−"}{fmtNum(Math.abs(r.amount))}</span>
      {r.status === "fuzzy" && <span style={{ fontSize: 10, color: "#C9912B" }}>≈ {r.match}</span>}
      {r.status === "missing" && <span style={{ fontSize: 10, fontWeight: 700, color: T.danger }}>липсва в приложението</span>}
    </div>
  );

  return (
    <div style={{ maxWidth: 920, margin: "0 auto", padding: isMobile ? "18px 14px 48px" : "28px 28px 60px" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 18, gap: 12, flexWrap: "wrap" }}>
        <h2 style={{ fontSize: 18, fontWeight: 600, letterSpacing: "-0.02em", margin: 0 }}>Движения</h2>
        <div style={{ display: "flex", gap: 10 }}>
          <div style={{ minWidth: 130 }}><Select label="Тип" value={kind} onChange={setKind} options={MOV_KINDS} T={T} /></div>
          <div style={{ minWidth: 100 }}><Select label="Година" value={year} onChange={setYear} options={years.map(y => ({ v: y, l: y }))} T={T} /></div>
        </div>
      </div>

      <div style={{ display: "flex", gap: 12, flexWrap: "wrap", marginBottom: 16 }}>
        <div style={{ flex: 1, minWidth: 150, padding: "14px 18px", background: T.surface, border: `1px solid ${T.line}`, borderRadius: 10 }}>
          <div style={{ fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: T.faint, marginBottom: 6 }}>Влезли {year}</div>
          <div style={{ fontFamily: MONO, fontSize: 20, fontWeight: 700, color: T.sage }}>{eur(yIn)}</div>
        </div>
        <div style={{ flex: 1, minWidth: 150, padding: "14px 18px", background: T.surface, border: `1px solid ${T.line}`, borderRadius: 10 }}>
          <div style={{ fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: T.faint, marginBottom: 6 }}>Излезли {year}</div>
          <div style={{ fontFamily: MONO, fontSize: 20, fontWeight: 700, color: T.danger }}>{eur(yOut)}</div>
        </div>
        <div style={{ flex: 1, minWidth: 150, padding: "14px 18px", background: T.surface, border: `1px solid ${T.line}`, borderRadius: 10 }}>
          <div style={{ fontSize: 10, letterSpacing: "0.08em", textTransform: "uppercase", color: T.faint, marginBottom: 6 }}>Нето</div>
          <div style={{ fontFamily: MONO, fontSize: 20, fontWeight: 700, color: yIn - yOut >= 0 ? T.ink : T.danger }}>{eur(yIn - yOut)}</div>
        </div>
      </div>

      {/* Сверка */}
      <Card T={T} title="Сверка с извлечение" icon="check"
        right={<label style={{ cursor: "pointer" }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 7, padding: "8px 14px", borderRadius: 7, fontSize: 12, fontWeight: 600, fontFamily: MONO, background: T.blue, color: "#fff" }}>
            <Icon name="download" size={14} />Качи извлечение
          </span>
          <input type="file" accept=".xls,.csv,.html,.htm,.xlsx" multiple onChange={handleRecFiles} style={{ display: "none" }} />
        </label>}>
        <div style={{ fontSize: 12, color: T.sub, lineHeight: 1.6 }}>
          Качи ДСК извлечение и ще сравня ред по ред със записите тук, без да внасям нищо. Показвам какво съвпада, какво е приблизително и какво липсва от едната или другата страна.
        </div>
        {recMsg && <div style={{ marginTop: 10, fontSize: 12, color: T.danger }}>{recMsg}</div>}
        {rec && (
          <div style={{ marginTop: 14 }}>
            <div style={{ display: "flex", gap: 8, flexWrap: "wrap", marginBottom: 12 }}>
              {chip("период", `${fmtDate(rec.from)} – ${fmtDate(rec.to)}`, T.sub)}
              {chip("✓ съвпадат", rec.ok, T.sage)}
              {chip("≈ приблизителни", rec.fuzzy, "#C9912B")}
              {chip("✗ липсват тук", rec.missing, T.danger)}
              {chip("без ред в банката", rec.extra.length, T.blue)}
            </div>
            {rec.missing > 0 && (
              <div style={{ marginBottom: 12 }}>
                <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: T.danger, marginBottom: 6 }}>В банката, но не и в приложението</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>{rec.rows.filter(r => r.status === "missing").map(recRow)}</div>
                <div style={{ fontSize: 11, color: T.sub, marginTop: 6 }}>Внеси ги от <span onClick={() => onNavigate && onNavigate("bank")} style={{ color: T.blue, cursor: "pointer", fontWeight: 600 }}>Банка → Качи извлечение</span>.</div>
              </div>
            )}
            {rec.fuzzy > 0 && (
              <div style={{ marginBottom: 12 }}>
                <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: "#C9912B", marginBottom: 6 }}>Приблизителни съвпадения — прегледай ги</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>{rec.rows.filter(r => r.status === "fuzzy").map(recRow)}</div>
              </div>
            )}
            {rec.extra.length > 0 && (
              <div>
                <div style={{ fontSize: 11, fontWeight: 700, letterSpacing: "0.06em", textTransform: "uppercase", color: T.blue, marginBottom: 6 }}>В приложението, но без ред в банката за периода</div>
                <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                  {rec.extra.map(x => (
                    <div key={x.key} style={{ display: "flex", alignItems: "center", gap: 10, padding: "9px 12px", background: T.field, border: `1px solid ${T.line}`, borderRadius: 8 }}>
                      <span style={{ fontSize: 11, color: T.faint, fontFamily: MONO, minWidth: 70 }}>{fmtDate(x.date)}</span>
                      <span style={{ fontSize: 12, flex: 1 }}>{x.label}</span>
                      <span style={{ fontFamily: MONO, fontWeight: 700, fontSize: 12.5, color: x.dir > 0 ? T.sage : T.danger }}>{x.dir > 0 ? "+" : "−"}{fmtNum(x.amt)}</span>
                    </div>
                  ))}
                </div>
                <div style={{ fontSize: 11, color: T.sub, marginTop: 6 }}>Нормално за: плащания по Wise/PayPal, прихващания, ръчни записи с друга дата. Ако е ДСК запис — провери го.</div>
              </div>
            )}
            {rec.missing === 0 && rec.fuzzy === 0 && rec.extra.length === 0 && (
              <div style={{ fontSize: 12.5, fontWeight: 600, color: T.sage }}>Всичко съвпада — банката и приложението казват едно и също. 🎉</div>
            )}
          </div>
        )}
      </Card>

      {/* хронология по месеци */}
      {byMonth.length === 0 ? <Empty T={T} icon="history" text={"Няма движения за " + year} /> : byMonth.map(([mm, m]) => (
        <div key={mm} style={{ marginBottom: 18 }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", padding: "0 4px 8px", flexWrap: "wrap", gap: 8 }}>
            <span style={{ fontSize: 12.5, fontWeight: 700 }}>{MOV_BG_M[+mm.slice(5, 7) - 1]} {mm.slice(0, 4)}</span>
            <span style={{ fontSize: 11, fontFamily: MONO, color: T.sub }}>
              <span style={{ color: T.sage }}>+{fmtNum(m.inc)}</span> · <span style={{ color: T.danger }}>−{fmtNum(m.out)}</span> · нето <b style={{ color: m.inc - m.out >= 0 ? T.ink : T.danger }}>{fmtNum(m.inc - m.out)}</b>
            </span>
          </div>
          <div style={{ display: "flex", flexDirection: "column", gap: 7 }}>
            {m.rows.map(r => (
              <div key={r.key} onClick={() => onNavigate && onNavigate(r.nav)} style={{ cursor: "pointer", display: "flex", alignItems: "center", gap: 12, padding: "10px 14px", background: T.surface, border: `1px solid ${T.line}`, borderRadius: 9, opacity: r.cash ? 1 : 0.62 }}>
                <span style={{ fontSize: 11, color: T.faint, fontFamily: MONO, minWidth: 70 }}>{fmtDate(r.date)}</span>
                {kindBadge(r)}
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 12.5, fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.label}</div>
                  <div style={{ fontSize: 10.5, color: T.faint, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.sub}</div>
                </div>
                {r.bank && <span title="Потвърдено от банково извлечение" style={{ width: 7, height: 7, borderRadius: 9, background: T.sage, flexShrink: 0 }} />}
                <span style={{ fontFamily: MONO, fontWeight: 700, fontSize: 13, color: !r.cash ? T.faint : (r.dir > 0 ? T.sage : T.danger), minWidth: 92, textAlign: "right" }}>
                  {r.dir > 0 ? "+" : "−"}{fmtNum(r.amt)}
                </span>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, { MovementsView });
