from django.db import models
from django.conf import settings
from cryptography.fernet import Fernet


class InfluencerProfile(models.Model):
    """
    Influencer Profile Model - Stores all calculated metrics and final data
    for each influencer after processing Instagram API data.
    
    This model holds the 14 key metrics + AI-generated niche that will be
    displayed to businesses searching for influencers.
    """
    
    # One-to-One relationship with User
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='influencer_profile',
        help_text="Associated user account"
    )
    
    # ========================================================================
    # INSTAGRAM ACCOUNT INFORMATION
    # ========================================================================
    
    instagram_handle = models.CharField(
        max_length=100,
        unique=True,
        db_index=True,
        help_text="Instagram username/handle"
    )

    full_name = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text="Full name from Instagram profile"
    )

    biography = models.TextField(
        blank=True,
        null=True,
        help_text="Instagram biography/bio text"
    )

    # Encrypted access token - NEVER expose this in API responses
    access_token = models.TextField(
        blank=True,
        null=True,
        help_text="Encrypted Instagram access token (long-lived)"
    )

    instagram_business_id = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Instagram Business Account ID"
    )

    verification_status = models.BooleanField(
        default=False,
        help_text="Whether the influencer has completed Instagram verification"
    )
    
    # ========================================================================
    # BASIC METRICS (From Instagram API)
    # ========================================================================
    
    followers_count = models.IntegerField(
        default=0,
        help_text="Total number of followers"
    )

    following_count = models.IntegerField(
        default=0,
        help_text="Total number of accounts this user is following"
    )

    media_count = models.IntegerField(
        default=0,
        help_text="Total number of media posts"
    )
    
    # ========================================================================
    # CALCULATED AVERAGES (From Media Post Insights)
    # ========================================================================
    
    ave_impressions = models.FloatField(
        default=0.0,
        help_text="Average impressions across all posts"
    )
    
    ave_reach = models.FloatField(
        default=0.0,
        help_text="Average reach across all posts"
    )
    
    ave_engagement = models.FloatField(
        default=0.0,
        help_text="Average engagement (likes + comments + shares) across all posts"
    )
    
    ave_saves = models.FloatField(
        default=0.0,
        help_text="Average saves across all posts"
    )
    
    ave_video_views = models.FloatField(
        default=0.0,
        null=True,
        blank=True,
        help_text="Average video views (only for video posts)"
    )
    
    engagement_rate_percent = models.FloatField(
        default=0.0,
        help_text="Engagement rate: (Total Engagements / Total Followers) * 100"
    )

    avg_likes = models.FloatField(
        default=0.0,
        help_text="Average likes per post"
    )

    avg_comments = models.FloatField(
        default=0.0,
        help_text="Average comments per post"
    )
    
    # ========================================================================
    # GROWTH METRICS
    # ========================================================================
    
    follower_growth = models.IntegerField(
        default=0,
        help_text="Follower growth over the last 30 days (absolute number)"
    )
    
    follower_growth_rate_percent = models.FloatField(
        default=0.0,
        help_text="Follower growth rate: (Growth / Previous Followers) * 100"
    )
    
    # ========================================================================
    # PROFILE INSIGHTS
    # ========================================================================
    
    profile_views = models.IntegerField(
        default=0,
        help_text="Total profile views over the last 30 days"
    )
    
    # ========================================================================
    # AUDIENCE DEMOGRAPHICS
    # ========================================================================
    
    female_audience_percentage = models.FloatField(
        default=0.0,
        help_text="Percentage of audience that is female"
    )
    
    male_audience_percentage = models.FloatField(
        default=0.0,
        help_text="Percentage of audience that is male"
    )
    
    audience_summary_string = models.TextField(
        blank=True,
        null=True,
        help_text="Human-readable audience summary (top cities and countries)"
    )

    audience_age_distribution = models.JSONField(
        default=dict,
        blank=True,
        help_text="Instagram follower age buckets -> percentage of audience (sums ~100)",
    )
    audience_gender_distribution = models.JSONField(
        default=dict,
        blank=True,
        help_text="Raw gender codes from API (e.g. F, M, U) -> percentage of total weighted audience",
    )
    audience_top_countries = models.JSONField(
        default=list,
        blank=True,
        help_text="Top countries from follower_demographics: [{name, percentage}, ...]",
    )
    audience_top_cities = models.JSONField(
        default=list,
        blank=True,
        help_text="Top cities from follower_demographics: [{name, percentage}, ...]",
    )

    # ========================================================================
    # AI-PREDICTED NICHE & POPULARITY (From Groq LLaMA Zero-Shot Classification)
    # ========================================================================

    ai_predicted_niche = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        db_index=True,
        help_text="AI-predicted niche (e.g., 'fashion', 'fitness', 'food') - Top prediction from ML model"
    )

    ai_predicted_popularity = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        db_index=True,
        help_text="AI-predicted popularity tier (Nano, Micro, Mid, Macro, Mega) - Top prediction from ML model"
    )

    niche_probabilities = models.JSONField(
        default=dict,
        blank=True,
        help_text="Probability distribution across all niche classes (e.g., {'fashion': 0.8, 'fitness': 0.1, ...})"
    )

    popularity_probabilities = models.JSONField(
        default=dict,
        blank=True,
        help_text="Probability distribution across popularity tiers (e.g., {'micro': 0.7, 'mid': 0.2, ...})"
    )

    processed_data_snapshot = models.JSONField(
        default=dict,
        blank=True,
        help_text="Snapshot of processed data fed to ML model for transparency and debugging"
    )

    # ========================================================================
    # ESTIMATED PRICING (Dynamic calculation based on followers + engagement)
    # ========================================================================

    estimated_price_min = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        null=True,
        blank=True,
        help_text="Estimated minimum price per post (calculated dynamically)"
    )

    estimated_price_max = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        null=True,
        blank=True,
        help_text="Estimated maximum price per post (calculated dynamically)"
    )

    estimated_price_avg = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        null=True,
        blank=True,
        help_text="Estimated average price per post (calculated dynamically)"
    )

    # ========================================================================
    # EXPLAINABILITY & TRANSPARENCY (AI-generated explanations)
    # ========================================================================

    niche_classification_explanation = models.TextField(
        blank=True,
        null=True,
        help_text="AI-generated explanation for why this niche was assigned (for transparency)"
    )

    tier_classification_explanation = models.TextField(
        blank=True,
        null=True,
        help_text="AI-generated explanation for why this tier was assigned (for transparency)"
    )

    authenticity_score = models.CharField(
        max_length=20,
        blank=True,
        null=True,
        choices=[
            ('High', 'High - Authentic engagement'),
            ('Medium-High', 'Medium-High - Mostly authentic'),
            ('Medium', 'Medium - Some concerns'),
            ('Low', 'Low - Possible fake followers')
        ],
        help_text="Authenticity score based on engagement quality and bot detection"
    )

    bot_detection_flags = models.JSONField(
        default=list,
        blank=True,
        help_text="List of bot detection signals (e.g., low comment ratio, suspicious engagement)"
    )

    # ========================================================================
    # METADATA
    # ========================================================================
    
    last_data_fetch = models.DateTimeField(
        null=True,
        blank=True,
        help_text="Timestamp of last successful data fetch from Instagram API"
    )
    
    data_processing_status = models.CharField(
        max_length=20,
        choices=[
            ('PENDING', 'Pending'),
            ('PROCESSING', 'Processing'),
            ('COMPLETED', 'Completed'),
            ('FAILED', 'Failed'),
        ],
        default='PENDING',
        help_text="Status of background data processing task"
    )
    
    error_message = models.TextField(
        blank=True,
        null=True,
        help_text="Error message if data processing failed"
    )
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name = 'Influencer Profile'
        verbose_name_plural = 'Influencer Profiles'
        ordering = ['-created_at']
    
    def __str__(self):
        return f"@{self.instagram_handle} ({self.user.get_full_name() or self.user.username})"
    
    # ========================================================================
    # ENCRYPTION METHODS FOR ACCESS TOKEN
    # ========================================================================
    
    def set_access_token(self, token):
        """
        Encrypts and stores the Instagram access token.
        NEVER store tokens in plain text!
        """
        if token:
            cipher = Fernet(settings.ENCRYPTION_KEY)
            encrypted_token = cipher.encrypt(token.encode())
            self.access_token = encrypted_token.decode()
    
    def get_access_token(self):
        """
        Decrypts and returns the Instagram access token.
        Returns None if no token is stored.
        """
        if self.access_token:
            try:
                cipher = Fernet(settings.ENCRYPTION_KEY)
                decrypted_token = cipher.decrypt(self.access_token.encode())
                return decrypted_token.decode()
            except Exception:
                return None
        return None
    
    # ========================================================================
    # UTILITY METHODS
    # ========================================================================
    
    @property
    def is_verified(self):
        """Check if influencer has completed verification"""
        return self.verification_status and self.instagram_business_id
    
    @property
    def data_is_fresh(self):
        """Check if data was fetched within last 7 days"""
        if not self.last_data_fetch:
            return False
        from django.utils import timezone
        from datetime import timedelta
        return timezone.now() - self.last_data_fetch < timedelta(days=7)


