# from decimal import Decimal
# from django.contrib.auth.models import AbstractUser
# from django.core.validators import MinValueValidator, MaxValueValidator
# from django.db import models
# from django.utils import timezone


# class User(AbstractUser):
#     class Roles(models.TextChoices):
#         ADMIN = "ADMIN", "Admin"
#         ACCOUNTANT = "ACCOUNTANT", "Accountant"
#         BUSINESS = "BUSINESS", "Business"
#         INVESTOR = "INVESTOR", "Investor"

#     email = models.EmailField(unique=True)
#     role = models.CharField(max_length=20, choices=Roles.choices)
#     phone = models.CharField(max_length=30, blank=True)
#     image = models.ImageField(upload_to="users/profile/", blank=True, null=True)
#     is_active = models.BooleanField(default=True)

#     def __str__(self):
#         return f"{self.username} ({self.role})"


# class SoftDeleteModel(models.Model):
#     deleted_at = models.DateTimeField(null=True, blank=True, db_index=True)

#     class Meta:
#         abstract = True

#     def soft_delete(self):
#         self.deleted_at = timezone.now()
#         self.save(update_fields=["deleted_at"])

#     def restore(self):
#         self.deleted_at = None
#         self.save(update_fields=["deleted_at"])


# class Business(SoftDeleteModel):
#     user = models.OneToOneField(
#         User,
#         on_delete=models.PROTECT,
#         related_name="business_profile",
#         null=True,
#         blank=True
#     )

#     name = models.CharField(max_length=255)
#     email = models.EmailField(blank=True)
#     location = models.CharField(max_length=500, blank=True)

#     owner_name = models.CharField(max_length=255)
#     owner_aadhar = models.CharField(max_length=32, blank=True)
#     owner_pan = models.CharField(max_length=20, blank=True)
#     owner_mobile = models.CharField(max_length=30, blank=True)
#     owner_sex = models.CharField(max_length=30, blank=True)
#     owner_photo = models.ImageField(
#         upload_to="businesses/owners/",
#         blank=True,
#         null=True
#     )
#     business_photo = models.ImageField(
#         upload_to="businesses/business/",
#         blank=True,
#         null=True
#     )
#     created_by = models.ForeignKey(
#         User,
#         on_delete=models.PROTECT,
#         related_name="businesses_created"
#     )
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-created_at"]

#     def __str__(self):
#         return self.name


# class BusinessBankDetail(models.Model):
#     business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="bank_detail_fields")
#     key = models.CharField(max_length=100)
#     value = models.TextField(blank=True)

#     class Meta:
#         ordering = ["id"]

#     def __str__(self):
#         return f"{self.key}: {self.value}"


# class BusinessDetailField(models.Model):
#     business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="detail_fields")
#     key = models.CharField(max_length=100)
#     value = models.TextField(blank=True)

#     class Meta:
#         ordering = ["id"]

#     def __str__(self):
#         return f"{self.key}: {self.value}"


# class BusinessDocument(models.Model):
#     business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="uploaded_documents")
#     title = models.CharField(max_length=255)
#     file = models.FileField(upload_to="businesses/documents/")
#     uploaded_by = models.ForeignKey(User, on_delete=models.PROTECT)
#     created_at = models.DateTimeField(auto_now_add=True)

#     def __str__(self):
#         return self.title


# class Investor(SoftDeleteModel):
#     user = models.OneToOneField(
#         User, on_delete=models.PROTECT, related_name="investor_profile",
#         null=True, blank=True
#     )
#     name = models.CharField(max_length=255)
#     email = models.EmailField(blank=True)
#     mobile = models.CharField(max_length=30, blank=True)
#     image = models.ImageField(upload_to="investors/profile/", blank=True, null=True)
#     other_details = models.TextField(blank=True)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="investors_created")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-created_at"]

#     def __str__(self):
#         return self.name


# class InvestorDetailField(models.Model):
#     class Sections(models.TextChoices):
#         IDENTITY = "IDENTITY", "Identity"
#         BANK = "BANK", "Bank"
#         NOMINEE = "NOMINEE", "Nominee"

#     investor = models.ForeignKey(Investor, on_delete=models.CASCADE, related_name="detail_fields")
#     section = models.CharField(max_length=20, choices=Sections.choices)
#     key = models.CharField(max_length=100)
#     value = models.TextField(blank=True)

#     class Meta:
#         ordering = ["section", "id"]
#         indexes = [models.Index(fields=["investor", "section"])]

#     def __str__(self):
#         return f"{self.section}: {self.key}: {self.value}"


# class InvestorDocument(models.Model):
#     class Sections(models.TextChoices):
#         IDENTITY = "IDENTITY", "Identity"
#         BANK = "BANK", "Bank"
#         NOMINEE = "NOMINEE", "Nominee"
#         OTHER = "OTHER", "Other"

#     investor = models.ForeignKey(Investor, on_delete=models.CASCADE, related_name="uploaded_documents")
#     section = models.CharField(max_length=20, choices=Sections.choices, default=Sections.OTHER)
#     title = models.CharField(max_length=255)
#     file = models.FileField(upload_to="investors/documents/")
#     uploaded_by = models.ForeignKey(User, on_delete=models.PROTECT)
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["-created_at"]

