#!/usr/bin/env bash
# arcodange — operational CLI for the Arcodange Dolibarr ERP. Read-only on prod;
# host-guarded WRITE ops on the sandbox via `arcodange sandbox ...`.
#
# Usage: arcodange <command> [subcommand] [args]
#
# Run `arcodange help` for the full command list.
#
# This is a thin dispatcher: every subcommand delegates to a script under
# .claude/skills/<skill>/scripts/. The skills (markdown SKILL.md files)
# remain the source of behaviour documentation; this CLI is the human-
# friendly entry point so you don't have to spell out 5-component paths.

set -euo pipefail

# --- Locate the project root ----------------------------------------------
# Strategy:
#  1. git rev-parse --show-toplevel (works when CWD is inside the repo).
#  2. Walk up from this script's directory to find a sibling .claude/skills.
# Either approach handles being run from a worktree without surprises.

if SROOT=$(git rev-parse --show-toplevel 2>/dev/null) && [[ -d "${SROOT}/.claude/skills" ]]; then
  :
else
  SROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
  if [[ ! -d "${SROOT}/.claude/skills" ]]; then
    echo "arcodange: cannot find project root (no .claude/skills/ found)" >&2
    exit 2
  fi
fi

SKILLS="${SROOT}/.claude/skills"
DOLC="${SKILLS}/dolibarr/scripts/dol-curl.sh"

# --- Help text -----------------------------------------------------------

usage() {
  cat <<'EOF'
arcodange — read-only Arcodange Dolibarr CLI.

USAGE
  arcodange <command> [subcommand] [args...]

COMMANDS

  tva                                French TVA monthly preparation
    collect              [--year|--since|--until]  TVA collectée by month × rate (CA3 A1/A4/E2)
    collect-detail       [--year|--since|--until]  Per-line audit, customer side
    deductible           [--year|--since|--until]  TVA déductible by month × rate (CA3 19/20/17+24)
    deductible-detail    [--year|--since|--until]  Per-line audit, supplier side
    summary              [--year|--since|--until]  Composite CA3-ready monthly summary

  invoice                            Customer invoices (KissMetrics)
    list                 [--since YYYY-MM-DD]      Table of KM invoices with payment state
    audit                <invoice-id>              JSON facts + PDF mandatory-mention audit

  thirdparty                         Clients + suppliers completeness
    audit                <socid>                   Country-aware audit for one thirdparty
    audit-all            [--clients-only|--suppliers-only]   Audit every visible thirdparty

  payments                           Cash receipts (KissMetrics-side)
    state                [--since YYYY-MM-DD]      Per-invoice TTC vs payments reconciliation
    timeline             [--year|--since|--until]  Payment timeline with cumulative balance
    by-month             [--year|--all-clients]    Monthly aggregation

  templates                          Recurring invoice templates
    list                 [--max-id N]              Enumerate templates (probes ids)
    inspect              <template-id>             Full template audit with health checks

  snapshot               [--out FILE|--print-only] Bundle full read-only state into one JSON

  bank                               Bank-side data (Qonto + Wise) + Dolibarr reconciliation
    probe                                          Auth + discovery (org slug, profile id, balance ids)
    qonto-transactions   [--month|--since|--until] Qonto transactions table (incoming + outgoing)
    wise-transactions    [--month|--since|--until|--type|--enrich]  Wise activities (incoming + outgoing)
    match                [--month|--since|--until|--window-days N|--enrich]  Match bank ↔ Dolibarr (split buckets)
    balance                                        Live balances + Dolibarr cross-check per fk_account
    curl                 <qonto|wise> <path>       Raw read-only curl through bank-curl.sh

  email                              Supplier-invoice emails from the Zoho mailbox
    list                 [--folder|--limit|--candidates-only|--all-folders]   List candidates
    inspect              <messageId> [--folder|--save-pdf|--json]   Parse PDFs + draft Dolibarr entry
    curl                 <path>                    Raw read-only curl through zoho-curl.sh

  sandbox                            WRITE ops on erp-sandbox ONLY (host-guarded; JSON on stdin)
    thirdparty                                     Create a client/supplier fiche
    invoice                                        Customer/supplier invoice + product/service lines
    payment                                        Record a règlement (transaction_id=bank tx) → bank_transaction_id
    creditnote                                     Create an avoir — customer or supplier (kind)
    accounts                                       List bank accounts (id/label) to pick account_id
    write                <METHOD> <path> [body]    Raw host-guarded write

  promote                            Replay a reviewed change-set sandbox -> prod (ADR-0003)
    plan                 <manifest.json>           Human-readable review of the change-set
    apply                <manifest.json> [--target sandbox|prod]   Replay it (prod is key+confirm gated)

  whoami                                          GET /users/info — confirm auth
  ping                                            GET /status     — liveness + Dolibarr version
  curl                   <path>                   Raw read-only curl through dol-curl.sh

  help [command]                                  Show this help (or subcommand help)

CREDENTIALS
  Reads .claude/skills/dolibarr/.env (mode 600, gitignored). See
  .claude/skills/dolibarr/README.md for one-time setup.

EXAMPLES
  arcodange ping
  arcodange whoami
  arcodange invoice list
  arcodange invoice audit 12
  arcodange tva summary --year 2026
  arcodange thirdparty audit-all
  arcodange snapshot --out /tmp/erp.json
  echo '{"name":"OVH","role":"supplier"}' | arcodange sandbox thirdparty
EOF
}

