"""
CODH Core Models
System configuration and audit logging
"""

import uuid
from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import URLValidator
from django.conf import settings

User = get_user_model()


class SystemConfiguration(models.Model):
    """
    Global system configuration - singleton model
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    # Installation Status
    is_configured = models.BooleanField(default=False)
    installation_date = models.DateTimeField(null=True, blank=True)
    installed_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='installations')
    
    # Platform Settings
    platform_name = models.CharField(max_length=255, default='CODH Project DNA Collection Wizard')
    platform_url = models.URLField(validators=[URLValidator()])
    company_name = models.CharField(max_length=255, default='2SIMPLIFIED GROUP')
    security_team = models.CharField(max_length=255, default='2S-TASKFORCE')
    
    # Branding
    logo = models.ImageField(upload_to='branding/', null=True, blank=True)
    favicon = models.ImageField(upload_to='branding/', null=True, blank=True)
    primary_color = models.CharField(max_length=7, default='#4ADE80')  # Light Green
    secondary_color = models.CharField(max_length=7, default='#60A5FA')  # Light Blue
    accent_color = models.CharField(max_length=7, default='#FB923C')  # Orange
    
    # Currency & Locale
    default_currency = models.CharField(max_length=3, default='USD')
    default_timezone = models.CharField(max_length=50, default='UTC')
    default_language = models.CharField(max_length=10, default='en')
    
    # Email Configuration
    email_from_name = models.CharField(max_length=255, default='CODH Platform')
    email_from_address = models.EmailField(default='noreply@codh.platform')
    email_reply_to = models.EmailField(null=True, blank=True)
    
    # Security Settings
    require_2fa_for_admin = models.BooleanField(default=False)
    password_expiry_days = models.IntegerField(default=90)
    session_timeout_minutes = models.IntegerField(default=60)
    max_login_attempts = models.IntegerField(default=5)
    lockout_duration_minutes = models.IntegerField(default=30)
    
    # API Configuration (Encrypted)
    kimi_api_key_encrypted = models.BinaryField(null=True, blank=True)
    mofh_api_key_encrypted = models.BinaryField(null=True, blank=True)
    mofh_api_username_encrypted = models.BinaryField(null=True, blank=True)
    mofh_api_password_encrypted = models.BinaryField(null=True, blank=True)
    vpstc_api_key_encrypted = models.BinaryField(null=True, blank=True)
    
    # Payment Gateway Settings (Encrypted)
    paystack_secret_key_encrypted = models.BinaryField(null=True, blank=True)
    paystack_public_key_encrypted = models.BinaryField(null=True, blank=True)
    flutterwave_secret_key_encrypted = models.BinaryField(null=True, blank=True)
    flutterwave_public_key_encrypted = models.BinaryField(null=True, blank=True)
    stripe_secret_key_encrypted = models.BinaryField(null=True, blank=True)
    stripe_public_key_encrypted = models.BinaryField(null=True, blank=True)
    
    # Automation Settings
    auto_provision_hosting = models.BooleanField(default=True)
    auto_activate_subscriptions = models.BooleanField(default=True)
    auto_suspend_on_expiry = models.BooleanField(default=True)
    retry_failed_tasks = models.BooleanField(default=True)
    max_retry_attempts = models.IntegerField(default=3)
    
    # Notification Settings
    enable_email_notifications = models.BooleanField(default=True)
    enable_push_notifications = models.BooleanField(default=True)
    enable_sms_notifications = models.BooleanField(default=False)
    admin_notification_email = models.EmailField(null=True, blank=True)
    
    # Maintenance Mode
    maintenance_mode = models.BooleanField(default=False)
    maintenance_message = models.TextField(default='System is under maintenance. Please check back later.')
    
    # Metadata
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name = 'System Configuration'
        verbose_name_plural = 'System Configuration'
    
    def save(self, *args, **kwargs):
        # Ensure only one instance exists
        if not self.pk and SystemConfiguration.objects.exists():
            raise Exception('Only one SystemConfiguration instance allowed')
        super().save(*args, **kwargs)
    
    @classmethod
    def get_config(cls):
        """Get or create system configuration"""
        config, created = cls.objects.get_or_create(pk=1)
        return config


class SetupWizardProgress(models.Model):
    """
    Track setup wizard progress
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    STEP_CHOICES = [
        ('requirements', 'Server Requirements'),
        ('database', 'Database Configuration'),
        ('admin', 'Admin Account'),
        ('api', 'API Configuration'),
        ('payment', 'Payment Gateways'),
        ('branding', 'Branding & Settings'),
        ('complete', 'Complete'),
    ]
    
    current_step = models.CharField(max_length=20, choices=STEP_CHOICES, default='requirements')
    step_data = models.JSONField(default=dict)
    is_completed = models.BooleanField(default=False)
    completed_at = models.DateTimeField(null=True, blank=True)
    
    # Server Requirements Check
    python_version_ok = models.BooleanField(default=False)
    php_version_ok = models.BooleanField(default=False)
    mysql_version_ok = models.BooleanField(default=False)
    redis_ok = models.BooleanField(default=False)
    disk_space_ok = models.BooleanField(default=False)
    
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    
    class Meta:
        verbose_name = 'Setup Wizard Progress'
        verbose_name_plural = 'Setup Wizard Progress'


