// Bills & Subscriptions view
// - Subscription templates: add/edit/pause/delete the recurring expense definitions
// - Auto-creation: when the dashboard loads, missing months get inserted as 'predicted'
// - Audit table: shows last/upcoming charge per active template

function BillsView() {
  const subs = window.FIN_DATA.SUBSCRIPTIONS || [];
  const txs = window.FIN_DATA.TRANSACTIONS || [];
  const active = subs.filter(s => s.active);
  const paused = subs.filter(s => !s.active);

  const sgdAmount = (s) => s.currency === "USD"
    ? s.amount * (window.FIN_DATA.SETTINGS?.fx_rate_usd_to_sgd || 1.35)
    : s.amount;
  const monthlyFixed = active.reduce((sum, s) => sum + sgdAmount(s), 0);
  const annualFixed = monthlyFixed * 12;

  const txsBySub = {};
  txs.forEach(t => {
    if (t.subscriptionId) {
      (txsBySub[t.subscriptionId] = txsBySub[t.subscriptionId] || []).push(t);
    }
  });
  Object.values(txsBySub).forEach(arr => arr.sort((a, b) => b.date.localeCompare(a.date)));

  const predictedCount = txs.filter(t => t.status === "predicted").length;

  const [showAdd, setShowAdd] = React.useState(false);
  const [editing, setEditing] = React.useState(null);

  return (
    <div>
      <div style={{ marginBottom: 22, display: "flex", justifyContent: "space-between", alignItems: "flex-start", flexWrap: "wrap", gap: 12 }}>
        <div>
          <div style={{ fontSize: 11, fontWeight: 600, color: "var(--text-muted)", textTransform: "uppercase", letterSpacing: "0.04em", marginBottom: 4 }}>
            Bills & Subscriptions
          </div>
          <h1 style={{ fontSize: 24, fontWeight: 700, margin: 0, color: "var(--text-1)", letterSpacing: "-0.015em" }}>
            {fmt.sgd(monthlyFixed)} <span style={{ color: "var(--text-muted)", fontWeight: 500 }}>/ month fixed</span>
          </h1>
          <div style={{ fontSize: 13, color: "var(--text-muted)", marginTop: 4 }}>
            {active.length} active · {fmt.sgd(annualFixed, { decimals: 0 })} annualized
            {paused.length > 0 && <> · {paused.length} paused</>}
          </div>
        </div>
        <button onClick={() => setShowAdd(true)} className="btn-primary">
          <Icon name="plus" size={14}/> New subscription
        </button>
      </div>

      {predictedCount > 0 && (
        <div style={{
          padding: "10px 14px", background: "var(--info-soft)", color: "var(--info)",
          borderRadius: 10, fontSize: 12, marginBottom: 16,
          display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap",
        }}>
          <Icon name="info" size={14}/>
          <div>
            <span style={{ fontWeight: 600 }}>{predictedCount} predicted transaction{predictedCount === 1 ? "" : "s"}</span>
            <span style={{ marginLeft: 6 }}>waiting for confirmation. Find them in the Transactions view (greyed out) and confirm or adjust the amount once your statement arrives.</span>
          </div>
        </div>
      )}

      <div className="card" style={{ padding: 18, marginBottom: 18 }}>
        <div style={{ marginBottom: 14 }}>
          <div style={{ fontSize: 14, fontWeight: 600, color: "var(--text-1)" }}>Active subscriptions</div>
          <div style={{ fontSize: 11, color: "var(--text-muted)", marginTop: 2 }}>Auto-created each month on the schedule below</div>
        </div>

        {active.length === 0 ? (
          <BillsEmpty icon="repeat" message="No active subscriptions" sub="Click 'New subscription' to add one."/>
        ) : (
          <SubscriptionTable subs={active} txsBySub={txsBySub} onEdit={setEditing}/>
        )}
      </div>

      {paused.length > 0 && (
        <div className="card" style={{ padding: 18, marginBottom: 18 }}>
          <div style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 14, fontWeight: 600, color: "var(--text-muted)" }}>Paused</div>
            <div style={{ fontSize: 11, color: "var(--text-muted)", marginTop: 2 }}>Not auto-created. Resume to start tracking again.</div>
          </div>
          <SubscriptionTable subs={paused} txsBySub={txsBySub} onEdit={setEditing} muted/>
        </div>
      )}

      {showAdd && <SubscriptionModal onClose={() => setShowAdd(false)}/>}
      {editing && <SubscriptionModal initial={editing} onClose={() => setEditing(null)}/>}
    </div>
  );
}

