import uuid

from django.db import models

from core.models import TimeStampedModel
from flats.models import Flat


class FlatSale(TimeStampedModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    flat = models.OneToOneField(Flat, on_delete=models.CASCADE, related_name="sale")
    buyer_name = models.CharField(max_length=255)
    buyer_mobile = models.CharField(max_length=20, blank=True)
    buyer_address = models.TextField(blank=True)
    sale_price = models.DecimalField(max_digits=14, decimal_places=2)
    booking_money = models.DecimalField(max_digits=14, decimal_places=2, default=0)
    sale_date = models.DateField()
    notes = models.TextField(blank=True)

    class Meta:
        db_table = "sales_flatsale"
        ordering = ["-sale_date"]

    def __str__(self):
        return f"{self.flat} sold to {self.buyer_name}"

    @property
    def project(self):
        return self.flat.project

    @property
    def total_installments_paid(self):
        return self.installments.aggregate(t=models.Sum("amount"))["t"] or 0

    @property
    def total_received(self):
        return self.booking_money + self.total_installments_paid

    @property
    def due_amount(self):
        return self.sale_price - self.total_received


class Installment(TimeStampedModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    sale = models.ForeignKey(FlatSale, on_delete=models.CASCADE, related_name="installments")
    date = models.DateField()
    amount = models.DecimalField(max_digits=14, decimal_places=2)
    payment_method = models.CharField(
        max_length=20,
        choices=[("cash", "Cash"), ("bank", "Bank"), ("mobile_banking", "Mobile Banking"), ("other", "Other")],
        default="bank",
    )
    remarks = models.CharField(max_length=255, blank=True)

    class Meta:
        db_table = "sales_installment"
        ordering = ["-date"]

    def __str__(self):
        return f"{self.sale.buyer_name} - {self.amount} on {self.date}"

    @property
    def project(self):
        return self.sale.flat.project