class MediaPost(models.Model):
    """
    Media Post Model - Temporary storage for individual post data.
    
    This model stores raw metrics for each Instagram post. After data is
    fetched, these records are used to calculate the averages that are
    stored in the InfluencerProfile model.
    
    You may choose to delete old MediaPost records periodically to save
    database space, since the important aggregated data is in InfluencerProfile.
    """
    
    influencer = models.ForeignKey(
        InfluencerProfile,
        on_delete=models.CASCADE,
        related_name='media_posts',
        help_text="Associated influencer profile"
    )
    
    # ========================================================================
    # POST IDENTIFICATION
    # ========================================================================
    
    media_id = models.CharField(
        max_length=100,
        unique=True,
        db_index=True,
        help_text="Instagram media ID"
    )
    
    media_type = models.CharField(
        max_length=20,
        choices=[
            ('IMAGE', 'Image'),
            ('VIDEO', 'Video'),
            ('CAROUSEL_ALBUM', 'Carousel'),
        ],
        default='IMAGE',
        help_text="Type of media post"
    )
    
    caption = models.TextField(
        blank=True,
        null=True,
        help_text="Post caption text (used for AI niche prediction)"
    )
    
    timestamp = models.DateTimeField(
        null=True,
        blank=True,
        help_text="When the post was published on Instagram"
    )
    
    # ========================================================================
    # POST METRICS (From Instagram Insights API)
    # ========================================================================
    
    impressions = models.IntegerField(
        default=0,
        help_text="Number of times the post was viewed"
    )
    
    reach = models.IntegerField(
        default=0,
        help_text="Number of unique accounts that saw the post"
    )
    
    engagement = models.IntegerField(
        default=0,
        help_text="Total engagement (likes + comments + shares)"
    )

    like_count = models.IntegerField(
        default=0,
        help_text="Number of likes on the post"
    )

    comment_count = models.IntegerField(
        default=0,
        help_text="Number of comments on the post"
    )
    
    saved = models.IntegerField(
        default=0,
        help_text="Number of times the post was saved"
    )
    
    video_views = models.IntegerField(
        null=True,
        blank=True,
        help_text="Number of video views (only applicable for video posts)"
    )
    
    # ========================================================================
    # METADATA
    # ========================================================================
    
    fetched_at = models.DateTimeField(
        auto_now_add=True,
        help_text="When this data was fetched from Instagram API"
    )
    
    class Meta:
        verbose_name = 'Media Post'
        verbose_name_plural = 'Media Posts'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['influencer', '-timestamp']),
        ]
    
    def __str__(self):
        caption_preview = self.caption[:50] if self.caption else "No caption"
        return f"{self.media_id} - {caption_preview}..."
    
    @property
    def engagement_rate(self):
        """Calculate engagement rate for this specific post"""
        if self.reach > 0:
            return (self.engagement / self.reach) * 100
        return 0.0