# --- Dispatch ------------------------------------------------------------

cmd="${1:-help}"
shift || true

case "${cmd}" in

  tva)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      collect)           exec "${SKILLS}/dolibarr-tva-reconciliation/scripts/tva-by-month.sh"        "$@" ;;
      collect-detail)    exec "${SKILLS}/dolibarr-tva-reconciliation/scripts/tva-line-detail.sh"     "$@" ;;
      deductible)        exec "${SKILLS}/dolibarr-tva-deductible/scripts/deductible-by-month.sh"     "$@" ;;
      deductible-detail) exec "${SKILLS}/dolibarr-tva-deductible/scripts/deductible-line-detail.sh"  "$@" ;;
      summary)           exec "${SKILLS}/dolibarr-tva-summary/scripts/tva-summary.sh"                "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange tva — French TVA monthly preparation.

  collect              TVA collectée by month × rate (CA3 A1/A4/E2)
  collect-detail       Per-line audit, customer side
  deductible           TVA déductible by month × rate (CA3 19/20/17+24)
  deductible-detail    Per-line audit, supplier side
  summary              CA3-ready monthly net summary (collectée − déductible)

All accept --year YYYY, --since YYYY-MM-DD, --until YYYY-MM-DD.
EOF
        ;;
      *) echo "arcodange tva: unknown subcommand '${sub}' (try 'arcodange tva help')" >&2; exit 2 ;;
    esac
    ;;

  invoice)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      list)  exec "${SKILLS}/dolibarr-invoice-audit/scripts/list-km-invoices.sh" "$@" ;;
      audit) exec "${SKILLS}/dolibarr-invoice-audit/scripts/audit-invoice.sh"    "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange invoice — customer (KissMetrics) invoice operations.

  list                 [--since YYYY-MM-DD]   Table of KM invoices with payment state
  audit                <invoice-id>           JSON facts + PDF mandatory-mention audit
EOF
        ;;
      *) echo "arcodange invoice: unknown subcommand '${sub}' (try 'arcodange invoice help')" >&2; exit 2 ;;
    esac
    ;;

  thirdparty)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      audit)     exec "${SKILLS}/dolibarr-thirdparty-completeness/scripts/audit-thirdparty.sh"        "$@" ;;
      audit-all) exec "${SKILLS}/dolibarr-thirdparty-completeness/scripts/audit-all-thirdparties.sh"  "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange thirdparty — clients + suppliers completeness.

  audit                <socid>                 Country-aware audit for one thirdparty
  audit-all            [--clients-only|--suppliers-only]   Audit every visible thirdparty
EOF
        ;;
      *) echo "arcodange thirdparty: unknown subcommand '${sub}'" >&2; exit 2 ;;
    esac
    ;;

  payments)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      state)    exec "${SKILLS}/dolibarr-payments-state/scripts/km-payment-state.sh"    "$@" ;;
      timeline) exec "${SKILLS}/dolibarr-payments-state/scripts/km-payment-timeline.sh" "$@" ;;
      by-month) exec "${SKILLS}/dolibarr-payments-state/scripts/payments-by-month.sh"   "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange payments — KissMetrics cash-receipt tracking.

  state                [--since YYYY-MM-DD]      Per-invoice TTC vs payments reconciliation
  timeline             [--year|--since|--until]  Payment timeline with cumulative balance
  by-month             [--year|--all-clients]    Monthly aggregation