#     def __str__(self):
#         return self.title


# class AccountantDetailField(models.Model):
#     accountant = models.ForeignKey(
#         User, on_delete=models.CASCADE, related_name="accountant_detail_fields"
#     )
#     key = models.CharField(max_length=100)
#     value = models.TextField(blank=True)

#     class Meta:
#         ordering = ["id"]

#     def __str__(self):
#         return f"{self.key}: {self.value}"


# class AccountantDocument(models.Model):
#     accountant = models.ForeignKey(
#         User, on_delete=models.CASCADE, related_name="accountant_documents"
#     )
#     title = models.CharField(max_length=255)
#     file = models.FileField(upload_to="accountants/identity/")
#     uploaded_by = models.ForeignKey(
#         User, on_delete=models.PROTECT, related_name="accountant_documents_uploaded"
#     )
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["-created_at"]

#     def __str__(self):
#         return self.title


# class Scheme(SoftDeleteModel):
#     class Categories(models.TextChoices):
#         SILVER = "SILVER", "Silver"
#         GOLD = "GOLD", "Gold"
#         PLATINUM = "PLATINUM", "Platinum"
#         DIAMOND = "DIAMOND", "Diamond"

#     category = models.CharField(max_length=20, choices=Categories.choices)
#     name = models.CharField(max_length=255)
#     description = models.TextField(blank=True)
#     tenure_months = models.PositiveIntegerField()
#     annual_interest_rate = models.DecimalField(
#         max_digits=7, decimal_places=4,
#         validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
#     )
#     penalty_rate = models.DecimalField(
#         max_digits=7, decimal_places=4, default=Decimal("0"),
#         validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
#     )
#     withdrawal_type = models.CharField(
#         max_length=40,
#         default="MONTHLY_WITHDRAWAL",
#         blank=True,
#     )
#     compounding_frequency = models.CharField(max_length=30, blank=True)
#     rules = models.JSONField(default=list, blank=True)
#     is_active = models.BooleanField(default=True)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="schemes_created")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["category", "tenure_months", "name"]

#     def __str__(self):
#         return f"{self.category} - {self.name} - {self.tenure_months} months - {self.annual_interest_rate}% p.a."


# class KuberBusinessInvestment(SoftDeleteModel):
#     class InvestmentTypes(models.TextChoices):
#         ORDINARY = "ORDINARY", "Ordinary"
#         EQUITY_SHARE = "EQUITY_SHARE", "Equity Share"

#     business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="kuber_investments")
#     investment_type = models.CharField(
#         max_length=20,
#         choices=InvestmentTypes.choices,
#         default=InvestmentTypes.ORDINARY,
#     )
#     amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))])
#     annual_rate = models.DecimalField(
#         max_digits=7, decimal_places=4,
#         validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
#     )
#     # Locked at the time an Equity Share investment is created. The current
#     # principal/value is always calculated from the latest Balance Sheet
#     # Total Equity multiplied by this percentage.
#     equity_share_percentage = models.DecimalField(
#         max_digits=9, decimal_places=6, null=True, blank=True,
#         validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
#     )
#     investment_date = models.DateField(default=timezone.localdate)
#     maturity_date = models.DateField(null=True, blank=True)
#     notes = models.TextField(blank=True)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="kuber_business_investments_created")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-investment_date"]

#     def __str__(self):
#         return f"{self.business} / {self.amount} / {self.annual_rate}% p.a."


# class Investment(SoftDeleteModel):
#     class Status(models.TextChoices):
#         ACTIVE = "ACTIVE", "Active"
#         MATURED = "MATURED", "Matured"
#         CLOSED = "CLOSED", "Closed"
#         CANCELLED = "CANCELLED", "Cancelled"

#     investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="investments")
#     business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="investments")
#     scheme = models.ForeignKey(Scheme, on_delete=models.PROTECT, related_name="investments")
#     # One-time principal for Silver/Gold/Diamond. Platinum uses actual recurring contributions.
#     amount = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True,
#                                  validators=[MinValueValidator(Decimal("0.01"))])
#     # Only used by Platinum; it is set on the individual investment, never on Scheme.
#     monthly_installment = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True,
#                                               validators=[MinValueValidator(Decimal("0.01"))])
#     # Copied from the selected scheme at investment creation; admin does not manually enter it.
#     investor_annual_rate = models.DecimalField(
#         max_digits=7, decimal_places=4,
#         validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
#     )
#     investment_date = models.DateField(default=timezone.localdate)
#     maturity_date = models.DateField(null=True, blank=True)
#     status = models.CharField(max_length=20, choices=Status.choices, default=Status.ACTIVE)
#     terms_snapshot = models.JSONField(default=dict, blank=True)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="investments_created")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-investment_date"]

#     def __str__(self):
#         amount = self.monthly_installment if self.scheme.category == Scheme.Categories.PLATINUM else self.amount
#         suffix = "/month" if self.scheme.category == Scheme.Categories.PLATINUM else ""
#         return f"{self.investor.name} -> {self.business.name} ({amount}{suffix})"