class AuditLog(models.Model):
    """
    Comprehensive audit logging for all system actions
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='audit_logs')
    action = models.CharField(max_length=255)
    description = models.TextField(blank=True)
    
    # Request Details
    ip_address = models.GenericIPAddressField(null=True, blank=True)
    user_agent = models.CharField(max_length=255, blank=True)
    request_data = models.JSONField(default=dict, blank=True)
    response_status = models.IntegerField(null=True, blank=True)
    duration = models.FloatField(null=True, blank=True)  # in seconds
    
    # Object tracking
    object_type = models.CharField(max_length=100, blank=True)
    object_id = models.CharField(max_length=100, blank=True)
    
    # Severity
    SEVERITY_CHOICES = [
        ('info', 'Info'),
        ('warning', 'Warning'),
        ('error', 'Error'),
        ('critical', 'Critical'),
    ]
    severity = models.CharField(max_length=10, choices=SEVERITY_CHOICES, default='info')
    
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = 'Audit Log'
        verbose_name_plural = 'Audit Logs'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'created_at']),
            models.Index(fields=['action', 'created_at']),
            models.Index(fields=['severity', 'created_at']),
        ]


class APIToken(models.Model):
    """
    API tokens for external integrations
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='api_tokens')
    name = models.CharField(max_length=255)
    token = models.CharField(max_length=255, unique=True)
    
    # Permissions
    permissions = models.JSONField(default=list)  # List of allowed endpoints
    
    # Usage tracking
    last_used_at = models.DateTimeField(null=True, blank=True)
    request_count = models.IntegerField(default=0)
    
    # Status
    is_active = models.BooleanField(default=True)
    expires_at = models.DateTimeField(null=True, blank=True)
    
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = 'API Token'
        verbose_name_plural = 'API Tokens'
        ordering = ['-created_at']


class BackgroundTask(models.Model):
    """
    Track background task execution
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    TASK_TYPES = [
        ('provisioning', 'Hosting Provisioning'),
        ('deployment', 'Application Deployment'),
        ('sync', 'WordPress Sync'),
        ('billing', 'Billing Processing'),
        ('notification', 'Notification Send'),
        ('backup', 'Backup'),
        ('cleanup', 'Cleanup'),
    ]
    
    task_type = models.CharField(max_length=20, choices=TASK_TYPES)
    task_name = models.CharField(max_length=255)
    celery_task_id = models.CharField(max_length=255, blank=True)
    
    # Related objects
    user_id = models.UUIDField(null=True, blank=True)
    project_id = models.UUIDField(null=True, blank=True)
    hosting_account_id = models.UUIDField(null=True, blank=True)
    
    # Status
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('running', 'Running'),
        ('completed', 'Completed'),
        ('failed', 'Failed'),
        ('retrying', 'Retrying'),
        ('cancelled', 'Cancelled'),
    ]
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending')
    
    # Progress
    progress_percent = models.IntegerField(default=0)
    current_step = models.CharField(max_length=255, blank=True)
    
    # Results
    result_data = models.JSONField(default=dict, blank=True)
    error_message = models.TextField(blank=True)
    stack_trace = models.TextField(blank=True)
    
    # Retry logic
    retry_count = models.IntegerField(default=0)
    max_retries = models.IntegerField(default=3)
    
    # Timing
    started_at = models.DateTimeField(null=True, blank=True)
    completed_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = 'Background Task'
        verbose_name_plural = 'Background Tasks'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['task_type', 'status']),
            models.Index(fields=['user_id', 'status']),
        ]


class SystemHealth(models.Model):
    """
    System health monitoring
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    
    # Component Status
    database_status = models.CharField(max_length=10, default='unknown')  # ok, warning, error
    redis_status = models.CharField(max_length=10, default='unknown')
    celery_status = models.CharField(max_length=10, default='unknown')
    disk_status = models.CharField(max_length=10, default='unknown')
    memory_status = models.CharField(max_length=10, default='unknown')
    
    # Metrics
    disk_usage_percent = models.FloatField(null=True, blank=True)
    memory_usage_percent = models.FloatField(null=True, blank=True)
    cpu_usage_percent = models.FloatField(null=True, blank=True)
    
    # Queue metrics
    pending_tasks = models.IntegerField(default=0)
    failed_tasks = models.IntegerField(default=0)
    
    # Response times (ms)
    api_response_time = models.FloatField(null=True, blank=True)
    db_query_time = models.FloatField(null=True, blank=True)
    
    checked_at = models.DateTimeField(auto_now_add=True)
    
    class Meta:
        verbose_name = 'System Health'
        verbose_name_plural = 'System Health Checks'
        ordering = ['-checked_at']
