# -*- coding: utf-8 -*-
"""
Core Models Module

This module contains core models for the Adtlas DAI Management System.
These models provide foundational functionality used across the application.
"""

from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator, MaxValueValidator
from apps.common.models import BaseModel, TimeStampedModel
import uuid

User = get_user_model()


class SystemConfiguration(BaseModel):
    """
    System-wide configuration settings.
    
    This model stores application-wide settings that can be modified
    through the admin interface without code changes.
    """
    
    key = models.CharField(
        max_length=100,
        unique=True,
        verbose_name=_("Configuration Key"),
        help_text=_("Unique identifier for this configuration setting")
    )
    
    value = models.TextField(
        verbose_name=_("Configuration Value"),
        help_text=_("The configuration value (can be JSON for complex data)")
    )
    
    description = models.TextField(
        blank=True,
        verbose_name=_("Description"),
        help_text=_("Description of what this configuration controls")
    )
    
    is_active = models.BooleanField(
        default=True,
        verbose_name=_("Is Active"),
        help_text=_("Whether this configuration is currently active")
    )
    
    class Meta:
        verbose_name = _("System Configuration")
        verbose_name_plural = _("System Configurations")
        ordering = ['key']
        db_table = 'core_system_configuration'
    
    def __str__(self):
        return f"{self.key}: {self.value[:50]}..."


class ApplicationMetrics(TimeStampedModel):
    """
    Application performance and usage metrics.
    
    Tracks various metrics about application usage, performance,
    and system health for monitoring and analytics.
    """
    
    metric_name = models.CharField(
        max_length=100,
        db_index=True,
        verbose_name=_("Metric Name"),
        help_text=_("Name of the metric being tracked")
    )
    
    metric_value = models.DecimalField(
        max_digits=15,
        decimal_places=4,
        verbose_name=_("Metric Value"),
        help_text=_("Numeric value of the metric")
    )
    
    metric_type = models.CharField(
        max_length=50,
        choices=[
            ('counter', _("Counter")),
            ('gauge', _("Gauge")),
            ('histogram', _("Histogram")),
            ('summary', _("Summary")),
        ],
        default='gauge',
        verbose_name=_("Metric Type"),
        help_text=_("Type of metric being recorded")
    )
    
    tags = models.JSONField(
        default=dict,
        blank=True,
        verbose_name=_("Tags"),
        help_text=_("Additional metadata tags for the metric")
    )
    
    timestamp = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
        verbose_name=_("Timestamp"),
        help_text=_("When this metric was recorded")
    )
    
    class Meta:
        verbose_name = _("Application Metric")
        verbose_name_plural = _("Application Metrics")
        ordering = ['-timestamp']
        db_table = 'core_application_metrics'
        indexes = [
            models.Index(fields=['metric_name', 'timestamp']),
            models.Index(fields=['metric_type', 'timestamp']),
        ]
    
    def __str__(self):
        return f"{self.metric_name}: {self.metric_value} ({self.timestamp})"


class AuditLog(TimeStampedModel):
    """
    Audit log for tracking user actions and system events.
    
    Provides comprehensive logging of user activities and system
    events for security, compliance, and debugging purposes.
    """
    
    user = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='audit_logs',
        verbose_name=_("User"),
        help_text=_("User who performed the action (if applicable)")
    )
    
    action = models.CharField(
        max_length=100,
        db_index=True,
        verbose_name=_("Action"),
        help_text=_("Action that was performed")
    )
    
    resource_type = models.CharField(
        max_length=100,
        db_index=True,
        verbose_name=_("Resource Type"),
        help_text=_("Type of resource that was affected")
    )
    
    resource_id = models.CharField(
        max_length=100,
        blank=True,
        verbose_name=_("Resource ID"),
        help_text=_("ID of the specific resource that was affected")
    )
    
    ip_address = models.GenericIPAddressField(
        null=True,
        blank=True,
        verbose_name=_("IP Address"),
        help_text=_("IP address from which the action was performed")
    )
    
    user_agent = models.TextField(
        blank=True,
        verbose_name=_("User Agent"),
        help_text=_("Browser/client user agent string")
    )
    
    details = models.JSONField(
        default=dict,
        blank=True,
        verbose_name=_("Details"),
        help_text=_("Additional details about the action")
    )
    
    success = models.BooleanField(
        default=True,
        verbose_name=_("Success"),
        help_text=_("Whether the action was successful")
    )
    
    class Meta:
        verbose_name = _("Audit Log")
        verbose_name_plural = _("Audit Logs")
        ordering = ['-created_at']
        db_table = 'core_audit_log'
        indexes = [
            models.Index(fields=['user', 'created_at']),
            models.Index(fields=['action', 'created_at']),
            models.Index(fields=['resource_type', 'created_at']),
        ]
    
    def __str__(self):
        user_str = self.user.email if self.user else "System"
        return f"{user_str} - {self.action} on {self.resource_type} ({self.created_at})"


