#!/usr/bin/env python3
"""
Complete GL Item Type Seeding Script

Seeds all 28 item type definitions into the database.
For each item type, attempts to link to its configured GL account.
If GL account doesn't exist, will still create the definition but note it in output.
"""

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,
    ItemTypeEnum,
    GLAccountMapping
)
from app.models.accounting import AccountingCode


def main():
    db = SessionLocal()
    print("\n" + "="*80)
    print("COMPLETE ITEM TYPE SEEDING (28 types)")
    print("="*80)

    # Get existing GL accounts from database
    existing_accounts = {}
    accounts = db.query(AccountingCode).all()
    for acc in accounts:
        existing_accounts[acc.code] = acc.id

    print(f"\nDatabase has {len(existing_accounts)} GL accounts available")
    print(f"Mapping defines 28 item types that need seeding\n")

    created_count = 0
    failed_items = []

    # Iterate through all 28 item types in the mapping
    for item_type in ItemTypeEnum:
        mapping = GLAccountMapping.MAPPING.get(item_type, {})
        if not mapping:
            print(f"[SKIP] {item_type:35} - No mapping found")
            failed_items.append((item_type, "No mapping"))
            continue

        # Check if already exists
        existing = db.query(ItemTypeDefinition).filter(
            ItemTypeDefinition.item_type == item_type
        ).first()

        if existing:
            print(f"[EXIST] {item_type:35} - Already in database")
            created_count += 1
            continue

        # Get GL account IDs if they exist
        debit_code = mapping.get('debit_account')
        debit_id = existing_accounts.get(debit_code) if debit_code else None

        # For now, we only create if debit account exists
        if debit_code and not debit_id:
            print(f"[WARN ] {item_type:35} - GL {debit_code} missing in DB")
            failed_items.append((item_type, f"GL {debit_code} missing"))
            continue

        # Create the ItemTypeDefinition
        try:
            item_def = ItemTypeDefinition(
                item_type=item_type,
                name=mapping.get('name', item_type),
                description=mapping.get('description', ''),
                debit_account_id=debit_id,
                is_asset=mapping.get('is_asset', False),
                is_taxable=mapping.get('is_taxable', False),
                useful_life_years=mapping.get('useful_life_years', 0),
                requires_serial_number=mapping.get('requires_serial_number', False),
                is_active=True
            )
            db.add(item_def)
            db.commit()

            gl_info = f"GL {debit_code}" if debit_code else "No GL"
            print(f"[OK   ] {item_type:35} - {gl_info}")
            created_count += 1

        except Exception as e:
            db.rollback()
            print(f"[ERROR] {item_type:35} - {str(e)}")
            failed_items.append((item_type, str(e)))

    # Summary
    print("\n" + "="*80)
    print(f"SUMMARY: Created or verified {created_count} item types")

    if failed_items:
        print(f"\n{len(failed_items)} items could not be created:")
        for item_type, reason in failed_items:
            print(f"  - {item_type:35} ({reason})")

    # Final count
    final_count = db.query(ItemTypeDefinition).count()
    print(f"\nTotal ItemTypeDefinitions in database: {final_count}/28")

    print("\n" + "="*80 + "\n")

    db.close()
    return len(failed_items) == 0


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