#!/usr/bin/env python3
"""Create Facturapi organizations for tenants that don't have one.

Requires FACTURAPI_USER_KEY environment variable (user key with permission to
manage organizations).

Usage:
    export MASTER_DB_URL=postgresql://user:pass@host/nexus_autoparts
    export TENANT_DB_URL_TEMPLATE="postgresql://user:pass@host/{db_name}"
    export FACTURAPI_USER_KEY=sk_user_xxxxxxxxxxxxxxxx
    python3 scripts/setup_facturapi_orgs.py

    # Preview only
    python3 scripts/setup_facturapi_orgs.py --dry-run
"""

import argparse
import os
import sys

POS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "pos")
sys.path.insert(0, POS_DIR)

import psycopg2  # noqa: E402
from services import facturapi_service  # noqa: E402


def get_tenants(master_dsn: str):
    conn = psycopg2.connect(master_dsn)
    try:
        cur = conn.cursor()
        cur.execute(
            """
            SELECT t.id, t.db_name, t.name, t.subdomain
            FROM tenants t
            WHERE t.is_active = true
            ORDER BY t.id
            """
        )
        rows = cur.fetchall()
        cur.close()
        return rows
    finally:
        conn.close()


def get_tenant_fiscal_data(db_name: str, template_dsn: str) -> dict:
    dsn = template_dsn.format(db_name=db_name)
    conn = psycopg2.connect(dsn)
    try:
        cur = conn.cursor()

        cur.execute(
            """
            SELECT key, value FROM tenant_config
            WHERE key IN ('tenant_rfc', 'tenant_razon_social', 'tenant_cp', 'cfdi_regimen_fiscal')
            """
        )
        config = {row[0]: row[1] or "" for row in cur.fetchall()}

        cur.execute(
            """
            SELECT rfc, razon_social, regimen_fiscal, codigo_postal
            FROM branches WHERE is_main = true LIMIT 1
            """
        )
        branch = cur.fetchone()
        if branch:
            config["rfc"] = (branch[0] or config.get("tenant_rfc", "")).strip()
            config["razon_social"] = (branch[1] or config.get("tenant_razon_social", "")).strip()
            config["regimen_fiscal"] = (branch[2] or config.get("cfdi_regimen_fiscal", "")).strip()
            config["cp"] = (branch[3] or config.get("tenant_cp", "")).strip()
        else:
            config["rfc"] = config.get("tenant_rfc", "").strip()
            config["razon_social"] = config.get("tenant_razon_social", "").strip()
            config["regimen_fiscal"] = config.get("cfdi_regimen_fiscal", "").strip()
            config["cp"] = config.get("tenant_cp", "").strip()

        # Existing facturapi keys
        cur.execute(
            """
            SELECT key, value FROM tenant_config
            WHERE key IN ('cfdi_facturapi_org_id', 'cfdi_facturapi_key')
            """
        )
        for key, value in cur.fetchall():
            config[key] = value or ""

        cur.close()
        return config
    finally:
        conn.close()


def save_facturapi_config(db_name: str, template_dsn: str, org_id: str, api_key: str):
    dsn = template_dsn.format(db_name=db_name)
    conn = psycopg2.connect(dsn)
    try:
        cur = conn.cursor()
        cur.execute(
            """
            INSERT INTO tenant_config (key, value) VALUES ('cfdi_facturapi_org_id', %s)
            ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
            """,
            (org_id,),
        )
        cur.execute(
            """
            INSERT INTO tenant_config (key, value) VALUES ('cfdi_facturapi_key', %s)
            ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
            """,
            (api_key,),
        )
        conn.commit()
        cur.close()
    finally:
        conn.close()


def main():
    parser = argparse.ArgumentParser(description="Create Facturapi organizations for tenants")
    parser.add_argument("--dry-run", action="store_true", help="Preview changes without applying")
    args = parser.parse_args()

    master_dsn = os.environ.get("MASTER_DB_URL")
    template_dsn = os.environ.get("TENANT_DB_URL_TEMPLATE")
    user_key = os.environ.get("FACTURAPI_USER_KEY")

    if not master_dsn or not template_dsn:
        print("Set MASTER_DB_URL and TENANT_DB_URL_TEMPLATE", file=sys.stderr)
        sys.exit(1)

    if not user_key:
        print("Set FACTURAPI_USER_KEY (user key required to manage organizations)", file=sys.stderr)
        sys.exit(1)

    tenants = get_tenants(master_dsn)
    if not tenants:
        print("No active tenants found.")
        return

    created = 0
    skipped = 0
    errors = 0

    for tenant_id, db_name, name, _subdomain in tenants:
        print(f"\n[{tenant_id}] {name} ({db_name})")
        try:
            config = get_tenant_fiscal_data(db_name, template_dsn)

            if config.get("cfdi_facturapi_org_id") and config.get("cfdi_facturapi_key"):
                print("  SKIP: already has org_id and key")
                skipped += 1
                continue

            if not config.get("rfc"):
                print("  ERROR: tenant RFC not configured")
                errors += 1
                continue

            print(f"  RFC: {config['rfc']}")
            print(f"  Razon social: {config['razon_social'] or '(will use RFC)'}")

            if args.dry_run:
                print("  DRY-RUN: would create organization")
                continue

            result = facturapi_service.create_organization(config)
            save_facturapi_config(db_name, template_dsn, result["org_id"], result["api_key"])
            print(f"  CREATED: org_id={result['org_id']}")
            created += 1

        except Exception as e:
            print(f"  ERROR: {type(e).__name__}: {str(e)[:200]}")
            errors += 1

    print(f"\nDone. Created: {created} | Skipped: {skipped} | Errors: {errors}")


if __name__ == "__main__":
    main()
