#!/usr/bin/env python

"""Fix missing payment journal entries for purchase with amount_paid set"""

from decimal import Decimal
from datetime import date
from app.core.database import SessionLocal
from app.services.accounting_service import AccountingService
from app.models.accounting import AccountingEntry, JournalEntry, AccountingCode
import uuid

def fix_missing_payment_entry():
    """Create missing payment journal entries for the purchase"""
    db = SessionLocal()
    try:
        # Find the purchase
        from sqlalchemy import text
        result = db.execute(text("""
            SELECT id, branch_id FROM purchases WHERE total_amount = 221616
        """))
        purchase_row = result.first()
        if not purchase_row:
            print("ERROR: Purchase not found")
            return False

        purchase_id = purchase_row[0]
        branch_id = purchase_row[1]
        print(f"Found purchase: {purchase_id}, branch: {branch_id}")

        # Find AP account
        ap_account = db.query(AccountingCode).filter(
            AccountingCode.code == '2110'
        ).first()

        if not ap_account:
            print("ERROR: AP account 2110 not found")
            return False

        print(f"AP Account: {ap_account.code} {ap_account.name}")

        # Find Bank account
        bank_account = db.query(AccountingCode).filter(
            AccountingCode.code == '1100'
        ).first()

        if not bank_account:
            print("ERROR: Bank account 1100 not found")
            return False

        print(f"Bank Account: {bank_account.code} {bank_account.name}")

        # Create AccountingEntry
        accounting_entry = AccountingEntry(
            date_prepared=date.today(),
            date_posted=date.today(),
            particulars=f"Payment for Purchase {purchase_id}",
            book=f"PAYMENT-{purchase_id}",
            status='posted',
            branch_id=branch_id
        )
        db.add(accounting_entry)
        db.flush()

        print(f"\nCreated Accounting Entry: {accounting_entry.id}")

        # Create AP Debit JournalEntry - reduces liability
        ap_debit = JournalEntry(
            accounting_entry_id=accounting_entry.id,
            accounting_code_id=ap_account.id,
            entry_type='debit',
            debit_amount=Decimal('221616'),
            credit_amount=Decimal('0'),
            description='Payment reduces AP liability',
            date=date.today(),
            branch_id=branch_id
        )
        db.add(ap_debit)
        db.flush()
        print(f"AP Debit Entry: {ap_debit.id} - Debit 221,616")

        # Create Bank Credit JournalEntry - reduces bank balance
        bank_credit = JournalEntry(
            accounting_entry_id=accounting_entry.id,
            accounting_code_id=bank_account.id,
            entry_type='credit',
            debit_amount=Decimal('0'),
            credit_amount=Decimal('221616'),
            description='Bank payment outflow',
            date=date.today(),
            branch_id=branch_id
        )
        db.add(bank_credit)
        db.flush()
        print(f"Bank Credit Entry: {bank_credit.id} - Credit 221,616")

        # Flush to ensure IDs are committed
        db.flush()

        # Update GL account balances
        accounting_service = AccountingService(db)
        accounting_service.update_account_balance(ap_account.id)
        accounting_service.update_account_balance(bank_account.id)

        print(f"\nAP Account updated:")
        print(f"  Debits: {ap_account.total_debits}")
        print(f"  Credits: {ap_account.total_credits}")
        print(f"  Balance: {ap_account.balance}")

        print(f"\nBank Account updated:")
        print(f"  Debits: {bank_account.total_debits}")
        print(f"  Credits: {bank_account.total_credits}")
        print(f"  Balance: {bank_account.balance}")

        db.commit()

        print(f"\n*** SUCCESS ***")
        print("Payment journal entries created successfully!")
        print("The 221,616 purchase payment is now recorded in:")
        print("- Accounts Payable (2110): Reduced liability")
        print("- Operating Bank (1100): Reduced bank balance")

        return True

    except Exception as e:
        db.rollback()
        print(f"ERROR: {str(e)}")
        import traceback
        traceback.print_exc()
        return False
    finally:
        db.close()

if __name__ == '__main__':
    success = fix_missing_payment_entry()
    exit(0 if success else 1)
