from django.db import models

from .fields import EncryptedCharField


class ScanProfile(models.Model):
    INTERVAL_CHOICES = [
        (1, 'Every 1 day'),
        (3, 'Every 3 days'),
        (7, 'Every 7 days'),
        (30, 'Every 30 days'),
    ]
    SEVERITY_CHOICES = [
        ('warning', 'Warning and above'),
        ('critical', 'Critical only'),
    ]

    name = models.CharField(max_length=200)
    enabled = models.BooleanField(default=True)
    schedule_interval = models.IntegerField(choices=INTERVAL_CHOICES, default=7)
    gateway_ip = models.GenericIPAddressField(help_text='e.g. 192.168.1.1')
    public_ip = models.GenericIPAddressField(help_text='Your public/WAN IP address')
    network_cidr = models.CharField(max_length=50, blank=True, help_text='e.g. 192.168.1.0/24')
    auth_provider_host = models.CharField(max_length=255, blank=True, help_text='e.g. pass.junv.cc')
    domains = models.JSONField(default=list, blank=True, help_text='List of public hostnames to check')
    cameras = models.JSONField(default=list, blank=True, help_text='List of camera IPs to probe')
    telegram_bot_token = EncryptedCharField(blank=True)
    telegram_chat_id = EncryptedCharField(blank=True)
    notify_on_severity = models.CharField(max_length=20, choices=SEVERITY_CHOICES, default='critical')
    last_run_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name


class ScanRun(models.Model):
    STATUS_CHOICES = [
        ('pending', 'Pending'),
        ('running', 'Running'),
        ('success', 'Success'),
        ('failed', 'Failed'),
    ]

    profile = models.ForeignKey(ScanProfile, on_delete=models.CASCADE, related_name='runs')
    started_at = models.DateTimeField(auto_now_add=True)
    finished_at = models.DateTimeField(null=True, blank=True)
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending')
    summary = models.JSONField(default=dict)
    triggered_by = models.CharField(max_length=20, default='manual')

    class Meta:
        ordering = ['-started_at']

    def __str__(self):
        return f'{self.profile.name} run #{self.pk} ({self.status})'

    @property
    def duration_seconds(self):
        if self.finished_at and self.started_at:
            return int((self.finished_at - self.started_at).total_seconds())
        return None


class ScanFinding(models.Model):
    SEVERITY_CHOICES = [
        ('ok', 'OK'),
        ('info', 'Info'),
        ('warning', 'Warning'),
        ('critical', 'Critical'),
    ]

    run = models.ForeignKey(ScanRun, on_delete=models.CASCADE, related_name='findings')
    check_name = models.CharField(max_length=100)
    severity = models.CharField(max_length=20, choices=SEVERITY_CHOICES)
    title = models.CharField(max_length=255)
    detail = models.TextField()
    raw = models.JSONField(default=dict)

    class Meta:
        ordering = ['severity', 'check_name']

    def __str__(self):
        return f'[{self.severity.upper()}] {self.title}'