function SubscriptionTable({ subs, txsBySub, onEdit, muted }) {
  const sorted = [...subs].sort((a, b) => {
    if (muted) return a.merchant.localeCompare(b.merchant);
    return a.dayOfMonth - b.dayOfMonth;
  });

  return (
    <div>
      <div style={{
        display: "grid", gridTemplateColumns: "1.4fr 90px 110px 110px 90px 70px",
        gap: 8, padding: "8px 12px", fontSize: 11,
        color: "var(--text-muted)", fontWeight: 600,
        textTransform: "uppercase", letterSpacing: "0.04em",
        borderBottom: "1px solid var(--border-subtle)",
      }}>
        <div>Subscription</div>
        <div style={{ textAlign: "right" }}>Amount</div>
        <div style={{ textAlign: "right" }}>Annual</div>
        <div>Day</div>
        <div>Last</div>
        <div></div>
      </div>
      {sorted.map(sub => <SubscriptionRow key={sub.id} sub={sub} instances={txsBySub[sub.id] || []} onEdit={onEdit} muted={muted}/>)}
    </div>
  );
}

function SubscriptionRow({ sub, instances, onEdit, muted }) {
  const card = sub.cardId ? getCard(sub.cardId) : null;
  const cat = sub.category ? getCategory(sub.category) : null;
  const sgdAmount = sub.currency === "USD"
    ? sub.amount * (window.FIN_DATA.SETTINGS?.fx_rate_usd_to_sgd || 1.35)
    : sub.amount;
  const annual = sgdAmount * 12;
  const last = instances[0];
  const dim = muted ? { opacity: 0.6 } : {};

  return (
    <div
      onClick={() => onEdit(sub)}
      style={{
        display: "grid", gridTemplateColumns: "1.4fr 90px 110px 110px 90px 70px",
        gap: 8, alignItems: "center", padding: "12px",
        borderBottom: "1px solid var(--border-subtle)",
        cursor: "pointer", transition: "background 0.12s",
        ...dim,
      }}
      onMouseEnter={e => { e.currentTarget.style.background = "var(--bg-muted)"; }}
      onMouseLeave={e => { e.currentTarget.style.background = "transparent"; }}>

      <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 0 }}>
        {cat && (
          <div style={{
            width: 30, height: 30, borderRadius: 8,
            background: cat.color + "22",
            display: "grid", placeItems: "center", flexShrink: 0,
          }}>
            <Icon name={cat.icon} size={14} style={{ color: cat.color }}/>
          </div>
        )}
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 500, color: "var(--text-1)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
            {sub.merchant}
          </div>
          <div style={{ fontSize: 11, color: "var(--text-muted)", marginTop: 1 }}>
            {card ? `${card.name} ····${card.last4}` : sub.paymentMethod || "Bank"}
            {sub.note && <> · {sub.note}</>}
          </div>
        </div>
      </div>

      <div style={{ textAlign: "right", fontSize: 13, color: "var(--text-1)", fontWeight: 500, fontVariantNumeric: "tabular-nums" }}>
        {sub.currency === "USD" ? `US$${sub.amount.toFixed(2)}` : fmt.sgd(sub.amount)}
      </div>

      <div style={{ textAlign: "right", fontSize: 13, color: "var(--text-2)", fontVariantNumeric: "tabular-nums" }}>
        {fmt.sgd(annual, { decimals: 0 })}
      </div>

      <div style={{ fontSize: 12, color: "var(--text-muted)" }}>
        {dayLabel(sub.dayOfMonth)}
      </div>

      <div style={{ fontSize: 11, color: "var(--text-muted)", fontVariantNumeric: "tabular-nums" }}>
        {last ? (
          <>
            {fmt.dateShort(last.date)}
            {last.status === "predicted" && (
              <div style={{ fontSize: 10, color: "var(--info)", fontWeight: 500 }}>predicted</div>
            )}
          </>
        ) : "—"}
      </div>

      <div style={{ textAlign: "right" }}>
        <Icon name="chevron-right" size={14} style={{ color: "var(--text-muted)" }}/>
      </div>
    </div>
  );
}