# class BalanceSheet(SoftDeleteModel):
#     """Structured balance sheet entered through the portal form.

#     Monetary values are stored as decimals; totals are calculated properties so
#     users cannot accidentally save inconsistent total figures.
#     """

#     business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="balance_sheets")
#     statement_date = models.DateField()

#     # Assets
#     cash_in_hand = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     bank_balance = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     accounts_receivable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     inventory = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     prepaid_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     other_current_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     fixed_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     accumulated_depreciation = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     other_non_current_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)

#     # Liabilities
#     accounts_payable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     short_term_borrowings = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     accrued_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     taxes_payable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     other_current_liabilities = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     long_term_loans = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     other_non_current_liabilities = models.DecimalField(max_digits=14, decimal_places=2, default=0)

#     # Equity / capital
#     owner_capital = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     reserves_surplus = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     retained_earnings = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     drawings = models.DecimalField(max_digits=14, decimal_places=2, default=0)

#     remarks = models.TextField(blank=True)
#     entered_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="balance_sheets_entered")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-statement_date", "-created_at"]
#         constraints = [
#             models.UniqueConstraint(
#                 fields=["business", "statement_date"],
#                 condition=models.Q(deleted_at__isnull=True),
#                 name="unique_live_balance_sheet_per_business_date",
#             )
#         ]

#     @property
#     def total_current_assets(self):
#         return (self.cash_in_hand + self.bank_balance + self.accounts_receivable +
#                 self.inventory + self.prepaid_expenses + self.other_current_assets)

#     @property
#     def total_non_current_assets(self):
#         return self.fixed_assets - self.accumulated_depreciation + self.other_non_current_assets

#     @property
#     def total_assets(self):
#         return self.total_current_assets + self.total_non_current_assets

#     @property
#     def total_current_liabilities(self):
#         return (self.accounts_payable + self.short_term_borrowings + self.accrued_expenses +
#                 self.taxes_payable + self.other_current_liabilities)

#     @property
#     def total_non_current_liabilities(self):
#         return self.long_term_loans + self.other_non_current_liabilities

#     @property
#     def total_liabilities(self):
#         return self.total_current_liabilities + self.total_non_current_liabilities

#     @property
#     def total_equity(self):
#         return self.owner_capital + self.reserves_surplus + self.retained_earnings - self.drawings

#     @property
#     def liabilities_and_equity(self):
#         return self.total_liabilities + self.total_equity

#     @property
#     def balance_difference(self):
#         return self.total_assets - self.liabilities_and_equity

#     @property
#     def is_balanced(self):
#         return self.balance_difference == Decimal("0.00")

#     def __str__(self):
#         return f"{self.business.name} - {self.statement_date}"


# class DailyFinancialStatement(SoftDeleteModel):
#     """Daily P&L and cash-flow summary submitted for a business.

#     This is intentionally separate from BalanceSheet: a balance sheet is a
#     point-in-time financial position, while this model records the period's
#     operating performance used to calculate profit/loss.
#     """

#     class Status(models.TextChoices):
#         SUBMITTED = "SUBMITTED", "Submitted"
#         REVIEWED = "REVIEWED", "Reviewed"
#         APPROVED = "APPROVED", "Approved"
#         REJECTED = "REJECTED", "Rejected"

#     business = models.ForeignKey(
#         Business, on_delete=models.PROTECT, related_name="daily_financial_statements"
#     )
#     statement_date = models.DateField()

#     # Profit & Loss inputs
#     revenue = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     direct_cost = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     operating_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     other_income = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     finance_cost = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     tax = models.DecimalField(max_digits=14, decimal_places=2, default=0)

#     # Cash-flow summary inputs
#     operating_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     operating_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     investing_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     investing_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     financing_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
#     financing_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)

#     remarks = models.TextField(blank=True)
#     status = models.CharField(max_length=20, choices=Status.choices, default=Status.SUBMITTED)
#     submitted_by = models.ForeignKey(
#         User, on_delete=models.PROTECT, related_name="daily_financial_statements_submitted"
#     )
#     submitted_at = models.DateTimeField(auto_now_add=True)
#     reviewed_by = models.ForeignKey(
#         User, on_delete=models.PROTECT, related_name="daily_financial_statements_reviewed",
#         null=True, blank=True
#     )
#     reviewed_at = models.DateTimeField(null=True, blank=True)
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     class Meta:
#         ordering = ["-statement_date", "-created_at"]
#         constraints = [
#             models.UniqueConstraint(
#                 fields=["business", "statement_date"],
#                 condition=models.Q(deleted_at__isnull=True),
#                 name="unique_live_daily_financial_statement_per_business_date",
#             )
#         ]

#     @property
#     def gross_profit(self):
#         return self.revenue - self.direct_cost

#     @property
#     def operating_profit(self):
#         return self.gross_profit - self.operating_expenses

#     @property
#     def profit_before_tax(self):
#         return self.operating_profit + self.other_income - self.finance_cost

#     @property
#     def net_profit(self):
#         return self.profit_before_tax - self.tax

