from django.conf import settings
from django.db import models
from django.utils import timezone
from django.utils.text import slugify


class SubscriptionPlan(models.Model):
    class Audience(models.TextChoices):
        SEEKER = 'seeker', 'Job Seekers'
        COMPANY = 'company', 'Employers'

    class Category(models.TextChoices):
        MEMBERSHIP = 'membership', 'Professional Membership'
        RECRUITMENT = 'recruitment', 'Employer Recruitment'
        TALENT_DATABASE = 'talent_database', 'Talent Database Access'

    name = models.CharField(max_length=80)
    slug = models.SlugField(max_length=100, unique=True)
    audience = models.CharField(max_length=20, choices=Audience.choices)
    category = models.CharField(
        max_length=20,
        choices=Category.choices,
        default=Category.MEMBERSHIP,
    )
    price_monthly = models.PositiveIntegerField(default=0)
    price_label = models.CharField(max_length=80, default='/month, billed monthly')
    description = models.TextField(blank=True)
    features = models.TextField(help_text='One feature per line. Prefix with ! for unavailable features.')
    is_featured = models.BooleanField(default=False)
    sort_order = models.PositiveSmallIntegerField(default=0)
    is_active = models.BooleanField(default=True)

    class Meta:
        ordering = ['audience', 'sort_order', 'price_monthly']

    def __str__(self):
        return f'{self.name} ({self.get_audience_display()})'

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

    @property
    def feature_list(self):
        return [line.strip() for line in self.features.splitlines() if line.strip()]


class SeekerSubscription(models.Model):
    """Paid seeker membership - unlocks priority job alerts and other Plus features."""
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='seeker_subscription',
    )
    plan = models.ForeignKey(
        SubscriptionPlan,
        on_delete=models.PROTECT,
        limit_choices_to={'audience': SubscriptionPlan.Audience.SEEKER},
        related_name='seeker_subscriptions',
    )
    is_active = models.BooleanField(default=True)
    started_at = models.DateTimeField(auto_now_add=True)
    expires_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text='Leave blank for no expiry (manual/admin activation).',
    )

    class Meta:
        verbose_name = 'Seeker subscription'
        verbose_name_plural = 'Seeker subscriptions'

    def __str__(self):
        return f'{self.user.email} – {self.plan.name}'

    @property
    def is_valid(self):
        if not self.is_active:
            return False
        if self.expires_at and self.expires_at <= timezone.now():
            return False
        return True

    @property
    def effective_benefits(self):
        from .plan_limits import get_seeker_plan_benefits

        if not self.is_valid:
            from .plan_limits import DEFAULT_SEEKER_FREE
            return DEFAULT_SEEKER_FREE
        return get_seeker_plan_benefits(self.plan.slug)


class CompanySubscription(models.Model):
    """Paid employer recruitment plan tied to a company profile."""
    company = models.OneToOneField(
        'companies.Company',
        on_delete=models.CASCADE,
        related_name='subscription',
    )
    plan = models.ForeignKey(
        SubscriptionPlan,
        on_delete=models.PROTECT,
        limit_choices_to={'audience': SubscriptionPlan.Audience.COMPANY},
        related_name='company_subscriptions',
    )
    is_active = models.BooleanField(default=True)
    started_at = models.DateTimeField(null=True, blank=True)
    expires_at = models.DateTimeField(
        null=True,
        blank=True,
        help_text='Leave blank for no expiry (manual/admin activation).',
    )
    legacy_txn = models.CharField(max_length=120, blank=True)

    class Meta:
        verbose_name = 'Company subscription'
        verbose_name_plural = 'Company subscriptions'

    def __str__(self):
        return f'{self.company.name} – {self.plan.name}'

    @property
    def is_valid(self):
        if not self.is_active:
            return False
        if self.expires_at and self.expires_at <= timezone.now():
            return False
        return True

    @property
    def effective_benefits(self):
        from .plan_limits import DEFAULT_COMPANY_NO_SUB, get_company_plan_benefits

        if not self.is_valid:
            return DEFAULT_COMPANY_NO_SUB
        return get_company_plan_benefits(self.plan.slug)


class SubscriptionUsageEvent(models.Model):
    class EventType(models.TextChoices):
        CV_PROFILE_VIEW = 'cv_profile_view', 'Candidate profile view'
        CV_DOWNLOAD = 'cv_download', 'CV download'

    company = models.ForeignKey(
        'companies.Company',
        on_delete=models.CASCADE,
        related_name='subscription_usage_events',
    )
    actor = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='subscription_usage_events',
    )
    event_type = models.CharField(max_length=30, choices=EventType.choices)
    seeker_profile = models.ForeignKey(
        'seekers.SeekerProfile',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='subscription_usage_events',
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['company', 'event_type', 'created_at']),
        ]

    def __str__(self):
        return f'{self.company.name} – {self.get_event_type_display()}'


class PaymentMethod(models.Model):
    """Supported checkout methods (mobile money, card, PayPal, DPO)."""
    slug = models.SlugField(max_length=40, unique=True)
    name = models.CharField(max_length=80)
    description = models.CharField(max_length=255, blank=True)
    is_active = models.BooleanField(default=True)
    sort_order = models.PositiveSmallIntegerField(default=0)
    legacy_id = models.PositiveIntegerField(null=True, blank=True, unique=True)

    class Meta:
        ordering = ['sort_order', 'name']

    def __str__(self):
        return self.name


class SubscriptionPayment(models.Model):
    """Payment record for a subscription purchase (imported from legacy or live checkout)."""
    class Status(models.TextChoices):
        PENDING = 'pending', 'Pending'
        PAID = 'paid', 'Paid'
        DELIVERED = 'delivered', 'Delivered'
        REJECTED = 'rejected', 'Rejected'
        FAILED = 'failed', 'Failed'

    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='subscription_payments',
    )
    company = models.ForeignKey(
        'companies.Company',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='subscription_payments',
    )
    plan = models.ForeignKey(
        SubscriptionPlan,
        on_delete=models.PROTECT,
        related_name='payments',
    )
    payment_method = models.ForeignKey(
        PaymentMethod,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='payments',
    )
    amount = models.PositiveIntegerField(default=0, help_text='Amount in ZMW (whole kwacha).')
    currency = models.CharField(max_length=3, default='ZMW')
    txn_reference = models.CharField(max_length=120, blank=True, db_index=True)
    provider_reference = models.CharField(max_length=120, blank=True)
    status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING)
    paid_at = models.DateTimeField(null=True, blank=True)
    expires_at = models.DateTimeField(null=True, blank=True)
    legacy_subscription_id = models.PositiveIntegerField(null=True, blank=True, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']

    def __str__(self):
        return f'{self.user.email} – {self.plan.name} ({self.status})'
