#!/usr/bin/env python3
"""
Simple GL Account Routing Validation

This test validates that GLAccountResolver correctly routes purchase items
to GL accounts based on item type.
"""

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

from app.core.database import SessionLocal
from app.models.item_type_mapping import ItemTypeDefinition, GLAccountMapping
from app.models.accounting import AccountingCode


def main():
    """Validate GL routing system"""
    db = SessionLocal()

    print("\n" + "="*80)
    print("GL ACCOUNT ROUTING SYSTEM VALIDATION")
    print("="*80)

    # Check 1: Verify ItemTypeDefinition table exists and is populated
    print("\n[CHECK 1] ItemTypeDefinition Table")
    print("-" * 80)
    count = db.query(ItemTypeDefinition).count()
    print(f"  Records in item_type_definitions table: {count}")

    if count == 0:
        print("  [WARNING] No item types seeded yet")
        print("  Run: python scripts/seed_item_type_definitions_simple.py")
        return False
    else:
        print(f"  [OK] {count} item types available")

    # Check 2: Verify GL accounts are linked
    print("\n[CHECK 2] GL Account Linking")
    print("-" * 80)
    all_have_accounts = True

    definitions = db.query(ItemTypeDefinition).all()
    for defn in definitions:
        if not defn.debit_account:
            print(f"  [WARNING] {defn.item_type} has no debit account")
            all_have_accounts = False
        else:
            print(f"  [OK] {defn.item_type:35} -> GL {defn.debit_account.code} ({defn.debit_account.name})")

    if not all_have_accounts:
        print("  [WARNING] Some item types missing GL accounts")

    # Check 3: Verify GLAccountMapping completeness
    print("\n[CHECK 3] GL Account Mapping Completeness")
    print("-" * 80)
    mappings = GLAccountMapping.MAPPING
    print(f"  Total item types defined in mapping: {len(mappings)}")

    # Check which GL codes are in the mapping
    codes_in_mapping = set()
    for item_type, mapping_dict in mappings.items():
        code = mapping_dict.get('debit_account')
        if code:
            codes_in_mapping.add(code)

    print(f"  Unique GL codes in mapping: {len(codes_in_mapping)}")
    print(f"  Sample GL codes: {sorted(list(codes_in_mapping))[:10]}")

    # Check 4: Verify actual GL accounts exist
    print("\n[CHECK 4] GL Accounts in Database")
    print("-" * 80)

    accounts_exist = 0
    accounts_missing = []

    for code in codes_in_mapping:
        account = db.query(AccountingCode).filter(
            AccountingCode.code == code
        ).first()

        if account:
            accounts_exist += 1
        else:
            accounts_missing.append(code)

    print(f"  GL accounts that exist: {accounts_exist}/{len(codes_in_mapping)}")

    if accounts_missing:
        print(f"  [WARNING] Missing GL codes: {accounts_missing[:10]}")
    else:
        print(f"  [OK] All mapped GL codes exist!")

    # Check 5: Summary
    print("\n[CHECK 5] System Status Summary")
    print("-" * 80)

    if count > 0 and accounts_exist > 0:
        print(f"  [OK] GL Routing System is READY")
        print(f"       - {count} item types defined")
        print(f"       - {accounts_exist} GL accounts linked")
        print(f"\n  Purchase Flow:")
        print(f"    1. User selects item_type when creating purchase item")
        print(f"    2. PurchaseService calls GLAccountResolver.get_debit_account_for_item()")
        print(f"    3. Resolver checks ItemTypeDefinition.debit_account")
        print(f"    4. Journal entry created to correct GL account")
        print(f"\n  Example Routes:")
        print(f"    - Vehicle purchase → GL 1210 (Motor Vehicles)")
        print(f"    - Machinery purchase → GL 1205 (Machinery)")
        print(f"    - Office supplies → GL 5020 (Supplies Expense)")
        return True
    else:
        print(f"  [ERROR] GL Routing System NOT READY")
        if count == 0:
            print(f"    - No item types seeded")
        if accounts_exist == 0:
            print(f"    - No GL accounts in database")
        return False


if __name__ == "__main__":
    try:
        success = main()
        print("\n" + "="*80 + "\n")
        sys.exit(0 if success else 1)
    except Exception as e:
        print(f"\n[ERROR] {str(e)}")
        import traceback
        traceback.print_exc()
        sys.exit(1)