#     @property
#     def profit_margin(self):
#         if self.revenue == 0:
#             return Decimal("0.00")
#         return (self.net_profit / self.revenue * Decimal("100")).quantize(Decimal("0.01"))

#     @property
#     def financial_status(self):
#         if self.net_profit > 0:
#             return "PROFIT"
#         if self.net_profit < 0:
#             return "LOSS"
#         return "BREAK_EVEN"

#     @property
#     def operating_cash_flow(self):
#         return self.operating_cash_inflow - self.operating_cash_outflow

#     @property
#     def investing_cash_flow(self):
#         return self.investing_cash_inflow - self.investing_cash_outflow

#     @property
#     def financing_cash_flow(self):
#         return self.financing_cash_inflow - self.financing_cash_outflow

#     @property
#     def net_cash_flow(self):
#         return self.operating_cash_flow + self.investing_cash_flow + self.financing_cash_flow

#     def __str__(self):
#         return f"{self.business.name} - {self.statement_date} - {self.financial_status}"


# class LedgerEntry(models.Model):
#     class EntryTypes(models.TextChoices):
#         CREDIT_PROFIT = "CREDIT_PROFIT", "Credit Profit"
#         SOFT_DEBIT = "SOFT_DEBIT", "Soft Debit"
#         DEBIT = "DEBIT", "Debit"

#     business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="ledger_entries")
#     investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="ledger_entries", null=True, blank=True)
#     investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="ledger_entries", null=True, blank=True)
#     kuber_investment = models.ForeignKey(
#         KuberBusinessInvestment, on_delete=models.PROTECT,
#         related_name="ledger_entries", null=True, blank=True
#     )
#     entry_date = models.DateField(default=timezone.localdate, db_index=True)
#     entry_type = models.CharField(max_length=30, choices=EntryTypes.choices)
#     amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0"))])
#     annual_rate = models.DecimalField(max_digits=7, decimal_places=4, null=True, blank=True)
#     description = models.TextField(blank=True)
#     reference = models.CharField(max_length=100, blank=True)
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["-entry_date", "-created_at"]
#         constraints = [
#             models.UniqueConstraint(
#                 fields=["kuber_investment", "entry_date", "entry_type"],
#                 condition=models.Q(kuber_investment__isnull=False),
#                 name="unique_kuber_ledger_entry_per_day_type",
#             ),
#             models.UniqueConstraint(
#                 fields=["investment", "entry_date", "entry_type"],
#                 condition=models.Q(investment__isnull=False),
#                 name="unique_investment_ledger_entry_per_day_type",
#             ),
#         ]

#     def __str__(self):
#         return f"{self.entry_date} {self.entry_type} {self.amount}"


# class Payout(models.Model):
#     investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="payouts")
#     investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="payouts")
#     amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))])
#     payout_date = models.DateField(default=timezone.localdate)
#     notes = models.TextField(blank=True)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="payouts_created")
#     created_at = models.DateTimeField(auto_now_add=True)

#     def __str__(self):
#         return f"{self.investor.name} - {self.amount}"


# class Certificate(SoftDeleteModel):
#     investment = models.OneToOneField(Investment, on_delete=models.PROTECT, related_name="certificate")
#     html_content = models.TextField()
#     version = models.PositiveIntegerField(default=1)
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="certificates_created")
#     created_at = models.DateTimeField(auto_now_add=True)
#     updated_at = models.DateTimeField(auto_now=True)


#     def __str__(self):
#         return f"Certificate #{self.pk} - {self.investment.investor.name}"


# class CertificateAttachment(SoftDeleteModel):
#     certificate = models.ForeignKey(Certificate, on_delete=models.CASCADE, related_name="attachments")
#     title = models.CharField(max_length=255, blank=True)
#     file = models.FileField(upload_to="certificates/attachments/")
#     sort_order = models.PositiveIntegerField(default=0)
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["sort_order", "id"]

#     def __str__(self):
#         return self.title or self.file.name


# class AuditLog(models.Model):
#     actor = models.ForeignKey(User, on_delete=models.PROTECT, related_name="audit_logs")
#     operation = models.CharField(max_length=30)
#     module = models.CharField(max_length=100)
#     object_type = models.CharField(max_length=100)
#     object_id = models.CharField(max_length=100, blank=True)
#     description = models.TextField(blank=True)
#     metadata = models.JSONField(default=dict, blank=True)
#     created_at = models.DateTimeField(auto_now_add=True, db_index=True)

#     class Meta:
#         ordering = ["-created_at"]


# class RecurringContribution(SoftDeleteModel):
#     investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="recurring_contributions")
#     contribution_date = models.DateField(default=timezone.localdate)
#     amount = models.DecimalField(max_digits=14, decimal_places=2,
#                                  validators=[MinValueValidator(Decimal("0.01"))])
#     created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="recurring_contributions_created")
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["contribution_date"]
#         constraints = [
#             models.UniqueConstraint(
#                 fields=["investment", "contribution_date"],
#                 condition=models.Q(deleted_at__isnull=True),
#                 name="one_platinum_contribution_per_investment_date",
#             )
#         ]


