from django.db import models
from django.utils import timezone
from organisations.models import Organisation, OrganisationBranch
from users.models import User
from django.conf import settings
from customers.models import Customer  # Added import for Customer model


class OrganisationSubAccount(models.Model):
    ACCOUNT_LINES = (
        ('assets', 'Assets'),
        ('liabilities', 'Liabilities'),
        ('capital', 'Capital'),
        ('income', 'Income'),
        ('expenses', 'Costs and Expenses')
    )
    account_name =  models.CharField(max_length=255)
    account_code =  models.CharField(max_length=50)
    report_level =  models.CharField(max_length=25, default='default')
    description =  models.CharField(max_length=255, null=True, blank=True)
    status =  models.CharField(max_length=50, default='active')
    account_type =  models.CharField(max_length=50, default='system')
    parent_id =  models.ForeignKey('OrganisationSubAccount', on_delete=models.CASCADE, related_name='child_accounts', null=True, blank=True)
    account_line =  models.CharField(max_length=25, choices=ACCOUNT_LINES)
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_sub_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)
    account_organisation =  models.ForeignKey(Organisation, on_delete=models.CASCADE, related_name='organisation_accounts')
    allow_sub_accounts =  models.BooleanField(default=True)

    class Meta:
        db_table = 'public\".\"organisaiton_sub_account'
    
    def __str__(self):
        return self.account_name

class InterBranchMapping(models.Model):
    start_branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='inter_branch_start_branch', null=True, blank=True)
    end_branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='inter_branch_end_branch', null=True, blank=True)
    chart = models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='mapping_chart', null=True, blank=True)
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"inter_branch_mapping'
    
    def __str__(self):
        return self.account_name

class Currencies(models.Model):
    currency_name =  models.CharField(max_length=255)
    currency_code =  models.CharField(max_length=50)
    currency_symbol =  models.CharField(max_length=25)
    status =  models.CharField(max_length=50, default='active')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_currencies')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"currencies'
    
    def __str__(self):
        return self.currency_name

class BankAccounts(models.Model):
    bank_name =  models.CharField(max_length=50)
    account_name =  models.CharField(max_length=255)
    account_number =  models.CharField(max_length=255)
    account_currency =  models.CharField(max_length=255, default='UGX')
    account_alias =  models.CharField(max_length=255)
    status =  models.CharField(max_length=50, default='active')
    branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='branch_bank_accounts', null=True, blank=True)
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='bank_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_bank_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"bank_accounts'
    
    def __str__(self):
        return self.account_name

class CashAccounts(models.Model):
    account_name =  models.CharField(max_length=255)
    account_currency  =  models.CharField(max_length=255, default='UGX')
    expenses_limit    =  models.FloatField(default=0)
    withdrawals_limit =  models.FloatField(default=0)
    status =  models.CharField(max_length=50, default='active')
    teller =  models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_cash_account')
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='cash_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_cash_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"cash_accounts'
    
    def __str__(self):
        return self.account_name

class SafeAccounts(models.Model):
    account_name =  models.CharField(max_length=255)
    account_currency =  models.CharField(max_length=255, default='UGX')
    status =  models.CharField(max_length=50, default='active')
    branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='branch_safe_accounts', null=True, blank=True)
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='safe_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_safe_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"safe_accounts'
    
    def __str__(self):
        return self.account_name

class MobileMoneyAccounts(models.Model):
    account_name =  models.CharField(max_length=255)
    telephone_number =  models.CharField(max_length=255)
    account_currency =  models.CharField(max_length=255, default='UGX')
    status =  models.CharField(max_length=50, default='active')
    branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='branch_mobile_money_accounts', null=True, blank=True)
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='mobile_money_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_mobile_money_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"mobile_money_accounts'
    
    def __str__(self):
        return self.account_name

