#!/usr/bin/env python3
"""Test FASE 3 improvements:
- Multi-sucursal sync (#1)
- Reorder alerts (#7)
- Warranty / RMA (#10)
"""

import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

os.environ.setdefault('MASTER_DB_URL', 'postgresql://postgres@/nexus_autoparts')
os.environ.setdefault('TENANT_DB_URL_TEMPLATE', 'postgresql://postgres@/{db_name}')
os.environ.setdefault('POS_JWT_SECRET', 'test-secret-12345678901234567890123456789012')

from services.inventory_engine import get_stock, record_transfer
from services.reorder_engine import generate_alerts, list_alerts, suggest_po_from_alerts
from services.warranty_engine import (
    register_warranty, create_claim, resolve_claim, get_warranty, get_claim, list_claims
)
from tenant_db import get_tenant_conn_by_dbname

RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RESET = '\033[0m'


def print_result(name, passed, detail=""):
    status = f"{GREEN}PASS{RESET}" if passed else f"{RED}FAIL{RESET}"
    print(f"  [{status}] {name}" + (f" — {detail}" if detail else ""))


def get_test_inventory(conn):
    cur = conn.cursor()
    cur.execute("""
        SELECT id, part_number, name, branch_id, min_stock, max_stock
        FROM inventory WHERE is_active = true LIMIT 1
    """)
    row = cur.fetchone()
    cur.close()
    return row


def get_branches(conn):
    cur = conn.cursor()
    cur.execute("SELECT id, name FROM branches WHERE is_active = true LIMIT 2")
    rows = cur.fetchall()
    cur.close()
    return rows