# class PasswordResetOTP(models.Model):
#     user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="password_reset_otps")
#     otp_hash = models.CharField(max_length=128)
#     expires_at = models.DateTimeField()
#     attempts = models.PositiveIntegerField(default=0)
#     used = models.BooleanField(default=False)
#     created_at = models.DateTimeField(auto_now_add=True)

#     class Meta:
#         ordering = ["-created_at"]


# class AccountantPermission(models.Model):
#     user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="accountant_permissions")
#     permissions = models.JSONField(default=dict, blank=True)
#     updated_at = models.DateTimeField(auto_now=True)

#     def __str__(self):
#         return f"Permissions for {self.user.username}"




from decimal import Decimal
from django.contrib.auth.models import AbstractUser
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.utils import timezone


class User(AbstractUser):
    class Roles(models.TextChoices):
        ADMIN = "ADMIN", "Admin"
        ACCOUNTANT = "ACCOUNTANT", "Accountant"
        BUSINESS = "BUSINESS", "Business"
        INVESTOR = "INVESTOR", "Investor"
        AGENT = "AGENT", "Agent"

    email = models.EmailField(unique=True)
    role = models.CharField(max_length=20, choices=Roles.choices)
    phone = models.CharField(max_length=30, blank=True)
    image = models.ImageField(upload_to="users/profile/", blank=True, null=True)
    # Admin-only credential display value. Django's real password remains hashed
    # in the standard password field; this value is only populated when an
    # admin creates/changes a login password through this panel.
    admin_visible_password = models.CharField(max_length=255, blank=True, default="")
    is_active = models.BooleanField(default=True)

    def __str__(self):
        return f"{self.username} ({self.role})"


class SoftDeleteModel(models.Model):
    deleted_at = models.DateTimeField(null=True, blank=True, db_index=True)

    class Meta:
        abstract = True

    def soft_delete(self):
        self.deleted_at = timezone.now()
        self.save(update_fields=["deleted_at"])

    def restore(self):
        self.deleted_at = None
        self.save(update_fields=["deleted_at"])


class Business(SoftDeleteModel):
    user = models.OneToOneField(
        User,
        on_delete=models.PROTECT,
        related_name="business_profile",
        null=True,
        blank=True
    )

    name = models.CharField(max_length=255)
    email = models.EmailField(blank=True)
    location = models.CharField(max_length=500, blank=True)

    owner_name = models.CharField(max_length=255)
    owner_aadhar = models.CharField(max_length=32, blank=True)
    owner_pan = models.CharField(max_length=20, blank=True)
    owner_mobile = models.CharField(max_length=30, blank=True)
    owner_sex = models.CharField(max_length=30, blank=True)
    owner_photo = models.ImageField(
        upload_to="businesses/owners/",
        blank=True,
        null=True
    )
    business_photo = models.ImageField(
        upload_to="businesses/business/",
        blank=True,
        null=True
    )
    created_by = models.ForeignKey(
        User,
        on_delete=models.PROTECT,
        related_name="businesses_created"
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


class BusinessBankDetail(models.Model):
    business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="bank_detail_fields")
    key = models.CharField(max_length=100)
    value = models.TextField(blank=True)

    class Meta:
        ordering = ["id"]

    def __str__(self):
        return f"{self.key}: {self.value}"


class BusinessDetailField(models.Model):
    business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="detail_fields")
    key = models.CharField(max_length=100)
    value = models.TextField(blank=True)

    class Meta:
        ordering = ["id"]

    def __str__(self):
        return f"{self.key}: {self.value}"


class BusinessDocument(models.Model):
    business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="uploaded_documents")
    title = models.CharField(max_length=255)
    file = models.FileField(upload_to="businesses/documents/")
    uploaded_by = models.ForeignKey(User, on_delete=models.PROTECT)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title


class Investor(SoftDeleteModel):
    user = models.OneToOneField(
        User, on_delete=models.PROTECT, related_name="investor_profile",
        null=True, blank=True
    )
    name = models.CharField(max_length=255)
    email = models.EmailField(blank=True)
    mobile = models.CharField(max_length=30, blank=True)
    image = models.ImageField(upload_to="investors/profile/", blank=True, null=True)
    other_details = models.TextField(blank=True)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="investors_created")
    # Agent attribution is independent from created_by. Admin creates the Investor,
    # while this optional field records whether the Investor came via an Agent.
    agent = models.ForeignKey(
        "agent_panel.Agent",
        on_delete=models.PROTECT,
        related_name="attributed_investors",
        null=True,
        blank=True,
    )
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.name


class InvestorDetailField(models.Model):
    class Sections(models.TextChoices):
        IDENTITY = "IDENTITY", "Identity"
        BANK = "BANK", "Bank"
        NOMINEE = "NOMINEE", "Nominee"

    investor = models.ForeignKey(Investor, on_delete=models.CASCADE, related_name="detail_fields")
    section = models.CharField(max_length=20, choices=Sections.choices)
    key = models.CharField(max_length=100)
    value = models.TextField(blank=True)

    class Meta:
        ordering = ["section", "id"]
        indexes = [models.Index(fields=["investor", "section"])]

    def __str__(self):
        return f"{self.section}: {self.key}: {self.value}"


