#!/usr/bin/env bash
# Per-line TVA breakdown with the country classification needed to choose
# the right CA3 line (E2 export hors UE vs A4 autoliquidation intra-UE vs
# domestic A1).
#
# Usage:
#   tva-line-detail.sh [--year YYYY] [--since YYYY-MM-DD] [--until YYYY-MM-DD]
#
# Pulls each invoice's lines + the thirdparty's country_code to assign each
# line to a CA3 bucket. Useful as the audit trail behind tva-by-month.sh.

set -euo pipefail

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

SINCE=""; UNTIL=""; YEAR=""
while [[ $# -gt 0 ]]; do
  case "$1" in
    --since) SINCE="$2"; shift 2 ;;
    --until) UNTIL="$2"; shift 2 ;;
    --year)  YEAR="$2"; SINCE="$2-01-01"; UNTIL="$2-12-31"; shift 2 ;;
    -h|--help) sed -n '2,12p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
    *) echo "tva-line-detail.sh: unknown arg: $1" >&2; exit 2 ;;
  esac
done

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

"${DOL_CURL}" '/invoices?limit=500&sortfield=t.datef&sortorder=ASC' > "${WORK}/inv.json"

# Per-invoice detail + per-thirdparty country
IDS=$(python3 -c "import json,sys; print(' '.join(str(r['id']) for r in json.load(open(sys.argv[1]))))" "${WORK}/inv.json")
mkdir -p "${WORK}/inv" "${WORK}/tp"
SOCIDS=$(python3 -c "import json,sys; print(' '.join(sorted({str(r.get('socid')) for r in json.load(open(sys.argv[1])) if r.get('socid')})))" "${WORK}/inv.json")
for id in ${IDS};    do "${DOL_CURL}" "/invoices/${id}"     > "${WORK}/inv/${id}.json"; done
for s  in ${SOCIDS}; do "${DOL_CURL}" "/thirdparties/${s}" > "${WORK}/tp/${s}.json"; done

python3 - "${WORK}" "${SINCE}" "${UNTIL}" "${YEAR}" <<'PY'
import json, sys, os, datetime
work, since, until, year_arg = sys.argv[1:5]

# EU member states (excl. FR — FR lines are "domestic")
EU = set("AT BE BG HR CY CZ DK EE FI DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE".split())

tp = {}
for fn in os.listdir(os.path.join(work,"tp")):
    try: d = json.load(open(os.path.join(work,"tp",fn)))
    except json.JSONDecodeError: continue
    tp[fn[:-len(".json")]] = d.get("country_code") or ""

def bucket(country, tx):
    if tx and tx > 0: return f"A1 (domestic {tx}%)"
    if country == "FR": return "A1 (domestic, 0%? check)"
    if country in EU:   return "A4 (autoliquidation intra-UE)"
    if country:         return "E2 (export hors UE)"
    return "(unknown country)"

def in_window(ts):
    if not ts: return False
    d = datetime.date.fromtimestamp(int(ts))
    if since and d < datetime.date.fromisoformat(since): return False
    if until and d > datetime.date.fromisoformat(until): return False
    return True

print(f"{'date':<10}  {'invoice':<24} {'client':<15} {'cnty':<4} {'tx':>5}  {'HT':>10}  {'TVA':>8}  CA3 bucket")
print("-" * 110)
all_lines = []
for fn in sorted(os.listdir(os.path.join(work,"inv"))):
    try: inv = json.load(open(os.path.join(work,"inv",fn)))
    except json.JSONDecodeError: continue
    ts = int(inv.get("date") or 0)
    if not in_window(ts): continue
    dt = datetime.date.fromtimestamp(ts)
    sid = str(inv.get("socid") or "")
    cnty = tp.get(sid, "")
    client = "tp-"+sid
    for line in inv.get("lines") or []:
        tx  = round(float(line.get("tva_tx") or 0), 4)
        ht  = float(line.get("total_ht")  or 0)
        tva = float(line.get("total_tva") or 0)
        buck = bucket(cnty, tx)
        all_lines.append((dt, inv["ref"], client, cnty, tx, ht, tva, buck))
        print(f"{dt}  {inv['ref']:<24} {client:<15} {cnty:<4} {tx:>5.2f}  {ht:>10.2f}  {tva:>8.2f}  {buck}")

print("-" * 110)
# Summary per bucket
import collections
buckets = collections.defaultdict(lambda: {"ht":0.0,"tva":0.0,"n":0})
for r in all_lines:
    b = r[7]
    buckets[b]["ht"] += r[5]; buckets[b]["tva"] += r[6]; buckets[b]["n"] += 1
print()
print("# Aggregated by CA3 bucket:")
for b, s in sorted(buckets.items()):
    print(f"  {b:<35} count={s['n']:>3}  HT={s['ht']:>10.2f}  TVA={s['tva']:>8.2f}")
PY
