#!/usr/bin/env bash
# Live balances per bank account, plus a Dolibarr cross-check by fk_account.
#
# Usage:
#   bank-balance.sh
#
# Outputs each bank account (Qonto + Wise) with:
#   - current live balance (from each bank's API)
#   - sum of all Dolibarr payments touching it (per fk_account)
#
# The sum-of-payments isn't the bank balance — it's just the cumulative
# operations Dolibarr has recorded on that account. Useful as a sanity check
# (e.g. "did I record everything?"). The bank-side current balance is
# authoritative.

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BANK_CURL="${SCRIPT_DIR}/bank-curl.sh"
DOL_CURL="${SCRIPT_DIR}/../../dolibarr/scripts/dol-curl.sh"

set -a; source "${SCRIPT_DIR}/../../dolibarr/.env"; set +a
: "${WISE_PROFILE_ID:?bank-balance.sh: WISE_PROFILE_ID not set}"

WORK="$(mktemp -d -t bankbal.XXXXXX)"
trap 'rm -rf "${WORK}"' EXIT

# Bank side
"${BANK_CURL}" qonto /v2/organization                                         > "${WORK}/qonto.json"
"${BANK_CURL}" wise  "/v4/profiles/${WISE_PROFILE_ID}/balances?types=STANDARD" > "${WORK}/wise.json"

# Dolibarr side: bank accounts + payments per invoice
"${DOL_CURL}" /bankaccounts                                                   > "${WORK}/dol_acct.json"
"${DOL_CURL}" '/invoices?limit=500'                                           > "${WORK}/dol_inv.json"
"${DOL_CURL}" '/supplierinvoices?limit=500'                                   > "${WORK}/dol_sup.json"

mkdir -p "${WORK}/dol_pay" "${WORK}/dol_supay"
for id in $(python3 -c "import json,sys; print(' '.join(str(r['id']) for r in json.load(open(sys.argv[1])) if r.get('id')))" "${WORK}/dol_inv.json"); do
  "${DOL_CURL}" "/invoices/${id}/payments" > "${WORK}/dol_pay/${id}.json" 2>/dev/null || echo "[]" > "${WORK}/dol_pay/${id}.json"
done
for id in $(python3 -c "import json,sys; print(' '.join(str(r['id']) for r in json.load(open(sys.argv[1])) if r.get('id')))" "${WORK}/dol_sup.json"); do
  "${DOL_CURL}" "/supplierinvoices/${id}/payments" > "${WORK}/dol_supay/${id}.json" 2>/dev/null || echo "[]" > "${WORK}/dol_supay/${id}.json"
done

python3 - "${WORK}" <<'PY'
import json, os, sys, collections
work = sys.argv[1]

# Bank-side balances
q = json.load(open(os.path.join(work, "qonto.json")))
qonto_accs = (q.get("organization") or {}).get("bank_accounts") or []
wise_bals  = json.load(open(os.path.join(work, "wise.json")))

print("=" * 90)
print(" BANK-SIDE balances (live)")
print("=" * 90)
print(f"  {'bank':<8} {'ref':<20} {'currency':<3} {'balance':>12}  details")
print("  " + "-" * 86)
qonto_total = 0.0
for a in qonto_accs:
    bal = float(a.get("balance") or 0); qonto_total += bal
    iban = (a.get("iban") or "")[-8:]
    print(f"  {'Qonto':<8} {a.get('name','-')[:20]:<20} {a.get('balance_cents_currency','EUR'):<3} {bal:>12.2f}  iban=...{iban}  id={a.get('id','-')[:14]}")
for b in wise_bals:
    amt = (b.get("amount") or {})
    print(f"  {'Wise':<8} {b.get('type','-'):<20} {amt.get('currency','-'):<3} {float(amt.get('value') or 0):>12.2f}  id={b.get('id','-')}")
print()
print(f"  Qonto total: {qonto_total:.2f} EUR")
print(f"  Wise total : {sum(float((b.get('amount') or {}).get('value') or 0) for b in wise_bals):.2f} EUR")
print()

# Dolibarr-side: sum of all payments per fk_account
dol_accts = {str(a["id"]): a for a in json.load(open(os.path.join(work, "dol_acct.json")))}
sums = collections.defaultdict(lambda: {"customer": 0.0, "supplier": 0.0})

inv = {str(r["id"]): r for r in json.load(open(os.path.join(work, "dol_inv.json")))}
for fn in os.listdir(os.path.join(work, "dol_pay")):
    iid = fn[:-5]; i = inv.get(iid)
    if not i: continue
    fka = str(i.get("fk_account") or "?")
    for p in json.load(open(os.path.join(work, "dol_pay", fn))):
        sums[fka]["customer"] += float(p.get("amount") or 0)

sup = {str(r["id"]): r for r in json.load(open(os.path.join(work, "dol_sup.json")))}
for fn in os.listdir(os.path.join(work, "dol_supay")):
    iid = fn[:-5]; s = sup.get(iid)
    if not s: continue
    fka = str(s.get("fk_account") or "?")
    for p in json.load(open(os.path.join(work, "dol_supay", fn))):
        sums[fka]["supplier"] += float(p.get("amount") or 0)

print("=" * 90)
print(" DOLIBARR-SIDE cumulative payments per fk_account")
print("=" * 90)
print(f"  {'fk_account':<10} {'ref':<10} {'label':<30} {'cust paid in':>12} {'sup paid out':>12} {'net':>10}")
print("  " + "-" * 86)
for fka in sorted(sums, key=lambda k: int(k) if k.isdigit() else 99):
    s = sums[fka]
    net = s["customer"] - s["supplier"]
    a = dol_accts.get(fka, {})
    ref = a.get("ref","-")[:10]; label = (a.get("label") or "-")[:30]
    print(f"  {fka:<10} {ref:<10} {label:<30} {s['customer']:>12.2f} {s['supplier']:>12.2f} {net:>10.2f}")
print()
print("# Note: Dolibarr-side numbers are CUMULATIVE since the account started in Dolibarr,")
print("#       not the current bank balance. Mismatch with the bank-side is expected when")
print("#       the account predates Dolibarr or has movements not recorded in Dolibarr")
print("#       (e.g. URSSAF, AI subscriptions — see bank-match.sh BANK-ONLY bucket).")
PY