class InvestorDocument(models.Model):
    class Sections(models.TextChoices):
        IDENTITY = "IDENTITY", "Identity"
        BANK = "BANK", "Bank"
        NOMINEE = "NOMINEE", "Nominee"
        OTHER = "OTHER", "Other"

    investor = models.ForeignKey(Investor, on_delete=models.CASCADE, related_name="uploaded_documents")
    section = models.CharField(max_length=20, choices=Sections.choices, default=Sections.OTHER)
    title = models.CharField(max_length=255)
    file = models.FileField(upload_to="investors/documents/")
    uploaded_by = models.ForeignKey(User, on_delete=models.PROTECT)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


class AccountantDetailField(models.Model):
    accountant = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="accountant_detail_fields"
    )
    key = models.CharField(max_length=100)
    value = models.TextField(blank=True)

    class Meta:
        ordering = ["id"]

    def __str__(self):
        return f"{self.key}: {self.value}"


class AccountantDocument(models.Model):
    accountant = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="accountant_documents"
    )
    title = models.CharField(max_length=255)
    file = models.FileField(upload_to="accountants/identity/")
    uploaded_by = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name="accountant_documents_uploaded"
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return self.title


class Scheme(SoftDeleteModel):
    class Categories(models.TextChoices):
        SILVER = "SILVER", "Silver"
        GOLD = "GOLD", "Gold"
        PLATINUM = "PLATINUM", "Platinum"
        DIAMOND = "DIAMOND", "Diamond"

    category = models.CharField(max_length=20, choices=Categories.choices)
    name = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    tenure_months = models.PositiveIntegerField()
    annual_interest_rate = models.DecimalField(
        max_digits=7, decimal_places=4,
        validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
    )
    penalty_rate = models.DecimalField(
        max_digits=7, decimal_places=4, default=Decimal("0"),
        validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
    )
    withdrawal_type = models.CharField(
        max_length=40,
        default="MONTHLY_WITHDRAWAL",
        blank=True,
    )
    compounding_frequency = models.CharField(max_length=30, blank=True)
    rules = models.JSONField(default=list, blank=True)
    is_active = models.BooleanField(default=True)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="schemes_created")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["category", "tenure_months", "name"]

    def __str__(self):
        return f"{self.category} - {self.name} - {self.tenure_months} months - {self.annual_interest_rate}% p.a."


class KuberBusinessInvestment(SoftDeleteModel):
    class InvestmentTypes(models.TextChoices):
        ORDINARY = "ORDINARY", "Ordinary"
        EQUITY_SHARE = "EQUITY_SHARE", "Equity Share"

    business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="kuber_investments")
    investment_type = models.CharField(
        max_length=20,
        choices=InvestmentTypes.choices,
        default=InvestmentTypes.ORDINARY,
    )
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))])
    annual_rate = models.DecimalField(
        max_digits=7, decimal_places=4,
        validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
    )
    # Locked at the time an Equity Share investment is created. The current
    # principal/value is always calculated from the latest Balance Sheet
    # Total Equity multiplied by this percentage.
    equity_share_percentage = models.DecimalField(
        max_digits=9, decimal_places=6, null=True, blank=True,
        validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
    )
    investment_date = models.DateField(default=timezone.localdate)
    maturity_date = models.DateField(null=True, blank=True)
    notes = models.TextField(blank=True)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="kuber_business_investments_created")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-investment_date"]

    def __str__(self):
        return f"{self.business} / {self.amount} / {self.annual_rate}% p.a."


class Investment(SoftDeleteModel):
    class Status(models.TextChoices):
        ACTIVE = "ACTIVE", "Active"
        MATURED = "MATURED", "Matured"
        CLOSED = "CLOSED", "Closed"
        CANCELLED = "CANCELLED", "Cancelled"

    investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="investments")
    business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="investments")
    scheme = models.ForeignKey(Scheme, on_delete=models.PROTECT, related_name="investments")
    # One-time principal for Silver/Gold/Diamond. Platinum uses actual recurring contributions.
    amount = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True,
                                 validators=[MinValueValidator(Decimal("0.01"))])
    # Only used by Platinum; it is set on the individual investment, never on Scheme.
    monthly_installment = models.DecimalField(max_digits=14, decimal_places=2, null=True, blank=True,
                                               validators=[MinValueValidator(Decimal("0.01"))])
    # Copied from the selected scheme at investment creation; admin does not manually enter it.
    investor_annual_rate = models.DecimalField(
        max_digits=7, decimal_places=4,
        validators=[MinValueValidator(Decimal("0")), MaxValueValidator(Decimal("100"))]
    )
    investment_date = models.DateField(default=timezone.localdate)
    maturity_date = models.DateField(null=True, blank=True)
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.ACTIVE)
    terms_snapshot = models.JSONField(default=dict, blank=True)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="investments_created")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-investment_date"]

    def __str__(self):
        amount = self.monthly_installment if self.scheme.category == Scheme.Categories.PLATINUM else self.amount
        suffix = "/month" if self.scheme.category == Scheme.Categories.PLATINUM else ""
        return f"{self.investor.name} -> {self.business.name} ({amount}{suffix})"