EOF
        ;;
      *) echo "arcodange payments: unknown subcommand '${sub}'" >&2; exit 2 ;;
    esac
    ;;

  templates)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      list)    exec "${SKILLS}/dolibarr-recurring-templates/scripts/list-templates.sh"   "$@" ;;
      inspect) exec "${SKILLS}/dolibarr-recurring-templates/scripts/inspect-template.sh" "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange templates — recurring invoice templates.

  list                 [--max-id N]   Enumerate templates (probes ids)
  inspect              <template-id>  Full audit with health checks
EOF
        ;;
      *) echo "arcodange templates: unknown subcommand '${sub}'" >&2; exit 2 ;;
    esac
    ;;

  snapshot)
    exec "${SKILLS}/dolibarr-data-snapshot/scripts/snapshot.sh" "$@"
    ;;

  bank)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      probe)              exec "${SKILLS}/arcodange-bank-reco/scripts/bank-probe.sh"        "$@" ;;
      qonto-transactions) exec "${SKILLS}/arcodange-bank-reco/scripts/qonto-transactions.sh" "$@" ;;
      wise-transactions)  exec "${SKILLS}/arcodange-bank-reco/scripts/wise-transactions.sh"  "$@" ;;
      match)              exec "${SKILLS}/arcodange-bank-reco/scripts/bank-match.sh"         "$@" ;;
      balance)            exec "${SKILLS}/arcodange-bank-reco/scripts/bank-balance.sh"       "$@" ;;
      curl)
        if [[ $# -lt 2 ]]; then
          echo "arcodange bank curl: usage: bank curl <qonto|wise> <path>" >&2; exit 2
        fi
        exec "${SKILLS}/arcodange-bank-reco/scripts/bank-curl.sh" "$@"
        ;;
      help|-h|--help)
        cat <<'EOF'
arcodange bank — bank-side data (Qonto + Wise) and Dolibarr reconciliation.

  probe                                          Auth + discovery (org slug, profile id, balance ids)
  qonto-transactions   [--month|--since|--until] Qonto transactions table
  wise-transactions    [--month|--since|--until|--type|--enrich]  Wise activities (incoming + outgoing)
  match                [--month|--since|--until|--window-days N]  Match bank ↔ Dolibarr (3 buckets)
  balance                                        Live balances + Dolibarr cross-check per fk_account
  curl                 <qonto|wise> <path>       Raw read-only curl through bank-curl.sh

Requires QONTO_LOGIN, QONTO_SECRET_KEY, QONTO_ORG_SLUG, WISE_API_TOKEN,
WISE_PROFILE_ID in .env. See arcodange-bank-reco/SKILL.md for setup.
EOF
        ;;
      *) echo "arcodange bank: unknown subcommand '${sub}' (try 'arcodange bank help')" >&2; exit 2 ;;
    esac
    ;;

  email)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      list)    exec "${SKILLS}/arcodange-email-ingest/scripts/email-list.sh"    "$@" ;;
      inspect) exec "${SKILLS}/arcodange-email-ingest/scripts/email-inspect.sh" "$@" ;;
      curl)    exec "${SKILLS}/arcodange-email-ingest/scripts/zoho-curl.sh"     "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange email — supplier-invoice ingestion from the Zoho mailbox.

  list                 [--folder PATH|--limit N|--candidates-only|--all-folders]
                       List messages (default: /Inbox/books)
  inspect              <messageId> [--folder PATH|--save-pdf DIR|--json]
                       Parse PDF attachments, propose Dolibarr supplier-invoice draft
  curl                 <path>     Raw read-only call through zoho-curl.sh

