"""Subscription checkout and activation after payment."""
import random
import string
from datetime import timedelta

from django.utils import timezone

from companies.models import Company
from subscriptions.benefits import sync_company_subscription_benefits, sync_seeker_subscription_benefits
from subscriptions.models import (
    CompanySubscription,
    PaymentMethod,
    SeekerSubscription,
    SubscriptionPayment,
    SubscriptionPlan,
)


def plan_allowed_for_user(plan, user):
    if not user or not user.is_authenticated:
        return False
    if user.is_platform_admin:
        return True
    if plan.audience == SubscriptionPlan.Audience.SEEKER:
        return user.is_seeker
    if plan.audience == SubscriptionPlan.Audience.COMPANY:
        return user.is_company
    return False


def subscription_expiry_for_plan(plan):
    label = (plan.price_label or '').lower()
    slug = plan.slug.lower()
    if 'year' in label or 'annual' in label or 'enterprise' in slug:
        return timezone.now() + timedelta(days=365)
    if 'quarter' in label or '6 month' in label or 'half' in label:
        return timezone.now() + timedelta(days=182)
    return timezone.now() + timedelta(days=30)


def generate_txn_reference(user_id, plan_id):
    suffix = ''.join(random.choice(string.digits) for _ in range(6))
    stamp = timezone.now().strftime('%d%m%Y%H%M%S')
    return f'sub-{suffix}{stamp}-{user_id}-{plan_id}'


def create_pending_payment(user, plan, payment_method_slug, txn_reference, provider_reference=''):
    payment_method = PaymentMethod.objects.filter(slug=payment_method_slug, is_active=True).first()
    company = Company.objects.filter(owner=user, is_active=True).first() if user.is_company else None
    return SubscriptionPayment.objects.create(
        user=user,
        company=company,
        plan=plan,
        payment_method=payment_method,
        amount=plan.price_monthly,
        txn_reference=txn_reference,
        provider_reference=provider_reference,
        status=SubscriptionPayment.Status.PENDING,
        expires_at=subscription_expiry_for_plan(plan),
    )


def activate_subscription_payment(payment, provider_reference=''):
    payment.status = SubscriptionPayment.Status.PAID
    payment.paid_at = timezone.now()
    if provider_reference:
        payment.provider_reference = provider_reference
    payment.save(update_fields=['status', 'paid_at', 'provider_reference'])

    user = payment.user
    plan = payment.plan
    expires_at = payment.expires_at or subscription_expiry_for_plan(plan)

    if plan.audience == SubscriptionPlan.Audience.SEEKER:
        subscription, _created = SeekerSubscription.objects.update_or_create(
            user=user,
            defaults={
                'plan': plan,
                'is_active': True,
                'expires_at': expires_at,
            },
        )
        sync_seeker_subscription_benefits(subscription)
    else:
        company = payment.company or Company.objects.filter(owner=user, is_active=True).first()
        if not company:
            return False
        subscription, _created = CompanySubscription.objects.update_or_create(
            company=company,
            defaults={
                'plan': plan,
                'is_active': True,
                'started_at': timezone.now(),
                'expires_at': expires_at,
                'legacy_txn': payment.txn_reference,
            },
        )
        sync_company_subscription_benefits(subscription)
    from accounts import events

    events.subscription_activated(user, plan, expires_at)
    return True


def reject_subscription_payment(payment):
    payment.status = SubscriptionPayment.Status.REJECTED
    payment.save(update_fields=['status'])


def verify_pending_payment(payment):
    """Poll DPO and update payment. Returns success, rejected, or pending."""
    if payment.status == SubscriptionPayment.Status.PAID:
        return 'success'
    if payment.status == SubscriptionPayment.Status.REJECTED:
        return 'rejected'
    provider_reference = payment.provider_reference
    if not provider_reference:
        return 'rejected'

    from subscriptions.dpo_client import DPOClient

    verification = DPOClient.verify_token(provider_reference)
    if verification == 'success':
        activate_subscription_payment(payment, provider_reference=provider_reference)
        return 'success'
    if verification == 'rejected':
        reject_subscription_payment(payment)
        return 'rejected'
    return 'pending'
