# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib import messages
from django.utils import timezone
from django.utils.html import format_html
from django.urls import reverse
from .models import Client, Domain, TenantRegistration, Subscription


class DomainInline(admin.TabularInline):
    """
    Inline для управления доменами тенанта.
    """
    model = Domain
    extra = 1
    fields = ['domain', 'is_primary']


@admin.register(Client)
class ClientAdmin(admin.ModelAdmin):
    """
    Админ-панель для управления тенантами (магазинами).
    ВАЖНО: Эта админка доступна только в Public схеме!
    """
    list_display = [
        'name',
        'schema_name',
        'owner_email',
        'is_active',
        'created_at',
        'subscription_status',
    ]

    list_filter = [
        'is_active',
        'created_at',
    ]

    search_fields = [
        'name',
        'schema_name',
        'owner_email',
        'owner_name',
    ]

    # Убираем schema_name из readonly при создании нового тенанта
    def get_readonly_fields(self, request, obj=None):
        if obj:  # Редактирование существующего тенанта
            return ['schema_name', 'created_at']
        else:  # Создание нового тенанта
            return ['created_at']

    fieldsets = (
        ('Информация о магазине', {
            'fields': ('name', 'schema_name', 'is_active')
        }),
        ('Владелец', {
            'fields': ('owner_name', 'owner_email', 'phone')
        }),
        ('Дополнительно', {
            'fields': ('created_at', 'notes'),
            'classes': ('collapse',)
        }),
    )

    inlines = [DomainInline]

    def subscription_status(self, obj):
        """Отображение статуса подписки"""
        try:
            sub = obj.subscription
            if sub.is_expired():
                return format_html('<span style="color: red;">Истекла {}</span>', sub.expires_at.date())
            elif sub.days_left() <= 7:
                return format_html('<span style="color: orange;">Осталось {} дн.</span>', sub.days_left())
            else:
                return format_html('<span style="color: green;">{} до {}</span>',
                                   sub.get_plan_display(), sub.expires_at.date())
        except Subscription.DoesNotExist:
            return format_html('<span style="color: gray;">Нет подписки</span>')

    subscription_status.short_description = "Подписка"

    def has_delete_permission(self, request, obj=None):
        """
        Запрещаем удаление тенантов через админку (для безопасности).
        Удаление должно происходить через специальную команду.
        """
        return False


@admin.register(Domain)
class DomainAdmin(admin.ModelAdmin):
    """
    Админ-панель для управления доменами.
    """
    list_display = [
        'domain',
        'tenant',
        'is_primary',
    ]

    list_filter = [
        'is_primary',
    ]

    search_fields = [
        'domain',
        'tenant__name',
        'tenant__schema_name',
    ]


