# -*- coding: utf-8 -*-
from django.db import models
from django.conf import settings
from django.core.validators import RegexValidator
from django.utils import timezone
from django_tenants.models import TenantMixin, DomainMixin
from phonenumber_field.modelfields import PhoneNumberField
from datetime import timedelta


# Зарезервированные имена схем, которые нельзя использовать
RESERVED_SCHEMA_NAMES = [
    'public', 'admin', 'api', 'www', 'mail', 'ftp', 'smtp',
    'static', 'media', 'assets', 'cdn', 'app', 'web',
    'billing', 'register', 'login', 'logout', 'dashboard',
    'test', 'dev', 'staging', 'production', 'demo'
]


class Client(TenantMixin):
    """
    Модель тенанта (владельца магазина).
    Каждый тенант = отдельная схема в PostgreSQL с изолированными данными.
    """
    name = models.CharField(
        max_length=200,
        db_index=True,
        verbose_name="Название магазина"
    )

    owner_email = models.EmailField(
        verbose_name="Email владельца",
        help_text="Контактный email владельца магазина. Один email может использоваться для нескольких магазинов (для супер-админа)"
    )

    owner_name = models.CharField(
        max_length=200,
        blank=True,
        null=True,
        verbose_name="Имя владельца"
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Дата создания"
    )

    is_active = models.BooleanField(
        default=True,
        verbose_name="Активен",
        help_text="Активна ли учетная запись магазина (ручная блокировка админом)"
    )

    # Дополнительные поля для будущего расширения
    phone = PhoneNumberField(
        blank=True,
        null=True,
        verbose_name="Телефон"
    )

    notes = models.TextField(
        blank=True,
        null=True,
        verbose_name="Заметки",
        help_text="Внутренние заметки администратора"
    )

    class Meta:
        verbose_name = "Тенант (Магазин)"
        verbose_name_plural = "Тенанты (Магазины)"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.name} ({self.schema_name})"

    # auto_create_schema наследуется от TenantMixin
    # auto_drop_schema наследуется от TenantMixin
    auto_create_schema = True  # Автоматически создавать схему при создании тенанта


class Domain(DomainMixin):
    """
    Модель домена для тенанта.
    Связывает поддомен (например shop1.inventory.by) с тенантом.
    """
    class Meta:
        verbose_name = "Домен"
        verbose_name_plural = "Домены"

    def __str__(self):
        return self.domain


class TenantRegistration(models.Model):
    """
    Модель заявки на регистрацию нового тенанта.
    Заявки сначала создаются со статусом 'pending', затем админ их активирует.
    """
    STATUS_PENDING = 'pending'
    STATUS_APPROVED = 'approved'
    STATUS_REJECTED = 'rejected'

    STATUS_CHOICES = [
        (STATUS_PENDING, 'Ожидает проверки'),
        (STATUS_APPROVED, 'Одобрено'),
        (STATUS_REJECTED, 'Отклонено'),
    ]

    # Данные от пользователя
    shop_name = models.CharField(
        max_length=200,
        verbose_name="Название магазина"
    )

    schema_name = models.CharField(
        max_length=63,
        unique=True,
        validators=[
            RegexValidator(
                regex=r'^[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?$',
                message='Поддомен должен содержать только латинские буквы в нижнем регистре, цифры и дефис. '
                        'Длина от 3 до 63 символов. Не может начинаться или заканчиваться дефисом.'
            )
        ],
        verbose_name="Желаемый поддомен",
        help_text="Например: myshop (будет доступен как myshop.inventory.by)"
    )

    owner_email = models.EmailField(
        verbose_name="Email владельца"
    )

    owner_name = models.CharField(
        max_length=200,
        verbose_name="Имя владельца"
    )

    phone = PhoneNumberField(
        verbose_name="Телефон"
    )

    # Служебные поля
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default=STATUS_PENDING,
        db_index=True,
        verbose_name="Статус"
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Дата подачи заявки"
    )

    processed_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Дата обработки"
    )

    processed_by = models.ForeignKey(
        'platform_admin.PlatformAdmin',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="Обработал",
        help_text="Администратор платформы, который обработал заявку"
    )

    rejection_reason = models.TextField(
        blank=True,
        verbose_name="Причина отклонения"
    )

    # Ссылка на созданный тенант (заполняется после активации)
    tenant = models.OneToOneField(
        Client,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name="Созданный тенант"
    )

    # Поля для установки пароля владельцем
    password_setup_token = models.UUIDField(
        null=True,
        blank=True,
        unique=True,
        verbose_name="Токен установки пароля",
        help_text="UUID токен для ссылки установки пароля владельцем"
    )

    password_setup_token_created_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Дата создания токена",
        help_text="Когда был создан токен установки пароля (действителен 7 дней)"
    )

    owner_notified_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name="Дата уведомления владельца",
        help_text="Когда было отправлено письмо владельцу с ссылкой установки пароля"
    )

    class Meta:
        verbose_name = "Заявка на регистрацию"
        verbose_name_plural = "Заявки на регистрацию"
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.shop_name} ({self.schema_name}) - {self.get_status_display()}"


class Subscription(models.Model):
    """
    Модель подписки тенанта.
    Определяет план подписки и срок действия.
    """
    PLAN_TRIAL = 'trial'
    PLAN_MONTHLY = 'monthly'
    PLAN_QUARTERLY = 'quarterly'
    PLAN_YEARLY = 'yearly'

    PLAN_CHOICES = [
        (PLAN_TRIAL, 'Триальный (90 дней)'),
        (PLAN_MONTHLY, 'Месячный'),
        (PLAN_QUARTERLY, 'Квартальный (3 месяца)'),
        (PLAN_YEARLY, 'Годовой'),
    ]

    client = models.OneToOneField(
        Client,
        on_delete=models.CASCADE,
        related_name='subscription',
        verbose_name="Тенант"
    )

    plan = models.CharField(
        max_length=20,
        choices=PLAN_CHOICES,
        default=PLAN_TRIAL,
        verbose_name="План подписки"
    )

    started_at = models.DateTimeField(
        verbose_name="Дата начала"
    )

    expires_at = models.DateTimeField(
        verbose_name="Дата окончания"
    )

    is_active = models.BooleanField(
        default=True,
        verbose_name="Активна",
        help_text="Активна ли подписка (может быть отключена вручную)"
    )

    auto_renew = models.BooleanField(
        default=False,
        verbose_name="Автопродление",
        help_text="Автоматически продлевать подписку"
    )

    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name="Дата создания"
    )

    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name="Дата обновления"
    )

    class Meta:
        verbose_name = "Подписка"
        verbose_name_plural = "Подписки"
        ordering = ['-expires_at']

    def __str__(self):
        return f"{self.client.name} - {self.get_plan_display()} (до {self.expires_at.date()})"

    def is_expired(self):
        """Проверка истечения подписки"""
        if not self.expires_at:
            return False
        return timezone.now() > self.expires_at

    def days_left(self):
        """Количество дней до окончания подписки"""
        if not self.expires_at:
            return 0
        if self.is_expired():
            return 0
        delta = self.expires_at - timezone.now()
        return max(delta.days, 0)

    @staticmethod
    def create_trial(client):
        """Создать триальную подписку на 90 дней"""
        now = timezone.now()
        return Subscription.objects.create(
            client=client,
            plan=Subscription.PLAN_TRIAL,
            started_at=now,
            expires_at=now + timedelta(days=90),
            is_active=True
        )
