#!/usr/bin/env bash
# List Qonto transactions for a period, on one bank account.
#
# Usage:
#   qonto-transactions.sh [--since YYYY-MM-DD] [--until YYYY-MM-DD]
#                         [--account <id>]        # default: first active account
#                         [--month YYYY-MM]
#                         [--side credit|debit]   # filter
#                         [--json]                # raw JSON, no table
#
# Output: a compact table — date | side | amount | currency | op type | label.
# Pagination is followed automatically.

set -euo pipefail

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

SINCE=""; UNTIL=""; MONTH=""; ACCOUNT=""; SIDE=""; FMT="table"
while [[ $# -gt 0 ]]; do
  case "$1" in
    --since)   SINCE="$2"; shift 2 ;;
    --until)   UNTIL="$2"; shift 2 ;;
    --month)   MONTH="$2"; shift 2 ;;
    --account) ACCOUNT="$2"; shift 2 ;;
    --side)    SIDE="$2"; shift 2 ;;
    --json)    FMT="json"; shift ;;
    -h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "qonto-transactions.sh: unknown arg: $1" >&2; exit 2 ;;
  esac
done

# Default window: --month overrides --since/--until; otherwise last 90 days.
if [[ -n "${MONTH}" ]]; then
  SINCE="${MONTH}-01"
  # Last day of month — works for any month using python
  UNTIL="$(python3 -c "import datetime,calendar; y,m=map(int,'${MONTH}'.split('-')); print(f'{y:04d}-{m:02d}-{calendar.monthrange(y,m)[1]:02d}')")"
fi
[[ -z "${SINCE}" ]] && SINCE="$(python3 -c "import datetime; print((datetime.date.today()-datetime.timedelta(days=90)).strftime('%Y-%m-%d'))")"
[[ -z "${UNTIL}" ]] && UNTIL="$(python3 -c "import datetime; print(datetime.date.today().strftime('%Y-%m-%d'))")"

# Discover default account if not specified
if [[ -z "${ACCOUNT}" ]]; then
  TMP_ORG=$(mktemp -t qontoorg.XXXXXX.json)
  trap 'rm -f "${TMP_ORG}"' EXIT
  "${BANK_CURL}" qonto /v2/organization > "${TMP_ORG}"
  ACCOUNT=$(python3 -c "
import json, sys
d = json.load(open(sys.argv[1]))
accs = (d.get('organization') or {}).get('bank_accounts') or []
active = [a for a in accs if a.get('status') == 'active']
if not active: sys.exit('no active account')
print(active[0]['id'])
" "${TMP_ORG}")
fi

# Paginate
TMP_ALL=$(mktemp -t qontoall.XXXXXX.json)
trap 'rm -f "${TMP_ORG:-/dev/null}" "${TMP_ALL}"' EXIT
echo '[]' > "${TMP_ALL}"

page=1
while :; do
  TMP_PAGE=$(mktemp -t qontop.XXXXXX.json)
  Q="bank_account_id=${ACCOUNT}&settled_at_from=${SINCE}T00:00:00Z&settled_at_to=${UNTIL}T23:59:59Z&per_page=100&current_page=${page}"
  "${BANK_CURL}" qonto "/v2/transactions?${Q}" > "${TMP_PAGE}"
  # Merge transactions into the all-array
  python3 - "${TMP_ALL}" "${TMP_PAGE}" <<'PY'
import json, sys
all_arr = json.load(open(sys.argv[1]))
page    = json.load(open(sys.argv[2]))
all_arr.extend(page.get("transactions") or [])
json.dump(all_arr, open(sys.argv[1], "w"))
PY
  NEXT=$(python3 -c "
import json, sys
d = json.load(open(sys.argv[1]))
m = d.get('meta') or {}
print(m.get('next_page') or '')
" "${TMP_PAGE}")
  rm -f "${TMP_PAGE}"
  [[ -z "${NEXT}" || "${NEXT}" == "None" ]] && break
  page=$((page+1))
done

if [[ "${FMT}" == "json" ]]; then
  cat "${TMP_ALL}"
  exit 0
fi

python3 - "${TMP_ALL}" "${SIDE}" "${SINCE}" "${UNTIL}" "${ACCOUNT}" <<'PY'
import json, sys
txs = json.load(open(sys.argv[1]))
side_filter, since, until, account = sys.argv[2:6]
if side_filter:
    txs = [t for t in txs if t.get("side") == side_filter]
txs.sort(key=lambda t: t.get("settled_at") or "")

print(f"# Qonto transactions on account {account[:8]}...  ({since} → {until})")
print()
print(f"{'date':<10}  {'side':<6} {'amount':>10}  {'cur':<3} {'op':<14} {'label':<40}")
print("-" * 100)
total_credit = total_debit = 0.0
for t in txs:
    dt = (t.get("settled_at") or "")[:10]
    amt = float(t.get("amount") or 0)
    side = t.get("side") or "-"
    op = (t.get("operation_type") or "-")[:14]
    label = (t.get("label") or "-")[:40]
    cur = t.get("currency") or "-"
    print(f"{dt:<10}  {side:<6} {amt:>10.2f}  {cur:<3} {op:<14} {label:<40}")
    if side == "credit": total_credit += amt
    if side == "debit":  total_debit  += amt
print("-" * 100)
print(f"# {len(txs)} txn(s) — credit total: {total_credit:.2f}, debit total: {total_debit:.2f}, net: {total_credit - total_debit:+.2f}")
PY