class SystemTransactions(models.Model):
    PAYMENT_OPTIONS = (
        ('offset', 'Offset'),
        ('cheque', 'Cheque'),
        ('cash', 'Cash'),
        ('bank', 'Bank'),
        ('mobile_money', 'Mobile Money'),
        ('settlement', 'Settlement')
    )

    TRANSACTION_TYPES = (
        ('normal', 'Normal'),
        ('revesal', 'Revesal'),
        ('reversed', 'Reversed')
    )
    amount =  models.FloatField()
    heading =  models.TextField()
    credit_chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='credit_account_chart')
    debit_chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='debit_account_chart')
    reference_no =  models.CharField(max_length=255, null=True, blank=True)
    branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='branch_transactions', null=True, blank=True)
    voucher_no =  models.CharField(max_length=255, null=True, blank=True)
    payment_method =  models.CharField(max_length=255, choices=PAYMENT_OPTIONS, default='settlement')
    transaction_type =  models.CharField(max_length=255, choices=TRANSACTION_TYPES, default='normal')
    coment =  models.TextField(null=True, blank=True)
    depositor_name = models.CharField(max_length=255, null=True, blank=True)
    record_date = models.DateTimeField(default = timezone.now)
    added_by =  models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_transactions', null=True, blank=True)
    date_added = models.DateTimeField(default = timezone.now)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_transactions')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"system_transactions'
    
    def __str__(self):
        return self.heading

class CashTransfers(models.Model):
    APPROVAL_STATUSES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
        ('closed', 'Closed'),
        ('reversed', 'Reversed')
    )
    amount =  models.FloatField()
    heading = models.TextField()
    source_chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='transfer_source_chart')
    destination_chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='transfer_destination_chart')
    branch =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='branch_transfers')
    record_date = models.DateTimeField(default = timezone.now)
    added_by =  models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_transafers')
    date_added = models.DateTimeField(default = timezone.now)
    approval_status = models.CharField(max_length=25, choices=APPROVAL_STATUSES, default='pending')
    approved_by =  models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_transafer_approvals', null=True, blank=True)
    date_approved = models.DateTimeField(null=True, blank=True)
    comment =  models.TextField(null=True, blank=True)
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='cash_transfers', null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_cash_transfers')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"cash_transfers'
    
    def __str__(self):
        return self.heading


class CrbActivationRequest(models.Model):
    APPROVAL_STATUSES = (
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected')
    )

    amount = models.FloatField()
    heading = models.TextField(null=True, blank=True)
    debit_chart = models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='crb_debit_chart')
    credit_chart = models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='crb_credit_chart')
    record_date = models.DateTimeField(default=timezone.now)
    added_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='crb_activation_added_by', null=True, blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    status = models.CharField(max_length=25, choices=APPROVAL_STATUSES, default='pending')
    approved_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='crb_activation_approver', null=True, blank=True)
    date_approved = models.DateTimeField(null=True, blank=True)
    comment = models.TextField(null=True, blank=True)
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='crb_activation_reference', null=True, blank=True)
    organisation_branch = models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='crb_activation_branch', null=True, blank=True)
    deleted = models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_crb_activations')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public"."crb_activation_requests'

    def __str__(self):
        return f"CRB Activation Request - {self.id} - {self.status}"

class CreditorAccounts(models.Model):
    account_name =  models.CharField(max_length=255)
    telephone_number =  models.CharField(max_length=255)
    description =  models.TextField(null=True, blank=True)
    organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE, related_name='organisation_creditor')
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='creditor_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_creditor_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"creditor_accounts'
    
    def __str__(self):
        return self.account_name
    

class CreditorSupplies(models.Model):
    creditor = models.ForeignKey(CreditorAccounts, on_delete=models.CASCADE, related_name='supplies_creditor')
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='credit_transaction')
    maturity_date =  models.DateTimeField(default = timezone.now)
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_creditor_supplies')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"credit_supplies'
    
    def __str__(self):
        return self.reference_transaction.heading
    
class CreditorPayments(models.Model):
    supply = models.ForeignKey(CreditorSupplies, on_delete=models.CASCADE, related_name='supplies_payment')
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='supplies_payment_transaction')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_creditor_payments')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"creditor_payments'
    
    def __str__(self):
        return self.reference_transaction.heading
    
class DebtorAccounts(models.Model):
    account_name =  models.CharField(max_length=255)
    telephone_number =  models.CharField(max_length=255)
    description =  models.TextField(null=True, blank=True)
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='debtor_accounts', null=True, blank=True)
    organisation = models.ForeignKey(Organisation, on_delete=models.CASCADE, related_name='organisation_debtor')
    chart =  models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='debtor_account_chart')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_debtor_accounts')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"debtor_accounts'
    
    def __str__(self):
        return self.account_name
    