class BalanceSheet(SoftDeleteModel):
    """Structured balance sheet entered through the portal form.

    Monetary values are stored as decimals; totals are calculated properties so
    users cannot accidentally save inconsistent total figures.
    """

    business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="balance_sheets")
    statement_date = models.DateField()

    # Assets
    cash_in_hand = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    bank_balance = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    accounts_receivable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    inventory = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    prepaid_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    other_current_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    fixed_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    accumulated_depreciation = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    other_non_current_assets = models.DecimalField(max_digits=14, decimal_places=2, default=0)

    # Liabilities
    accounts_payable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    short_term_borrowings = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    accrued_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    taxes_payable = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    other_current_liabilities = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    long_term_loans = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    other_non_current_liabilities = models.DecimalField(max_digits=14, decimal_places=2, default=0)

    # Equity / capital
    owner_capital = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    reserves_surplus = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    retained_earnings = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    drawings = models.DecimalField(max_digits=14, decimal_places=2, default=0)

    remarks = models.TextField(blank=True)
    entered_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="balance_sheets_entered")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-statement_date", "-created_at"]
        constraints = [
            models.UniqueConstraint(
                fields=["business", "statement_date"],
                condition=models.Q(deleted_at__isnull=True),
                name="unique_live_balance_sheet_per_business_date",
            )
        ]

    @property
    def total_current_assets(self):
        return (self.cash_in_hand + self.bank_balance + self.accounts_receivable +
                self.inventory + self.prepaid_expenses + self.other_current_assets)

    @property
    def total_non_current_assets(self):
        return self.fixed_assets - self.accumulated_depreciation + self.other_non_current_assets

    @property
    def total_assets(self):
        return self.total_current_assets + self.total_non_current_assets

    @property
    def total_current_liabilities(self):
        return (self.accounts_payable + self.short_term_borrowings + self.accrued_expenses +
                self.taxes_payable + self.other_current_liabilities)

    @property
    def total_non_current_liabilities(self):
        return self.long_term_loans + self.other_non_current_liabilities

    @property
    def total_liabilities(self):
        return self.total_current_liabilities + self.total_non_current_liabilities

    @property
    def total_equity(self):
        return self.owner_capital + self.reserves_surplus + self.retained_earnings - self.drawings

    @property
    def liabilities_and_equity(self):
        return self.total_liabilities + self.total_equity

    @property
    def balance_difference(self):
        return self.total_assets - self.liabilities_and_equity

    @property
    def is_balanced(self):
        return self.balance_difference == Decimal("0.00")

    def __str__(self):
        return f"{self.business.name} - {self.statement_date}"


class DailyFinancialStatement(SoftDeleteModel):
    """Daily P&L and cash-flow summary submitted for a business.

    This is intentionally separate from BalanceSheet: a balance sheet is a
    point-in-time financial position, while this model records the period's
    operating performance used to calculate profit/loss.
    """

    class Status(models.TextChoices):
        SUBMITTED = "SUBMITTED", "Submitted"
        REVIEWED = "REVIEWED", "Reviewed"
        APPROVED = "APPROVED", "Approved"
        REJECTED = "REJECTED", "Rejected"

    business = models.ForeignKey(
        Business, on_delete=models.PROTECT, related_name="daily_financial_statements"
    )
    statement_date = models.DateField()

    # Profit & Loss inputs
    revenue = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    direct_cost = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    operating_expenses = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    other_income = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    finance_cost = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    tax = models.DecimalField(max_digits=14, decimal_places=2, default=0)

    # Cash-flow summary inputs
    operating_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    operating_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    investing_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    investing_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    financing_cash_inflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    financing_cash_outflow = models.DecimalField(max_digits=14, decimal_places=2, default=0)

    remarks = models.TextField(blank=True)
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.SUBMITTED)
    submitted_by = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name="daily_financial_statements_submitted"
    )
    submitted_at = models.DateTimeField(auto_now_add=True)
    reviewed_by = models.ForeignKey(
        User, on_delete=models.PROTECT, related_name="daily_financial_statements_reviewed",
        null=True, blank=True
    )
    reviewed_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-statement_date", "-created_at"]
        constraints = [
            models.UniqueConstraint(
                fields=["business", "statement_date"],
                condition=models.Q(deleted_at__isnull=True),
                name="unique_live_daily_financial_statement_per_business_date",
            )
        ]

    @property
    def gross_profit(self):
        return self.revenue - self.direct_cost

    @property
    def operating_profit(self):
        return self.gross_profit - self.operating_expenses

    @property
    def profit_before_tax(self):
        return self.operating_profit + self.other_income - self.finance_cost

    @property
    def net_profit(self):
        return self.profit_before_tax - self.tax

    @property
    def profit_margin(self):
        if self.revenue == 0:
            return Decimal("0.00")
        return (self.net_profit / self.revenue * Decimal("100")).quantize(Decimal("0.01"))

    @property
    def financial_status(self):
        if self.net_profit > 0:
            return "PROFIT"
        if self.net_profit < 0:
            return "LOSS"
        return "BREAK_EVEN"

    @property
    def operating_cash_flow(self):
        return self.operating_cash_inflow - self.operating_cash_outflow

    @property
    def investing_cash_flow(self):
        return self.investing_cash_inflow - self.investing_cash_outflow

    @property
    def financing_cash_flow(self):
        return self.financing_cash_inflow - self.financing_cash_outflow

    @property
    def net_cash_flow(self):
        return self.operating_cash_flow + self.investing_cash_flow + self.financing_cash_flow

    def __str__(self):
        return f"{self.business.name} - {self.statement_date} - {self.financial_status}"