function dayLabel(n) {
  if (n >= 11 && n <= 13) return n + "th";
  const last = n % 10;
  return n + (last === 1 ? "st" : last === 2 ? "nd" : last === 3 ? "rd" : "th");
}

function SubscriptionModal({ initial, onClose }) {
  const isEdit = !!initial;
  const { CARDS, ACCOUNTS, CATEGORIES } = window.FIN_DATA;

  const [merchant, setMerchant] = React.useState(initial?.merchant || "");
  const [amount, setAmount] = React.useState(initial?.amount ? String(initial.amount) : "");
  const [currency, setCurrency] = React.useState(initial?.currency || "SGD");
  const [category, setCategory] = React.useState(initial?.category || CATEGORIES[0]?.id || "others");
  const [dayOfMonth, setDayOfMonth] = React.useState(initial?.dayOfMonth || 1);
  const [paymentMode, setPaymentMode] = React.useState(initial?.cardId ? "card" : initial?.accountId ? "bank" : "card");
  const [cardId, setCardId] = React.useState(initial?.cardId || CARDS.find(c => c.type === "credit")?.id || "");
  const [accountId, setAccountId] = React.useState(initial?.accountId || ACCOUNTS.find(a => a.type === "bank" && a.primary)?.id || "");
  const [paymentMethod, setPaymentMethod] = React.useState(initial?.paymentMethod || "GIRO");
  const [note, setNote] = React.useState(initial?.note || "");
  const [active, setActive] = React.useState(initial?.active ?? true);

  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState(null);

  const handleSave = async () => {
    setError(null);
    const n = parseFloat(amount);
    if (!merchant.trim()) return setError("Merchant is required.");
    if (!n || n <= 0) return setError("Amount must be greater than zero.");
    if (!dayOfMonth || dayOfMonth < 1 || dayOfMonth > 31) return setError("Day of month must be 1–31.");

    const seriesId = initial?.seriesId
      || (merchant.toLowerCase().replace(/[^a-z0-9]+/g, "-") + "-monthly").replace(/^-+|-+$/g, "");

    const payload = {
      seriesId,
      merchant: merchant.trim(),
      amount: n,
      currency,
      category,
      dayOfMonth: parseInt(dayOfMonth),
      note: note.trim() || null,
      active,
    };
    if (paymentMode === "card") {
      payload.cardId = cardId;
      payload.accountId = null;
      payload.paymentMethod = null;
    } else {
      payload.cardId = null;
      payload.accountId = accountId;
      payload.paymentMethod = paymentMethod;
    }

    setBusy(true);
    try {
      if (isEdit) {
        await window.updateSubscription(initial.id, payload);
      } else {
        await window.insertSubscription(payload);
      }
      if (window.refetchData) window.refetchData();
      onClose();
    } catch (err) {
      setError(err.message || "Save failed.");
      setBusy(false);
    }
  };

  const handleDelete = async () => {
    if (!isEdit) return;
    if (!window.confirm(`Delete the "${initial.merchant}" subscription? This stops auto-creation but keeps your past confirmed transactions.`)) return;
    const alsoPredicted = window.confirm("Also delete predicted (un-confirmed) charges for this subscription?\n\nClick OK to delete predicted charges too. Cancel to keep them.");
    setBusy(true);
    try {
      await window.deleteSubscription(initial.id, { deletePredicted: alsoPredicted });
      if (window.refetchData) window.refetchData();
      onClose();
    } catch (err) {
      setError(err.message || "Delete failed.");
      setBusy(false);
    }
  };

  return (
    <div style={{
      position: "fixed", inset: 0, background: "rgba(0,0,0,0.5)",
      display: "grid", placeItems: "center", zIndex: 1000, backdropFilter: "blur(4px)",
    }} onClick={onClose}>
      <div className="card" style={{
        width: 480, maxWidth: "calc(100vw - 32px)", maxHeight: "calc(100vh - 32px)",
        padding: 0, overflow: "hidden",
        display: "flex", flexDirection: "column",
        boxShadow: "0 20px 60px -10px rgba(0,0,0,0.4)",
      }} onClick={e => e.stopPropagation()}>

        <div style={{ padding: "18px 22px", display: "flex", justifyContent: "space-between", alignItems: "center", borderBottom: "1px solid var(--border-subtle)" }}>
          <h2 style={{ fontSize: 16, fontWeight: 600, margin: 0, color: "var(--text-1)" }}>
            {isEdit ? "Edit subscription" : "New subscription"}
          </h2>
          <button onClick={onClose} className="btn-ghost-sm"><Icon name="x" size={16}/></button>
        </div>

        <div style={{ padding: 22, display: "flex", flexDirection: "column", gap: 14, overflowY: "auto", flex: 1 }}>
          <SubField label="Merchant">
            <input value={merchant} onChange={e => setMerchant(e.target.value)} placeholder="e.g. Spotify, Netflix, Singtel" className="input"/>
          </SubField>

          <div style={{ display: "grid", gridTemplateColumns: "1.4fr 0.8fr 1fr", gap: 8 }}>
            <SubField label="Amount">
              <div style={{ position: "relative" }}>
                <span style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", fontSize: 12, fontWeight: 500, color: "var(--text-muted)" }}>{currency === "USD" ? "US$" : "S$"}</span>
                <input
                  value={amount}
                  onChange={e => setAmount(e.target.value)}
                  placeholder="0.00" type="number" step="0.01"
                  style={{
                    width: "100%", padding: "10px 12px 10px 38px",
                    fontSize: 16, fontWeight: 600, fontVariantNumeric: "tabular-nums",
                    background: "var(--bg-muted)", border: "1px solid transparent",
                    borderRadius: 8, color: "var(--text-1)", outline: "none", fontFamily: "inherit",
                  }}/>
              </div>
            </SubField>
            <SubField label="Currency">
              <select value={currency} onChange={e => setCurrency(e.target.value)} className="input">
                <option value="SGD">SGD</option>
                <option value="USD">USD</option>
              </select>
            </SubField>
            <SubField label="Day of month">
              <input
                value={dayOfMonth}
                onChange={e => setDayOfMonth(e.target.value)}
                type="number" min="1" max="31"
                className="input"/>
            </SubField>
          </div>

          <SubField label="Category">
            <select value={category} onChange={e => setCategory(e.target.value)} className="input">
              {CATEGORIES.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
            </select>
          </SubField>

          <SubField label="Pay via">
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 6 }}>
              <button onClick={() => setPaymentMode("card")} style={subSegStyle(paymentMode === "card")}>
                <Icon name="card" size={13}/> Card
              </button>
              <button onClick={() => setPaymentMode("bank")} style={subSegStyle(paymentMode === "bank")}>
                <Icon name="wallet" size={13}/> Bank (GIRO/PayNow)
              </button>
            </div>
          </SubField>

          {paymentMode === "card" ? (
            <SubField label="Card">
              <select value={cardId} onChange={e => setCardId(e.target.value)} className="input">
                <optgroup label="Credit">
                  {CARDS.filter(c => c.type === "credit").map(c => <option key={c.id} value={c.id}>{c.name} ····{c.last4}</option>)}
                </optgroup>
                <optgroup label="Debit">
                  {CARDS.filter(c => c.type === "debit").map(c => <option key={c.id} value={c.id}>{c.name} ····{c.last4}</option>)}
                </optgroup>
              </select>
            </SubField>
          ) : (
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
              <SubField label="Account">
                <select value={accountId} onChange={e => setAccountId(e.target.value)} className="input">
                  {ACCOUNTS.filter(a => a.type === "bank").map(a => <option key={a.id} value={a.id}>{a.name}</option>)}
                </select>
              </SubField>
              <SubField label="Method">
                <select value={paymentMethod} onChange={e => setPaymentMethod(e.target.value)} className="input">
                  <option value="GIRO">GIRO</option>
                  <option value="PayNow">PayNow</option>
                  <option value="Bank transfer">Bank transfer</option>
                </select>
              </SubField>
            </div>
          )}

          <SubField label="Note (optional)">
            <input value={note} onChange={e => setNote(e.target.value)} placeholder="e.g. Premium individual" className="input"/>
          </SubField>

          <label style={{ display: "flex", alignItems: "center", gap: 10, cursor: "pointer", padding: "10px 12px", borderRadius: 8, background: "var(--bg-muted)" }}>
            <input type="checkbox" checked={active} onChange={e => setActive(e.target.checked)} style={{ accentColor: "var(--accent)" }}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 13, fontWeight: 500, color: "var(--text-1)" }}>Active</div>
              <div style={{ fontSize: 11, color: "var(--text-muted)" }}>Auto-create predicted charges each month. Uncheck to pause.</div>
            </div>
          </label>

          {error && (
            <div style={{
              padding: "9px 12px", background: "var(--danger-soft)", color: "var(--danger)",
              borderRadius: 8, fontSize: 12, display: "flex", alignItems: "center", gap: 6,
            }}>
              <Icon name="alert" size={13}/>
              {error}
            </div>
          )}
        </div>

        <div style={{ padding: "14px 22px", display: "flex", justifyContent: "space-between", gap: 8, borderTop: "1px solid var(--border-subtle)", background: "var(--bg-muted)", flexShrink: 0 }}>
          {isEdit ? (
            <button onClick={handleDelete} disabled={busy} style={{
              fontSize: 12, padding: "8px 14px", borderRadius: 7,
              background: "transparent", color: "var(--danger)",
              border: "1px solid var(--border)",
              cursor: busy ? "wait" : "pointer", fontFamily: "inherit",
            }}>
              Delete subscription
            </button>
          ) : <div/>}
          <div style={{ display: "flex", gap: 8 }}>
            <button onClick={onClose} className="btn-ghost" disabled={busy}>Cancel</button>
            <button onClick={handleSave} className="btn-primary" disabled={busy}>
              {busy ? "Saving…" : (<><Icon name="check" size={14}/> {isEdit ? "Save changes" : "Add subscription"}</>)}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

