from django.db import models
from django.utils.translation import gettext_lazy as _


class ServiceCategory(models.Model):
    """
    Categories for services, e.g. "Databases", "Storage", "Compute".
    """

    name = models.CharField(max_length=100, verbose_name=_("Name"))
    description = models.TextField(blank=True, verbose_name=_("Description"))
    logo = models.ImageField(
        upload_to="public/service_categories",
        blank=True,
        null=True,
        verbose_name=_("Logo"),
    )

    parent = models.ForeignKey(
        to="self",
        on_delete=models.CASCADE,
        related_name="children",
        blank=True,
        null=True,
        verbose_name=_("Parent"),
    )

    class Meta:
        verbose_name = _("Service category")
        verbose_name_plural = _("Service categories")

    def __str__(self):
        return self.name


class Service(models.Model):
    """
    A service that can be offered, e.g. "PostgreSQL", "MinIO", "Kubernetes".
    """

    name = models.CharField(max_length=100, verbose_name=_("Name"))
    category = models.ForeignKey(
        to="ServiceCategory",
        on_delete=models.PROTECT,
        related_name="services",
        verbose_name=_("Category"),
    )
    description = models.TextField(blank=True, verbose_name=_("Description"))
    logo = models.ImageField(
        upload_to="public/services", blank=True, null=True, verbose_name=_("Logo")
    )
    # TODO schema
    external_links = models.JSONField(
        null=True, blank=True, verbose_name=_("External links")
    )

    class Meta:
        verbose_name = _("Service")
        verbose_name_plural = _("Services")

    def __str__(self):
        return self.name


class ControlPlane(models.Model):
    name = models.CharField(max_length=100, verbose_name=_("Name"))
    description = models.TextField(blank=True, verbose_name=_("Description"))
    k8s_api_endpoint = models.URLField(verbose_name=_("Kubernetes API endpoint"))
    # TODO: schema
    api_credentials = models.JSONField(verbose_name=_("API credentials"))

    cloud_provider = models.ForeignKey(
        to="CloudProvider",
        on_delete=models.PROTECT,
        related_name="control_planes",
        verbose_name=_("Cloud provider"),
    )

    class Meta:
        verbose_name = _("Control plane")
        verbose_name_plural = _("Control planes")

    def __str__(self):
        return self.name


class CloudProvider(models.Model):
    """
    A cloud provider, e.g. "Exoscale".
    """

    name = models.CharField(max_length=100, verbose_name=_("Name"))
    description = models.TextField(blank=True, verbose_name=_("Description"))
    logo = models.ImageField(
        upload_to="public/service_providers",
        blank=True,
        null=True,
        verbose_name=_("Logo"),
    )
    external_links = models.JSONField(
        null=True, blank=True, verbose_name=_("External links")
    )

    class Meta:
        verbose_name = _("Cloud provider")
        verbose_name_plural = _("Cloud providers")

    def __str__(self):
        return self.name


class Plan(models.Model):
    """
    Each service offering can have multiple plans, e.g. for different tiers.
    """

    name = models.CharField(max_length=100, verbose_name=_("Name"))
    description = models.TextField(blank=True, verbose_name=_("Description"))
    # TODO schema
    features = models.JSONField(verbose_name=_("Features"), null=True, blank=True)
    # TODO schema
    pricing = models.JSONField(verbose_name=_("Pricing"), null=True, blank=True)
    term = models.PositiveIntegerField(
        verbose_name=_("Term"), help_text=_("Term in months")
    )
    service_offering = models.ForeignKey(
        to="ServiceOffering",
        on_delete=models.PROTECT,
        related_name="plans",
        verbose_name=_("Service offering"),
    )

    class Meta:
        verbose_name = _("Plan")
        verbose_name_plural = _("Plans")

    def __str__(self):
        return self.name


class ServiceOffering(models.Model):
    """
    A service offering, e.g. "PostgreSQL on AWS", "MinIO on GCP".
    """

    service = models.ForeignKey(
        to="Service",
        on_delete=models.PROTECT,
        related_name="offerings",
        verbose_name=_("Service"),
    )
    provider = models.ForeignKey(
        to="CloudProvider",
        on_delete=models.PROTECT,
        related_name="offerings",
        verbose_name=_("Provider"),
    )
    control_plane = models.ManyToManyField(
        to="ControlPlane",
        related_name="offerings",
        verbose_name=_("Control planes"),
    )
    description = models.TextField(blank=True, verbose_name=_("Description"))

    class Meta:
        verbose_name = _("Service offering")
        verbose_name_plural = _("Service offerings")
