from decimal import Decimal

from django.db import models
from django.urls import reverse


class PilotCall(models.Model):
    SOURCE_YTEL = 'ytel'
    SOURCE_RINGCENTRAL = 'ringcentral'
    SOURCE_MANUAL = 'manual'

    CALL_SOURCE_CHOICES = [
        (SOURCE_YTEL, 'Ytel'),
        (SOURCE_RINGCENTRAL, 'RingCentral fallback'),
        (SOURCE_MANUAL, 'Manual/recording test'),
    ]

    STATUS_UNCONFIRMED = 'unconfirmed'
    STATUS_AVAILABLE = 'available'
    STATUS_BLOCKED = 'blocked'
    STATUS_PARTNER = 'partner'

    INTEGRATION_STATUS_CHOICES = [
        (STATUS_UNCONFIRMED, 'Not confirmed'),
        (STATUS_AVAILABLE, 'Available'),
        (STATUS_BLOCKED, 'Blocked / not exposed'),
        (STATUS_PARTNER, 'Needs enterprise/partner access'),
    ]

    client_name = models.CharField(max_length=140)
    phone = models.CharField(max_length=40)
    email = models.EmailField(blank=True)
    call_source = models.CharField(max_length=24, choices=CALL_SOURCE_CHOICES, default=SOURCE_YTEL)
    ytel_audio_status = models.CharField(max_length=24, choices=INTEGRATION_STATUS_CHOICES, default=STATUS_UNCONFIRMED)
    logics_api_status = models.CharField(max_length=24, choices=INTEGRATION_STATUS_CHOICES, default=STATUS_UNCONFIRMED)

    transcript = models.TextField(help_text='Paste a live transcript segment or recorded-call transcript for the pilot.')
    irs_debt = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    state_debt = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    tax_years = models.CharField(max_length=120, blank=True)
    filing_status = models.CharField(max_length=80, blank=True)
    employment_type = models.CharField(max_length=120, blank=True)
    occupation = models.CharField(max_length=120, blank=True)
    monthly_gross_income = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    spouse_income = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    mortgage = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    rent = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    utilities = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    car_payment = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    insurance = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    student_loans = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    credit_cards = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    assets = models.TextField(blank=True)
    business_expenses = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
    irs_payment_plan = models.BooleanField(default=False)
    levy = models.BooleanField(default=False)
    garnishment = models.BooleanField(default=False)
    best_callback_time = models.CharField(max_length=120, blank=True)
    agent_notes = models.TextField(blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = 'pilot call'
        verbose_name_plural = 'pilot calls'

    def __str__(self):
        return f'{self.client_name} · {self.get_call_source_display()}'

    def get_absolute_url(self):
        return reverse('call_detail', args=[self.pk])

    @property
    def required_fields(self):
        return [
            ('IRS debt', self.irs_debt),
            ('Tax years', self.tax_years),
            ('Employment', self.employment_type),
            ('Monthly income', self.monthly_gross_income),
            ('Best callback', self.best_callback_time),
        ]

    @property
    def completion_score(self):
        if not self.required_fields:
            return 0
        completed = sum(1 for _label, value in self.required_fields if self._has_value(value))
        return round((completed / len(self.required_fields)) * 100)

    @property
    def missing_required_labels(self):
        return [label for label, value in self.required_fields if not self._has_value(value)]

    @property
    def urgent_flags(self):
        flags = []
        if self.levy:
            flags.append('Levy mentioned')
        if self.garnishment:
            flags.append('Wage garnishment mentioned')
        if self.irs_debt and self.irs_debt > Decimal('50000'):
            flags.append('Debt over $50,000')
        if self.monthly_gross_income is not None and self.monthly_gross_income <= 0:
            flags.append('No monthly income captured')
        return flags

    @staticmethod
    def _has_value(value):
        if value is None:
            return False
        if isinstance(value, str):
            return bool(value.strip())
        return True



class WebhookEvent(models.Model):
    PROVIDER_GENERIC = 'generic'

    provider = models.CharField(max_length=60, default=PROVIDER_GENERIC)
    event_type = models.CharField(max_length=120, blank=True)
    external_id = models.CharField(max_length=160, blank=True)
    delivery_id = models.CharField(max_length=160, blank=True)
    source_ip = models.GenericIPAddressField(null=True, blank=True)
    content_type = models.CharField(max_length=180, blank=True)
    headers = models.JSONField(default=dict, blank=True)
    query_params = models.JSONField(default=dict, blank=True)
    payload = models.JSONField(default=dict, blank=True)
    raw_body = models.TextField(blank=True)
    processed = models.BooleanField(default=False)
    notes = models.TextField(blank=True)
    received_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-received_at']
        indexes = [
            models.Index(fields=['provider', 'event_type']),
            models.Index(fields=['received_at']),
        ]
        verbose_name = 'webhook event'
        verbose_name_plural = 'webhook events'

    def __str__(self):
        label = self.event_type or self.external_id or f'event #{self.pk}'
        return f'{self.provider}: {label}'

    @property
    def display_event_type(self):
        return self.event_type or 'unclassified'