class LedgerEntry(models.Model):
    class EntryTypes(models.TextChoices):
        CREDIT_PROFIT = "CREDIT_PROFIT", "Credit Profit"
        SOFT_DEBIT = "SOFT_DEBIT", "Soft Debit"
        DEBIT = "DEBIT", "Debit"

    business = models.ForeignKey(Business, on_delete=models.PROTECT, related_name="ledger_entries")
    investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="ledger_entries", null=True, blank=True)
    investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="ledger_entries", null=True, blank=True)
    kuber_investment = models.ForeignKey(
        KuberBusinessInvestment, on_delete=models.PROTECT,
        related_name="ledger_entries", null=True, blank=True
    )
    entry_date = models.DateField(default=timezone.localdate, db_index=True)
    entry_type = models.CharField(max_length=30, choices=EntryTypes.choices)
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0"))])
    annual_rate = models.DecimalField(max_digits=7, decimal_places=4, null=True, blank=True)
    description = models.TextField(blank=True)
    reference = models.CharField(max_length=100, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-entry_date", "-created_at"]
        constraints = [
            models.UniqueConstraint(
                fields=["kuber_investment", "entry_date", "entry_type"],
                condition=models.Q(kuber_investment__isnull=False),
                name="unique_kuber_ledger_entry_per_day_type",
            ),
            models.UniqueConstraint(
                fields=["investment", "entry_date", "entry_type"],
                condition=models.Q(investment__isnull=False),
                name="unique_investment_ledger_entry_per_day_type",
            ),
        ]

    def __str__(self):
        return f"{self.entry_date} {self.entry_type} {self.amount}"


class Payout(models.Model):
    investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="payouts")
    investor = models.ForeignKey(Investor, on_delete=models.PROTECT, related_name="payouts")
    amount = models.DecimalField(max_digits=14, decimal_places=2, validators=[MinValueValidator(Decimal("0.01"))])
    payout_date = models.DateField(default=timezone.localdate)
    notes = models.TextField(blank=True)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="payouts_created")
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.investor.name} - {self.amount}"


class Certificate(SoftDeleteModel):
    investment = models.OneToOneField(Investment, on_delete=models.PROTECT, related_name="certificate")
    html_content = models.TextField()
    version = models.PositiveIntegerField(default=1)
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="certificates_created")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


    def __str__(self):
        return f"Certificate #{self.pk} - {self.investment.investor.name}"


class CertificateAttachment(SoftDeleteModel):
    certificate = models.ForeignKey(Certificate, on_delete=models.CASCADE, related_name="attachments")
    title = models.CharField(max_length=255, blank=True)
    file = models.FileField(upload_to="certificates/attachments/")
    sort_order = models.PositiveIntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["sort_order", "id"]

    def __str__(self):
        return self.title or self.file.name


class AuditLog(models.Model):
    actor = models.ForeignKey(User, on_delete=models.PROTECT, related_name="audit_logs")
    operation = models.CharField(max_length=30)
    module = models.CharField(max_length=100)
    object_type = models.CharField(max_length=100)
    object_id = models.CharField(max_length=100, blank=True)
    description = models.TextField(blank=True)
    metadata = models.JSONField(default=dict, blank=True)
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        ordering = ["-created_at"]


class RecurringContribution(SoftDeleteModel):
    investment = models.ForeignKey(Investment, on_delete=models.PROTECT, related_name="recurring_contributions")
    contribution_date = models.DateField(default=timezone.localdate)
    amount = models.DecimalField(max_digits=14, decimal_places=2,
                                 validators=[MinValueValidator(Decimal("0.01"))])
    created_by = models.ForeignKey(User, on_delete=models.PROTECT, related_name="recurring_contributions_created")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["contribution_date"]
        constraints = [
            models.UniqueConstraint(
                fields=["investment", "contribution_date"],
                condition=models.Q(deleted_at__isnull=True),
                name="one_platinum_contribution_per_investment_date",
            )
        ]


class PasswordResetOTP(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="password_reset_otps")
    otp_hash = models.CharField(max_length=128)
    expires_at = models.DateTimeField()
    attempts = models.PositiveIntegerField(default=0)
    used = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ["-created_at"]


class AccountantPermission(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="accountant_permissions")
    permissions = models.JSONField(default=dict, blank=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"Permissions for {self.user.username}"
