from django.db import models


class SimulationScenario(models.Model):
    class ScenarioType(models.TextChoices):
        SINGLE = "single", "Single Simulation"
        CROP_COMPARISON = "crop_comparison", "Crop Comparison"
        FERTILIZATION_COMPARISON = (
            "fertilization_comparison",
            "Fertilization Comparison",
        )

    class Status(models.TextChoices):
        PENDING = "pending", "Pending"
        RUNNING = "running", "Running"
        SUCCESS = "success", "Success"
        FAILURE = "failure", "Failure"

    name = models.CharField(max_length=255, blank=True, default="")
    scenario_type = models.CharField(
        max_length=64,
        choices=ScenarioType.choices,
        default=ScenarioType.SINGLE,
        db_index=True,
    )
    model_name = models.CharField(max_length=128, default="Wofost81_NWLP_CWB_CNB")
    status = models.CharField(
        max_length=32,
        choices=Status.choices,
        default=Status.PENDING,
        db_index=True,
    )
    input_payload = models.JSONField(default=dict, blank=True)
    result_payload = models.JSONField(default=dict, blank=True)
    error_message = models.TextField(blank=True, default="")
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = "Simulation Scenario"
        verbose_name_plural = "Simulation Scenarios"

    def __str__(self):
        return self.name or f"{self.scenario_type}:{self.pk}"


class SimulationRun(models.Model):
    scenario = models.ForeignKey(
        SimulationScenario,
        on_delete=models.CASCADE,
        related_name="runs",
    )
    run_key = models.CharField(max_length=64)
    label = models.CharField(max_length=255)
    status = models.CharField(
        max_length=32,
        choices=SimulationScenario.Status.choices,
        default=SimulationScenario.Status.PENDING,
        db_index=True,
    )
    weather_payload = models.JSONField(default=list, blank=True)
    soil_payload = models.JSONField(default=dict, blank=True)
    crop_payload = models.JSONField(default=dict, blank=True)
    site_payload = models.JSONField(default=dict, blank=True)
    agromanagement_payload = models.JSONField(default=list, blank=True)
    result_payload = models.JSONField(default=dict, blank=True)
    error_message = models.TextField(blank=True, default="")
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ["scenario_id", "id"]
        constraints = [
            models.UniqueConstraint(
                fields=["scenario", "run_key"],
                name="crop_simulation_unique_run_key_per_scenario",
            )
        ]
        verbose_name = "Simulation Run"
        verbose_name_plural = "Simulation Runs"

    def __str__(self):
        return f"{self.scenario_id}:{self.run_key}"