class DebtorSupplies(models.Model):
    debtor = models.ForeignKey(DebtorAccounts, on_delete=models.CASCADE, related_name='supplies_debtor')
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='debtor_transaction')
    maturity_date =  models.DateTimeField(default = timezone.now)
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_debtor_supplies')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"debtor_supplies'
    
    def __str__(self):
        return self.reference_transaction.heading
    
class DebtorPayments(models.Model):
    supply = models.ForeignKey(DebtorSupplies, on_delete=models.CASCADE, related_name='debtor_payment')
    reference_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='debtor_payment_transaction')
    date_added = models.DateTimeField(default = timezone.now)
    added_by = models.BigIntegerField(null=True, blank=True)
    deleted =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_debtor_payments')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"debtor_payments'
    
    def __str__(self):
        return self.reference_transaction.heading
    
class InterBranchTransactions(models.Model):
    source_transaction      = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='source_transaction')
    destination_transaction = models.ForeignKey(SystemTransactions, on_delete=models.CASCADE, related_name='destination_transaction')
    date_added = models.DateTimeField(default = timezone.now)
    added_by   = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='interbranch_added_by',null=True, blank=True)
    deleted    =  models.BooleanField(default=False)
    deleted_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name='deleted_inter_branch_transactions')
    deleted_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        db_table = 'public\".\"inter_branch_transactions'

class PendingExpenses(models.Model):
    STATUSES = (
        ('Approved', 'Approved'),
        ('Pending', 'Pending'),
        ('Declined', 'Declined')
    )
    heading      =  models.TextField()
    amount       =  models.FloatField()
    voucher_no   =  models.CharField(max_length=50,null=True, blank=True)
    status       =  models.CharField(max_length=50, choices=STATUSES, default='Pending')
    comment       =  models.TextField(null=True, blank=True)
    date_added   = models.DateTimeField(default = timezone.now)
    last_updated = models.DateTimeField(null=True, blank=True)
    record_date  = models.DateTimeField(default = timezone.now)
    payment_method   =  models.CharField(max_length=50)
    added_by         =  models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='expense_added_by',null=True, blank=True)
    last_updated_by  =  models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='expense_approved_by',null=True, blank=True)
    credit_chart     = models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='expense_credit_chart', null=True, blank=True)
    debit_chart      = models.ForeignKey(OrganisationSubAccount, on_delete=models.CASCADE, related_name='expense_debit_chart', null=True, blank=True)
    branch           =  models.ForeignKey(OrganisationBranch, on_delete=models.CASCADE, related_name='current_branch', null=True, blank=True)
    

    
    class Meta:
        db_table = 'public\".\"pending_expenses'


class SystemTransactionsBackup(models.Model):
    PAYMENT_OPTIONS = (
        ('offset', 'Offset'),
        ('cheque', 'Cheque'),
        ('cash', 'Cash'),
        ('bank', 'Bank'),
        ('mobile_money', 'Mobile Money'),
        ('settlement', 'Settlement')
    )

    TRANSACTION_TYPES = (
        ('normal', 'Normal'),
        ('revesal', 'Revesal'),
        ('reversed', 'Reversed')
    )
    amount =  models.FloatField()
    heading =  models.TextField()
    credit_chart =  models.BigIntegerField(null=True, blank=True)
    debit_chart =  models.BigIntegerField(null=True, blank=True)
    reference_no =  models.CharField(max_length=255, null=True, blank=True)
    branch =  models.BigIntegerField(null=True, blank=True)
    voucher_no =  models.CharField(max_length=255, null=True, blank=True)
    payment_method =  models.CharField(max_length=50,null=True, blank=True)
    transaction_type = models.CharField(max_length=50,null=True, blank=True)
    coment =  models.TextField(null=True, blank=True)
    record_date = models.DateTimeField(default = timezone.now)
    added_by =  models.BigIntegerField(null=True, blank=True)
    date_added = models.DateTimeField(default = timezone.now)
    deleted =  models.BooleanField(default=False)

    class Meta:
        db_table = 'public\".\"system_transaction_back_up'
    
    def __str__(self):
        return self.heading
