from django.conf import settings
from django.db import models

from apps.core.models import Currency, TimeStampedModel


class ApprovalStep(models.TextChoices):
    MAKER = "maker", "Maker"
    CHECKER = "checker", "Checker"
    FINANCE = "finance", "Finance"
    DIRECTOR = "director", "Director"
    CEO = "ceo", "CEO / Authorized approver"


class WorkflowStatus(models.TextChoices):
    DRAFT = "draft", "Draft"
    IN_REVIEW = "in_review", "In review"
    APPROVED = "approved", "Approved"
    REJECTED = "rejected", "Rejected"
    EXECUTED = "executed", "Executed"


class ApprovalDecision(models.TextChoices):
    PENDING = "pending", "Pending"
    APPROVED = "approved", "Approved"
    REJECTED = "rejected", "Rejected"


class ApprovalWorkflow(TimeStampedModel):
    module = models.CharField(max_length=40)
    object_type = models.CharField(max_length=80)
    object_id = models.PositiveIntegerField()
    current_step = models.CharField(max_length=16, choices=ApprovalStep.choices, default=ApprovalStep.MAKER)
    status = models.CharField(max_length=16, choices=WorkflowStatus.choices, default=WorkflowStatus.DRAFT)
    submitted_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="submitted_workflows",
    )

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"{self.object_type} #{self.object_id} · {self.status}"


class ApprovalRecord(TimeStampedModel):
    workflow = models.ForeignKey(ApprovalWorkflow, on_delete=models.CASCADE, related_name="records")
    step = models.CharField(max_length=16, choices=ApprovalStep.choices)
    decision = models.CharField(max_length=16, choices=ApprovalDecision.choices, default=ApprovalDecision.PENDING)
    actor = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="approval_records",
    )
    notes = models.TextField(blank=True)
    decided_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        ordering = ["id"]


class ProjectLedgerLine(TimeStampedModel):
    class Kind(models.TextChoices):
        REVENUE = "revenue", "Revenue"
        EXPENSE = "expense", "Expense"

    project = models.ForeignKey("projects.Project", on_delete=models.CASCADE, related_name="ledger_lines")
    kind = models.CharField(max_length=16, choices=Kind.choices)
    category = models.CharField(max_length=80)
    amount = models.DecimalField(max_digits=16, decimal_places=2)
    currency = models.CharField(max_length=8, choices=Currency.choices, default=Currency.BDT)
    recognized = models.BooleanField(default=False)
    occurred_on = models.DateField()
    notes = models.CharField(max_length=255, blank=True)

    class Meta:
        ordering = ["-occurred_on", "-id"]


class ProfitCalculation(TimeStampedModel):
    project = models.ForeignKey("projects.Project", on_delete=models.PROTECT, related_name="profit_calculations")
    sales_revenue = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    eligible_costs = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    distributable_profit = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    currency = models.CharField(max_length=8, choices=Currency.choices, default=Currency.BDT)
    status = models.CharField(max_length=16, choices=WorkflowStatus.choices, default=WorkflowStatus.DRAFT)
    notes = models.TextField(blank=True)
    workflow = models.ForeignKey(
        ApprovalWorkflow,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="profit_calculations",
    )
    created_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="created_profit_calculations",
    )

    class Meta:
        ordering = ["-created_at"]

    def __str__(self):
        return f"Profit calc · {self.project.name} · {self.status}"


class ProfitDistribution(TimeStampedModel):
    calculation = models.OneToOneField(ProfitCalculation, on_delete=models.CASCADE, related_name="distribution")
    project = models.ForeignKey("projects.Project", on_delete=models.PROTECT, related_name="profit_distributions")
    status = models.CharField(max_length=16, choices=WorkflowStatus.choices, default=WorkflowStatus.DRAFT)
    executed_at = models.DateTimeField(null=True, blank=True)
    executed_by = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="executed_distributions",
    )

    class Meta:
        ordering = ["-created_at"]


class DistributionItem(TimeStampedModel):
    class ItemStatus(models.TextChoices):
        PENDING = "pending", "Pending"
        APPROVED = "approved", "Approved"
        PAID = "paid", "Paid"
        CANCELLED = "cancelled", "Cancelled"

    distribution = models.ForeignKey(ProfitDistribution, on_delete=models.CASCADE, related_name="items")
    investor = models.ForeignKey("investors.Investor", on_delete=models.PROTECT, related_name="distribution_items")
    investment = models.ForeignKey(
        "investments.Investment",
        on_delete=models.PROTECT,
        related_name="distribution_items",
    )
    participation_percent = models.DecimalField(max_digits=8, decimal_places=4)
    amount = models.DecimalField(max_digits=16, decimal_places=2)
    status = models.CharField(max_length=16, choices=ItemStatus.choices, default=ItemStatus.PENDING)

    class Meta:
        ordering = ["id"]