class NotificationTemplate(BaseModel):
    """
    Templates for system notifications.
    
    Defines reusable templates for various types of notifications
    sent to users via email, SMS, or in-app notifications.
    """
    
    name = models.CharField(
        max_length=100,
        unique=True,
        verbose_name=_("Template Name"),
        help_text=_("Unique name for this notification template")
    )
    
    subject = models.CharField(
        max_length=200,
        verbose_name=_("Subject"),
        help_text=_("Subject line for the notification")
    )
    
    body_text = models.TextField(
        verbose_name=_("Text Body"),
        help_text=_("Plain text version of the notification")
    )
    
    body_html = models.TextField(
        blank=True,
        verbose_name=_("HTML Body"),
        help_text=_("HTML version of the notification")
    )
    
    notification_type = models.CharField(
        max_length=50,
        choices=[
            ('email', _("Email")),
            ('sms', _("SMS")),
            ('push', _("Push Notification")),
            ('in_app', _("In-App Notification")),
        ],
        default='email',
        verbose_name=_("Notification Type"),
        help_text=_("Type of notification this template is for")
    )
    
    variables = models.JSONField(
        default=list,
        blank=True,
        verbose_name=_("Template Variables"),
        help_text=_("List of variables that can be used in this template")
    )
    
    is_active = models.BooleanField(
        default=True,
        verbose_name=_("Is Active"),
        help_text=_("Whether this template is currently active")
    )
    
    class Meta:
        verbose_name = _("Notification Template")
        verbose_name_plural = _("Notification Templates")
        ordering = ['name']
        db_table = 'core_notification_template'
    
    def __str__(self):
        return f"{self.name} ({self.notification_type})"


class SystemHealth(TimeStampedModel):
    """
    System health monitoring data.
    
    Tracks various system health metrics including database
    performance, memory usage, and service availability.
    """
    
    service_name = models.CharField(
        max_length=100,
        db_index=True,
        verbose_name=_("Service Name"),
        help_text=_("Name of the service being monitored")
    )
    
    status = models.CharField(
        max_length=20,
        choices=[
            ('healthy', _("Healthy")),
            ('warning', _("Warning")),
            ('critical', _("Critical")),
            ('unknown', _("Unknown")),
        ],
        default='unknown',
        verbose_name=_("Status"),
        help_text=_("Current health status of the service")
    )
    
    response_time = models.DecimalField(
        max_digits=10,
        decimal_places=4,
        null=True,
        blank=True,
        verbose_name=_("Response Time"),
        help_text=_("Service response time in milliseconds")
    )
    
    cpu_usage = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        null=True,
        blank=True,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name=_("CPU Usage"),
        help_text=_("CPU usage percentage")
    )
    
    memory_usage = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        null=True,
        blank=True,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name=_("Memory Usage"),
        help_text=_("Memory usage percentage")
    )
    
    disk_usage = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        null=True,
        blank=True,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name=_("Disk Usage"),
        help_text=_("Disk usage percentage")
    )
    
    additional_metrics = models.JSONField(
        default=dict,
        blank=True,
        verbose_name=_("Additional Metrics"),
        help_text=_("Additional service-specific metrics")
    )
    
    class Meta:
        verbose_name = _("System Health")
        verbose_name_plural = _("System Health")
        ordering = ['-created_at']
        db_table = 'core_system_health'
        indexes = [
            models.Index(fields=['service_name', 'created_at']),
            models.Index(fields=['status', 'created_at']),
        ]
    
    def __str__(self):
        return f"{self.service_name} - {self.status} ({self.created_at})"
