from django.db import models

from apps.core.models import Currency, TimeStampedModel


class ProjectStatus(models.TextChoices):
    PLANNING = "planning", "Planning & Pre-Development"
    CONCEPT = "concept", "Concept Design"
    MASTER_PLAN = "master_plan", "Master Plan Concept"
    ENGINEERING = "engineering", "Engineering"
    CONSTRUCTION = "construction", "Construction"
    HANDOVER = "handover", "Handover"
    COMPLETED = "completed", "Completed"


class TimelineStatus(models.TextChoices):
    DONE = "done", "Done"
    ACTIVE = "active", "Active"
    UPCOMING = "upcoming", "Upcoming"


class Project(TimeStampedModel):
    slug = models.SlugField(unique=True)
    name = models.CharField(max_length=180)
    location = models.CharField(max_length=180)
    project_type = models.CharField(max_length=80)
    total_area = models.CharField(max_length=80, blank=True)
    building_size = models.CharField(max_length=80, blank=True)
    units = models.CharField(max_length=120, blank=True)
    expected_completion = models.CharField(max_length=80, blank=True)
    status = models.CharField(max_length=32, choices=ProjectStatus.choices, default=ProjectStatus.PLANNING)
    status_label = models.CharField(max_length=80, blank=True)
    tag = models.CharField(max_length=80, blank=True)
    summary = models.TextField(blank=True)
    image = models.CharField(max_length=255, blank=True)
    overview = models.TextField(blank=True)
    location_detail = models.TextField(blank=True)
    master_plan = models.TextField(blank=True)
    architecture = models.TextField(blank=True)
    structural_design = models.TextField(blank=True)
    construction_progress = models.TextField(blank=True)
    safety_features = models.JSONField(default=list, blank=True)
    investment_opportunity = models.TextField(blank=True)
    investor_benefits = models.JSONField(default=list, blank=True)
    progress_percent = models.DecimalField(max_digits=5, decimal_places=2, default=0)
    is_published = models.BooleanField(default=True)

    class Meta:
        ordering = ["name"]

    def __str__(self):
        return self.name


class ProjectFinancialLine(TimeStampedModel):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="financial_lines")
    label = models.CharField(max_length=120)
    value = models.CharField(max_length=80)
    sort_order = models.PositiveSmallIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]


class ProjectDocumentMeta(TimeStampedModel):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="public_documents")
    name = models.CharField(max_length=180)
    file_type = models.CharField(max_length=20, default="PDF")
    sort_order = models.PositiveSmallIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]


class ProjectGalleryItem(TimeStampedModel):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="gallery_items")
    image = models.CharField(max_length=255)
    caption = models.CharField(max_length=180, blank=True)
    sort_order = models.PositiveSmallIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]


class ProjectVideo(TimeStampedModel):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="videos")
    title = models.CharField(max_length=180)
    note = models.CharField(max_length=255, blank=True)
    youtube_id = models.CharField(max_length=32, blank=True)
    sort_order = models.PositiveSmallIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]


class ProjectMilestone(TimeStampedModel):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="milestones")
    phase = models.CharField(max_length=120)
    status = models.CharField(max_length=16, choices=TimelineStatus.choices, default=TimelineStatus.UPCOMING)
    detail = models.CharField(max_length=255, blank=True)
    progress_percent = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    due_date = models.DateField(null=True, blank=True)
    completed_at = models.DateField(null=True, blank=True)
    sort_order = models.PositiveSmallIntegerField(default=0)

    class Meta:
        ordering = ["sort_order", "id"]

    def __str__(self):
        return f"{self.project.name} · {self.phase}"


class RuleModel(models.TextChoices):
    PRO_RATA = "pro_rata", "Pro-rata participation"
    UNIT = "unit", "Unit / share based"
    CONTRACTUAL = "contractual", "Contractual profit-sharing"
    HYBRID = "hybrid", "Hybrid"


class InvestmentWindowStatus(models.TextChoices):
    DRAFT = "draft", "Draft"
    OPEN = "open", "Open"
    PAUSED = "paused", "Paused"
    CLOSED = "closed", "Closed"


class ProjectInvestmentTerms(TimeStampedModel):
    project = models.OneToOneField(Project, on_delete=models.CASCADE, related_name="investment_terms")
    project_cost = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    investment_pool = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    company_contribution = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    reserved_amount = models.DecimalField(max_digits=16, decimal_places=2, default=0)
    min_investment = models.DecimalField(max_digits=16, decimal_places=2, default=5000)
    max_investment = models.DecimalField(max_digits=16, decimal_places=2, null=True, blank=True)
    currency = models.CharField(max_length=8, choices=Currency.choices, default=Currency.BDT)
    rule_model = models.CharField(max_length=20, choices=RuleModel.choices, default=RuleModel.PRO_RATA)
    total_units = models.PositiveIntegerField(null=True, blank=True)
    unit_price = models.DecimalField(max_digits=16, decimal_places=2, null=True, blank=True)
    status = models.CharField(
        max_length=16, choices=InvestmentWindowStatus.choices, default=InvestmentWindowStatus.DRAFT
    )
    opens_at = models.DateTimeField(null=True, blank=True)
    closes_at = models.DateTimeField(null=True, blank=True)
    distribution_notes = models.TextField(blank=True)
    disclaimer = models.TextField(
        blank=True,
        default=(
            "Investment values, participation percentages and distributions are subject to the "
            "applicable project agreement, accounting records, eligibility requirements, fees, "
            "taxes and applicable law. Project projections are not guaranteed returns."
        ),
    )
    is_published = models.BooleanField(default=False)

    class Meta:
        verbose_name_plural = "Project investment terms"

    def __str__(self):
        return f"Terms · {self.project.name}"

    @property
    def remaining_capacity(self):
        from apps.investments.models import Investment, InvestmentStatus

        subscribed = (
            self.project.investments.exclude(status=InvestmentStatus.CANCELLED).aggregate(
                total=models.Sum("committed_amount")
            )["total"]
            or 0
        )
        return (self.investment_pool or 0) - subscribed