def main():
    print("=" * 60)
    print("FASE 3: Multi-sucursal + Alertas + Garantías — VALIDATION")
    print("=" * 60)

    passed = 0
    failed = 0
    conn = get_tenant_conn_by_dbname('tenant_acct_test')
    inv = get_test_inventory(conn)
    branches = get_branches(conn)

    if not inv:
        print(f"\n{RED}No inventory items — aborting{RESET}")
        return passed, failed
    if len(branches) < 2:
        print(f"\n{YELLOW}Only 1 branch — multi-branch tests limited{RESET}")

    inv_id, part_num, inv_name, branch_id, min_stock, max_stock = inv
    branch_a = branches[0][0] if branches else branch_id
    branch_b = branches[1][0] if len(branches) > 1 else branch_a

    # Get or create a valid customer_id
    cur = conn.cursor()
    cur.execute("SELECT id FROM customers LIMIT 1")
    cust_row = cur.fetchone()
    if not cust_row:
        cur.execute("""
            INSERT INTO customers (name, phone, branch_id, is_active)
            VALUES ('Cliente Test', '555-0000', %s, true)
            RETURNING id
        """, (branch_id,))
        customer_id = cur.fetchone()[0]
        conn.commit()
    else:
        customer_id = cust_row[0]
    cur.close()

    # ═══════════════════════════════════════════════════════════════════════
    # MULTI-SUCURSAL
    # ═══════════════════════════════════════════════════════════════════════
    print("\n[MULTI-SUCURSAL]")

    # Test 1: Stock by branch query
    try:
        cur = conn.cursor()
        cur.execute("""
            SELECT b.id, b.name, COALESCE(SUM(io.quantity), 0)
            FROM branches b
            LEFT JOIN inventory_operations io ON io.branch_id = b.id AND io.inventory_id = %s
            WHERE b.is_active = true GROUP BY b.id ORDER BY b.name
        """, (inv_id,))
        rows = cur.fetchall()
        cur.close()
        if rows:
            print_result("Stock by branch", True, f"{len(rows)} branches")
            passed += 1
        else:
            print_result("Stock by branch", False, "no data")
            failed += 1
    except Exception as e:
        print_result("Stock by branch", False, str(e))
        failed += 1

    # Test 2: Transfer between branches
    try:
        if branch_a != branch_b:
            stock_before_a = get_stock(conn, inv_id, branch_a)
            stock_before_b = get_stock(conn, inv_id, branch_b)
            record_transfer(conn, inv_id, branch_a, branch_b, 2, notes="Test transfer")
            conn.commit()
            stock_after_a = get_stock(conn, inv_id, branch_a)
            stock_after_b = get_stock(conn, inv_id, branch_b)
            if stock_after_a == stock_before_a - 2 and stock_after_b == stock_before_b + 2:
                print_result("Transfer", True, f"2 uds de {branch_a} a {branch_b}")
                passed += 1
            else:
                print_result("Transfer", False, f"stock mismatch A:{stock_before_a}->{stock_after_a} B:{stock_before_b}->{stock_after_b}")
                failed += 1
        else:
            print_result("Transfer", True, "SKIP (solo 1 sucursal)")
            passed += 1
    except Exception as e:
        conn.rollback()
        print_result("Transfer", False, str(e))
        failed += 1

    # Test 3: Price sync
    try:
        cur = conn.cursor()
        cur.execute("UPDATE inventory SET price_1 = 999.99 WHERE id = %s", (inv_id,))
        conn.commit()
        cur.execute("""
            UPDATE inventory SET price_1 = 999.99, price_2 = 888.88, price_3 = 777.77
            WHERE part_number = (SELECT part_number FROM inventory WHERE id = %s)
              AND id != %s
        """, (inv_id, inv_id))
        synced = cur.rowcount
        conn.commit()
        cur.close()
        print_result("Price sync", True, f"{synced} items actualizados")
        passed += 1
    except Exception as e:
        conn.rollback()
        print_result("Price sync", False, str(e))
        failed += 1

    # ═══════════════════════════════════════════════════════════════════════
    # ALERTAS DE REORDER
    # ═══════════════════════════════════════════════════════════════════════
    print("\n[ALERTAS DE REORDER]")

    # Test 4: Generate alerts
    try:
        # Ensure min_stock is set for our test item so it generates an alert
        cur = conn.cursor()
        cur.execute("UPDATE inventory SET min_stock = 1000, reorder_point = 500 WHERE id = %s", (inv_id,))
        conn.commit()
        cur.close()

        result = generate_alerts(conn, branch_id=branch_id, auto_notify=False)
        conn.commit()

        # Accept either new alerts created or valid empty result (deduplication)
        if isinstance(result, dict) and 'created' in result:
            print_result("Generate alerts", True, f"{result['created']} alertas ({result['by_type']})")
            passed += 1
        else:
            print_result("Generate alerts", False, "resultado inesperado")
            failed += 1
    except Exception as e:
        conn.rollback()
        print_result("Generate alerts", False, str(e))
        failed += 1

    # Test 5: List alerts
    try:
        alerts = list_alerts(conn, status='open', branch_id=branch_id, limit=10)
        if alerts:
            print_result("List alerts", True, f"{len(alerts)} alertas abiertas")
            passed += 1
        else:
            print_result("List alerts", False, "no hay alertas")
            failed += 1
    except Exception as e:
        print_result("List alerts", False, str(e))
        failed += 1

    # Test 6: Suggest PO
    try:
        suggestion = suggest_po_from_alerts(conn, branch_id=branch_id)
        if suggestion and suggestion.get('items'):
            print_result("Suggest PO", True, f"{len(suggestion['items'])} items sugeridos")
            passed += 1
        else:
            print_result("Suggest PO", False, "sin sugerencias")
            failed += 1
    except Exception as e:
        print_result("Suggest PO", False, str(e))
        failed += 1

    # ═══════════════════════════════════════════════════════════════════════
    # GARANTÍAS / RMA
    # ═══════════════════════════════════════════════════════════════════════
    print("\n[GARANTÍAS / RMA]")

    # Test 7: Register warranty
    try:
        if not customer_id:
            print_result("Register warranty", True, "SKIP (no customers)")
            passed += 1
            w_id = None
        else:
            w_id = register_warranty(
                conn, sale_id=1, sale_item_id=1, inventory_id=inv_id,
                customer_id=customer_id, warranty_months=12, part_number=part_num, name=inv_name
            )
        conn.commit()
        print_result("Register warranty", True, f"id={w_id}")
        passed += 1
    except Exception as e:
        conn.rollback()
        print_result("Register warranty", False, str(e))
        failed += 1
        w_id = None
        customer_id = None

    # Test 8: Get warranty
    try:
        if w_id:
            w = get_warranty(conn, w_id)
            if w and w['status'] == 'active':
                print_result("Get warranty", True, f"status={w['status']}, meses={w['warranty_months']}")
                passed += 1
            else:
                print_result("Get warranty", False, "datos incorrectos")
                failed += 1
        else:
            print_result("Get warranty", False, "no warranty id")
            failed += 1
    except Exception as e:
        print_result("Get warranty", False, str(e))
        failed += 1

    # Test 9: Create claim
    try:
        if w_id:
            claim_id = create_claim(conn, w_id, "El articulo presenta falla de fabrica", notes="Test claim")
            conn.commit()
            print_result("Create claim", True, f"id={claim_id}")
            passed += 1
        else:
            print_result("Create claim", False, "no warranty")
            failed += 1
    except Exception as e:
        conn.rollback()
        print_result("Create claim", False, str(e))
        failed += 1

    # Test 10: Resolve claim
    try:
        if w_id and claim_id:
            ok = resolve_claim(conn, claim_id, 'replaced', replacement_inventory_id=inv_id, notes="Reemplazado")
            conn.commit()
            if ok:
                c = get_claim(conn, claim_id)
                if c and c['resolution'] == 'replaced':
                    print_result("Resolve claim", True, f"resolution={c['resolution']}")
                    passed += 1
                else:
                    print_result("Resolve claim", False, "no se actualizo")
                    failed += 1
            else:
                print_result("Resolve claim", False, "resolve fallo")
                failed += 1
        else:
            print_result("Resolve claim", False, "no claim id")
            failed += 1
    except Exception as e:
        conn.rollback()
        print_result("Resolve claim", False, str(e))
        failed += 1

    # Test 11: List claims
    try:
        claims = list_claims(conn, status='resolved', limit=10)
        print_result("List claims", True, f"{len(claims)} claims")
        passed += 1
    except Exception as e:
        print_result("List claims", False, str(e))
        failed += 1

    conn.close()

    # ── Summary ─────────────────────────────────────────────────
    print("\n" + "=" * 60)
    print(f"RESULTS: {GREEN}{passed} passed{RESET}, {RED}{failed} failed{RESET}")
    print("=" * 60)
    return passed, failed


if __name__ == '__main__':
    passed, failed = main()
    sys.exit(0 if failed == 0 else 1)