Requires ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET, ZOHO_REFRESH_TOKEN, ZOHO_DC in .env.
See arcodange-email-ingest/SKILL.md for OAuth setup.
EOF
        ;;
      *) echo "arcodange email: unknown subcommand '${sub}' (try 'arcodange email help')" >&2; exit 2 ;;
    esac
    ;;

  sandbox)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      thirdparty) exec "${SKILLS}/dolibarr-sandbox-write/scripts/thirdparty-create.sh" "$@" ;;
      invoice)    exec "${SKILLS}/dolibarr-sandbox-write/scripts/invoice-create.sh"    "$@" ;;
      payment)    exec "${SKILLS}/dolibarr-sandbox-write/scripts/payment-record.sh"    "$@" ;;
      creditnote) exec "${SKILLS}/dolibarr-sandbox-write/scripts/creditnote-create.sh" "$@" ;;
      accounts)   exec "${SKILLS}/dolibarr-sandbox-write/scripts/bank-accounts.sh"     "$@" ;;
      write)      exec "${SKILLS}/dolibarr-sandbox-write/scripts/dol-write.sh"          "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange sandbox — WRITE operations against erp-sandbox (rehearsal ONLY).
Every write goes through dol-write.sh, which REFUSES any non-sandbox host.
Each subcommand reads a JSON object on stdin (or a file path arg).

  thirdparty   client/supplier fiche
               echo '{"name":"OVH","role":"supplier"}' | arcodange sandbox thirdparty
  invoice      customer/supplier invoice with product/service lines (+ ref_supplier)
               echo '{"socid":42,"validate":true,"lines":[{"desc":"X","qty":1,"price_ht":100,"tva":20,"type":"service"}]}' | arcodange sandbox invoice
  payment      règlement on a validated invoice
               echo '{"invoice_id":19,"mode":"VIR","account_id":1}' | arcodange sandbox payment
  creditnote   avoir (credit note) referencing a source invoice
               echo '{"socid":42,"source_invoice":19,"validate":true,"lines":[...]}' | arcodange sandbox creditnote
  write        raw host-guarded write   arcodange sandbox write POST /thirdparties '{"name":".."}'

Needs .claude/skills/dolibarr-sandbox-write/.env (DOLIBARR_SANDBOX_URL + _API_KEY).
See dolibarr-sandbox-write/SKILL.md.
EOF
        ;;
      *) echo "arcodange sandbox: unknown subcommand '${sub}' (try 'arcodange sandbox help')" >&2; exit 2 ;;
    esac
    ;;

  promote)
    sub="${1:-help}"; shift || true
    case "${sub}" in
      plan)  exec "${SKILLS}/dolibarr-sandbox-write/scripts/promote-plan.sh"  "$@" ;;
      apply) exec "${SKILLS}/dolibarr-sandbox-write/scripts/promote-apply.sh" "$@" ;;
      help|-h|--help)
        cat <<'EOF'
arcodange promote — replay a reviewed sandbox change-set onto a target.

A manifest is a JSON array of write ops with symbolic refs (@name) instead of
ids, so the same file replays on sandbox or prod (an invoice refs @tp1, its
just-created thirdparty). See dolibarr-sandbox-write/examples/promote-manifest.json.

  plan   <manifest.json>                    Human-readable review of the change-set
  apply  <manifest.json> [--target sandbox|prod]
                                            Replay it (sandbox = rehearse; prod = real)

PROD apply is gated: requires DOLIBARR_PROD_WRITE_KEY + ARCO_PROMOTE_CONFIRM=
I-UNDERSTAND-THIS-WRITES-PROD in the environment (the prod key is never stored).
EOF
        ;;
      *) echo "arcodange promote: unknown subcommand '${sub}' (try 'arcodange promote help')" >&2; exit 2 ;;
    esac
    ;;

  whoami)
    exec "${DOLC}" /users/info
    ;;

  ping)
    exec "${DOLC}" /status
    ;;

  curl)
    if [[ $# -lt 1 ]]; then
      echo "arcodange curl: missing path. Example: arcodange curl /invoices/12" >&2
      exit 2
    fi
    exec "${DOLC}" "$@"
    ;;

  help|-h|--help|"")
    if [[ $# -gt 0 ]]; then
      exec "$0" "$1" help
    fi
    usage
    ;;

  *)
    echo "arcodange: unknown command '${cmd}'" >&2
    echo "  Try 'arcodange help' for the list." >&2
    exit 2
    ;;
esac