function SubField({ label, children }) {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
      <label style={{ fontSize: 11, fontWeight: 600, color: "var(--text-muted)", textTransform: "uppercase", letterSpacing: "0.04em" }}>{label}</label>
      {children}
    </div>
  );
}

function subSegStyle(active) {
  return {
    padding: "9px 10px", borderRadius: 7,
    border: active ? "1.5px solid var(--text-1)" : "1px solid var(--border-subtle)",
    background: "var(--bg)",
    color: active ? "var(--text-1)" : "var(--text-2)",
    cursor: "pointer", fontSize: 12, fontWeight: active ? 600 : 500,
    display: "flex", alignItems: "center", justifyContent: "center", gap: 6,
    fontFamily: "inherit", transition: "all 0.12s",
  };
}

function BillsEmpty({ icon, message, sub }) {
  return (
    <div style={{ padding: "40px 20px", textAlign: "center", color: "var(--text-muted)" }}>
      <Icon name={icon} size={26} style={{ marginBottom: 10, color: "var(--text-muted)" }}/>
      <div style={{ fontSize: 13, fontWeight: 500, color: "var(--text-2)", marginBottom: 4 }}>{message}</div>
      <div style={{ fontSize: 12, color: "var(--text-muted)" }}>{sub}</div>
    </div>
  );
}

window.BillsView = BillsView;