@admin.register(TenantRegistration)
class TenantRegistrationAdmin(admin.ModelAdmin):
    """
    Админка для управления заявками на регистрацию
    """
    list_display = ("shop_name", "schema_name", "owner_email", "status", "created_at", "actions_column")
    list_filter = ("status", "created_at")
    search_fields = ("shop_name", "schema_name", "owner_email", "owner_name")
    readonly_fields = ("created_at", "processed_at", "processed_by", "tenant")

    fieldsets = (
        ("Информация о магазине", {
            "fields": ("shop_name", "schema_name")
        }),
        ("Владелец", {
            "fields": ("owner_name", "owner_email", "phone")
        }),
        ("Статус", {
            "fields": ("status", "created_at", "processed_at", "processed_by", "rejection_reason")
        }),
        ("Результат", {
            "fields": ("tenant",)
        }),
    )

    actions = ['approve_registrations', 'reject_registrations', 'resend_password_setup_email']

    def actions_column(self, obj):
        """Кнопки действий для каждой заявки"""
        if obj.status == TenantRegistration.STATUS_PENDING:
            approve_url = reverse('admin:tenants_tenantregistration_change', args=[obj.pk])
            return format_html(
                '<div style="display: flex; flex-direction: column; gap: 5px; min-width: 140px;">'
                '<a class="button" href="{}?approve=1" style="background: #417690; color: white; padding: 5px 10px; text-decoration: none; border-radius: 3px; text-align: center; display: block; white-space: nowrap;">Активировать</a>'
                '<a class="button" href="{}?reject=1" style="background: #ba2121; color: white; padding: 5px 10px; text-decoration: none; border-radius: 3px; text-align: center; display: block; white-space: nowrap;">Отклонить</a>'
                '</div>',
                approve_url, approve_url
            )
        elif obj.status == TenantRegistration.STATUS_APPROVED:
            if obj.tenant:
                tenant_url = reverse('admin:tenants_client_change', args=[obj.tenant.pk])
                return format_html('<a href="{}">Перейти к тенанту →</a>', tenant_url)
            return "Одобрено"
        else:
            return "Отклонено"

    actions_column.short_description = "Действия"

    def approve_registrations(self, request, queryset):
        """Массовая активация заявок"""
        approved_count = 0
        for registration in queryset.filter(status=TenantRegistration.STATUS_PENDING):
            try:
                self._approve_registration(registration, request.user)
                approved_count += 1
            except Exception as e:
                messages.error(request, f"Ошибка при активации '{registration.shop_name}': {str(e)}")

        if approved_count > 0:
            messages.success(request, f"Успешно активировано заявок: {approved_count}")

    approve_registrations.short_description = "✓ Активировать выбранные заявки"

    def reject_registrations(self, request, queryset):
        """Массовое отклонение заявок"""
        from platform_admin.models import PlatformAdmin

        # Получаем processed_by только если это PlatformAdmin
        processed_by = request.user if isinstance(request.user, PlatformAdmin) else None

        # Обновляем каждую заявку индивидуально (нельзя использовать update с FK на другую модель)
        rejected_count = 0
        for registration in queryset.filter(status=TenantRegistration.STATUS_PENDING):
            registration.status = TenantRegistration.STATUS_REJECTED
            registration.processed_at = timezone.now()
            registration.processed_by = processed_by
            registration.rejection_reason = "Отклонено массовым действием"
            registration.save()
            rejected_count += 1

        if rejected_count > 0:
            messages.success(request, f"Отклонено заявок: {rejected_count}")

    reject_registrations.short_description = "✗ Отклонить выбранные заявки"

    def resend_password_setup_email(self, request, queryset):
        """Повторно отправить письмо с ссылкой для установки пароля"""
        from tenants.services import send_password_setup_email

        sent_count = 0
        for registration in queryset.filter(status=TenantRegistration.STATUS_APPROVED):
            try:
                send_password_setup_email(registration)
                sent_count += 1
            except Exception as e:
                messages.error(request, f"Не удалось отправить письмо для {registration.shop_name}: {e}")

        if sent_count > 0:
            messages.success(request, f"Письма повторно отправлены: {sent_count}")

    resend_password_setup_email.short_description = "📧 Отправить письмо повторно"

    def save_model(self, request, obj, form, change):
        """
        Отлавливаем изменение статуса на APPROVED и запускаем процесс активации
        """
        # Если это изменение существующего объекта
        if change:
            # Получаем старое значение из БД
            try:
                old_obj = TenantRegistration.objects.get(pk=obj.pk)
                old_status = old_obj.status
            except TenantRegistration.DoesNotExist:
                old_status = None

            # Если статус изменился на APPROVED
            if old_status == TenantRegistration.STATUS_PENDING and obj.status == TenantRegistration.STATUS_APPROVED:
                # Не сохраняем пока - сначала активируем
                try:
                    self._approve_registration(obj, request.user)
                    messages.success(request, f"Заявка '{obj.shop_name}' успешно активирована!")
                    return  # _approve_registration уже сохраняет объект
                except Exception as e:
                    messages.error(request, f"Ошибка при активации: {str(e)}")
                    # Откатываем статус обратно
                    obj.status = old_status
                    super().save_model(request, obj, form, change)
                    return

        # Обычное сохранение для всех остальных случаев
        super().save_model(request, obj, form, change)

    def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
        """
        Обработка действий активации/отклонения через GET параметры
        """
        if object_id and request.method == 'GET':
            registration = TenantRegistration.objects.get(pk=object_id)

            if 'approve' in request.GET and registration.status == TenantRegistration.STATUS_PENDING:
                try:
                    self._approve_registration(registration, request.user)
                    messages.success(request, f"Заявка '{registration.shop_name}' успешно активирована!")
                    return self._redirect_to_changelist()
                except Exception as e:
                    messages.error(request, f"Ошибка при активации: {str(e)}")

            elif 'reject' in request.GET and registration.status == TenantRegistration.STATUS_PENDING:
                from platform_admin.models import PlatformAdmin

                # Обрабатываем отклонение
                registration.status = TenantRegistration.STATUS_REJECTED
                registration.processed_at = timezone.now()
                # processed_by только если это PlatformAdmin
                registration.processed_by = request.user if isinstance(request.user, PlatformAdmin) else None
                registration.rejection_reason = "Отклонено администратором"
                registration.save()
                messages.warning(request, f"Заявка '{registration.shop_name}' отклонена.")
                return self._redirect_to_changelist()

        return super().changeform_view(request, object_id, form_url, extra_context)

    def _approve_registration(self, registration, admin_user):
        """
        Активация заявки: делегирует всю работу TenantOnboardingService.
        """
        from tenants.services import TenantOnboardingService
        return TenantOnboardingService.activate_registration(registration, admin_user)

    def _redirect_to_changelist(self):
        """Редирект на список заявок"""
        from django.shortcuts import redirect
        return redirect('admin:tenants_tenantregistration_changelist')


@admin.register(Subscription)
class SubscriptionAdmin(admin.ModelAdmin):
    """
    Админка для управления подписками
    """
    list_display = ("client", "plan", "started_at", "expires_at", "is_active", "days_left_display", "is_expired_display")
    list_filter = ("plan", "is_active", "auto_renew")
    search_fields = ("client__name", "client__schema_name")
    readonly_fields = ("created_at", "updated_at", "days_left_display", "is_expired_display")

    fieldsets = (
        ("Основная информация", {
            "fields": ("client", "plan", "is_active", "auto_renew")
        }),
        ("Период действия", {
            "fields": ("started_at", "expires_at", "days_left_display", "is_expired_display")
        }),
        ("Служебная информация", {
            "fields": ("created_at", "updated_at")
        }),
    )

    def days_left_display(self, obj):
        """Отображение оставшихся дней"""
        if not obj or not obj.expires_at:
            return "—"
        days = obj.days_left()
        if days == 0:
            return format_html('<span style="color: red;">Истекла</span>')
        elif days <= 7:
            return format_html('<span style="color: orange;">{} дн.</span>', days)
        else:
            return format_html('{} дн.', days)

    days_left_display.short_description = "Осталось"

    def is_expired_display(self, obj):
        """Отображение статуса истечения"""
        if not obj or not obj.expires_at:
            return "—"
        if obj.is_expired():
            return format_html('<span style="color: red;">Да</span>')
        else:
            return format_html('<span style="color: green;">Нет</span>')

    is_expired_display.short_description = "Истекла"
