"""
Planes y consumo. Cableado y apagado (principio VI).

Las tablas existen y se escriben desde el primer día aunque no se cobre: el
consumo acumulado es el insumo para dimensionar los planes cuando se enciendan,
y empezar a medirlo el día que se decida cobrar deja sin datos justamente la
etapa que hay que dimensionar.
"""

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

from apps.core.models import BaseModel


class Plan(BaseModel):
    """
    Nivel de servicio. El primer corte crea uno solo, sin límites.

    Un límite nulo significa «sin tope», no «cero»: es la forma de tener la
    columna cableada sin que restrinja nada mientras la capacidad esté apagada.
    """

    code = models.CharField(max_length=50, unique=True)
    name = models.CharField(max_length=100)
    max_domains = models.PositiveIntegerField(null=True, blank=True)
    max_monitored_urls = models.PositiveIntegerField(null=True, blank=True)
    is_default = models.BooleanField(default=False)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['is_default'],
                condition=models.Q(is_default=True),
                name='only_one_default_plan',
            )
        ]

    def __str__(self) -> str:
        return self.code


class ConsumptionMetric(models.TextChoices):
    INSPECTIONS = 'INSPECTIONS', 'Inspections'
    SITEMAP_SUBMITS = 'SITEMAP_SUBMITS', 'Sitemap submits'
    MONITORED_URLS = 'MONITORED_URLS', 'Monitored URLs'


class ConsumptionRecord(BaseModel):
    """
    Acumulado por cuenta, período y métrica. Se escribe siempre, se cobre o no.

    El período es texto con año y mes en vez de una fecha porque la unidad de
    agregación es el mes calendario y una fecha invita a comparaciones por día
    que acá no significan nada.
    """

    account = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='consumption_records'
    )
    domain = models.ForeignKey(
        'domains.Domain',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='consumption_records',
    )
    period = models.CharField(max_length=7, help_text='Año y mes, en formato AAAA-MM')
    metric = models.CharField(max_length=20, choices=ConsumptionMetric.choices)
    amount = models.PositiveIntegerField(default=0)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['account', 'domain', 'period', 'metric'],
                name='one_total_per_account_domain_period_and_metric',
            )
        ]
        indexes = [models.Index(fields=['account', 'period'])]

    def __str__(self) -> str:
        return f'{self.period} {self.metric}: {self.amount}'
