from django.db import models
from django.utils.text import slugify
from django.utils import timezone
from django_ckeditor_5.fields import CKEditor5Field
from apps.accounts.models import User
from apps.accounts.fields import WebPImageField


class InsightCategory(models.Model):
    tenant = models.ForeignKey(
        'tenants.Tenant', on_delete=models.CASCADE,
        null=True, blank=True, related_name='insight_categories'
    )
    name  = models.CharField(max_length=100)
    slug  = models.SlugField(max_length=120)
    order = models.PositiveIntegerField(default=1)

    class Meta:
        ordering = ['order']
        unique_together = [('tenant', 'slug')]
        verbose_name = 'Insight Category'
        verbose_name_plural = 'Insight Categories'

    def __str__(self):
        return self.name


class Insight(models.Model):
    STATUS_DRAFT        = 'draft'
    STATUS_REVIEW       = 'review'
    STATUS_APPROVED     = 'approved'
    STATUS_READY        = 'ready'
    STATUS_SCHEDULED    = 'scheduled'
    STATUS_PUBLISHED    = 'published'
    STATUS_NEEDS_UPDATE = 'needs_update'
    STATUS_CHOICES = [
        (STATUS_DRAFT,        'Draft'),
        (STATUS_REVIEW,       'In Review'),
        (STATUS_APPROVED,     'Approved'),
        (STATUS_READY,        'Ready to Publish'),
        (STATUS_SCHEDULED,    'Scheduled'),
        (STATUS_PUBLISHED,    'Published'),
        (STATUS_NEEDS_UPDATE, 'Needs Update'),
    ]

    PRIORITY_CRITICAL = 'critical'
    PRIORITY_HIGH     = 'high'
    PRIORITY_MEDIUM   = 'medium'
    PRIORITY_LOW      = 'low'
    PRIORITY_CHOICES = [
        (PRIORITY_CRITICAL, 'Critical'),
        (PRIORITY_HIGH,     'High'),
        (PRIORITY_MEDIUM,   'Medium'),
        (PRIORITY_LOW,      'Low'),
    ]

    TYPE_PILLAR  = 'pillar'
    TYPE_CLUSTER = 'cluster'
    TYPE_CHOICES = [
        (TYPE_PILLAR,  'Pillar'),
        (TYPE_CLUSTER, 'Cluster'),
    ]

    # ── Core ───────────────────────────────────────────────────────────────────
    tenant      = models.ForeignKey(
        'tenants.Tenant', on_delete=models.CASCADE,
        null=True, blank=True, related_name='insights'
    )
    title       = models.CharField(max_length=300)
    slug        = models.SlugField(max_length=350, blank=True)
    category    = models.ForeignKey(InsightCategory, on_delete=models.SET_NULL, null=True, blank=True)
    author      = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
    excerpt     = models.TextField(help_text='Short summary shown on cards and homepage')
    body        = CKEditor5Field(config_name='extended')
    thumbnail   = WebPImageField(upload_to='insights/')
    image_alt   = models.CharField(max_length=200, blank=True, help_text='Alt text for the thumbnail (SEO + accessibility)')
    status      = models.CharField(max_length=20, choices=STATUS_CHOICES, default=STATUS_DRAFT)
    published_at = models.DateTimeField(null=True, blank=True)
    meta_description = models.TextField(blank=True)
    read_time   = models.PositiveIntegerField(default=3, help_text='Estimated read time in minutes')
    view_count  = models.PositiveIntegerField(default=0, editable=False)
    created_at  = models.DateTimeField(auto_now_add=True)
    updated_at  = models.DateTimeField(auto_now=True)

    # ── SEO ────────────────────────────────────────────────────────────────────
    meta_title      = models.CharField(max_length=70, blank=True,
                          help_text='SEO title (30-60 chars). Leave empty to use article title.')
    focus_keyword   = models.CharField(max_length=100, blank=True)
    canonical_url   = models.URLField(blank=True,
                          help_text='Leave empty to auto-generate from page URL')
    og_image_url    = models.URLField(blank=True,
                          help_text='Social share image override. Leave empty to use thumbnail.')
    tags            = models.CharField(max_length=500, blank=True,
                          help_text='Comma-separated internal tags (country, service, content type…)')
    target_region   = models.CharField(max_length=10, blank=True, default='global',
                          choices=[
                              ('global',  'Global'),
                              ('europe',  'Europe'),
                              ('uk',      'United Kingdom'),
                              ('ir',      'Iran'),
                              ('gcc',     'GCC'),
                          ],
                          help_text='Primary target region for SEO/GEO signals')

    # ── GEO / AI Visibility ────────────────────────────────────────────────────
    tldr            = models.TextField(blank=True,
                          help_text='TL;DR shown at top of article. Critical for AI Overview / GEO.')
    faq_json        = models.TextField(blank=True,
                          help_text='JSON: [{"q":"...","a":"..."}]')
    sources_json    = models.TextField(blank=True,
                          help_text='JSON: [{"title":"...","url":"..."}]')

    # ── Content structure ──────────────────────────────────────────────────────
    article_type    = models.CharField(max_length=10, choices=TYPE_CHOICES, default=TYPE_PILLAR)
    pillar          = models.ForeignKey('self', null=True, blank=True,
                          on_delete=models.SET_NULL, related_name='clusters',
                          help_text='For cluster articles: link to the parent pillar post')
    priority        = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default=PRIORITY_MEDIUM)

    # ── Author E-E-A-T ─────────────────────────────────────────────────────────
    author_title    = models.CharField(max_length=100, blank=True,
                          help_text='Job title / expertise for schema (e.g. Senior SEO Strategist)')
    author_bio      = models.TextField(blank=True,
                          help_text='Short bio for Article schema E-E-A-T signal')
    author_linkedin = models.URLField(blank=True)

    # ── Visibility & Feature ───────────────────────────────────────────────────
    is_visible      = models.BooleanField(default=True,
                          help_text='Uncheck to hide from public site without changing status')
    is_featured     = models.BooleanField(default=False,
                          help_text='Featured posts appear first on the insights listing')
    scheduled_at    = models.DateTimeField(null=True, blank=True,
                          help_text='Set a future date/time to auto-publish. Status must be Scheduled.')

    # ── SEO score (stored, recomputed on every save) ───────────────────────────
    seo_score       = models.PositiveSmallIntegerField(default=0, editable=False,
                          help_text='Auto-computed 0-100. Posts below 60 are hidden from the public site.')

    # ── Editorial ──────────────────────────────────────────────────────────────
    update_date     = models.DateField(null=True, blank=True,
                          help_text='Date of last significant content update')
    revision_note   = models.CharField(max_length=300, blank=True,
                          help_text='What changed in this revision?')

    class Meta:
        ordering = ['-published_at', '-created_at']
        unique_together = [('tenant', 'slug')]
        verbose_name = 'Insight'
        verbose_name_plural = 'Insights'

    def __str__(self):
        return self.title

    def compute_seo_score(self):
        """Return 0-100 SEO score based on 13 checks."""
        import json
        score = 0
        if self.title:                                            score += 1
        tl = len(self.meta_title or '')
        if 30 <= tl <= 60:                                        score += 1
        dl = len(self.meta_description or '')
        if 50 <= dl <= 160:                                       score += 1
        if self.focus_keyword:                                    score += 1
        if self.canonical_url:                                    score += 1
        if self.tldr:                                             score += 1
        try:
            if any(f.get('q') and f.get('a')
                   for f in (json.loads(self.faq_json) if self.faq_json else [])):
                score += 1
        except Exception:
            pass
        if self.thumbnail:                                        score += 1
        if self.og_image_url or self.thumbnail:                   score += 1
        try:
            if any(s.get('url')
                   for s in (json.loads(self.sources_json) if self.sources_json else [])):
                score += 1
        except Exception:
            pass
        if self.author_title:                                     score += 1
        if self.author_bio:                                       score += 1
        if self.tags:                                             score += 1
        return round(score / 13 * 100)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        # Auto-set published_at when publishing
        if self.status == self.STATUS_PUBLISHED and not self.published_at:
            self.published_at = self.scheduled_at or timezone.now()
        # Recompute score unless caller is doing a narrow update_fields that excludes it
        update_fields = kwargs.get('update_fields')
        if update_fields is None or 'seo_score' in update_fields:
            self.seo_score = self.compute_seo_score()
        super().save(*args, **kwargs)
