from django.db import models
from django.contrib.auth.models import User

class Cuenta(models.Model):
    MOVIMIENTO_CHOICES = [
        ('SI', 'SI'),
        ('NO', 'NO'),
    ]
    TIPO_SALDO_CHOICES = [
        ('DEBE', 'DEBE'),
        ('HABER', 'HABER'),
    ]

    codigo = models.CharField(max_length=50, primary_key=True, help_text="Código de la cuenta contable (único)")
    nombre = models.CharField(max_length=255, help_text="Nombre descriptivo de la cuenta")
    movimiento = models.CharField(max_length=2, choices=MOVIMIENTO_CHOICES, default='SI', help_text="SI si recibe asientos directos, NO si es de agrupación")
    tipo_saldo = models.CharField(max_length=5, choices=TIPO_SALDO_CHOICES, help_text="Naturaleza contable de la cuenta (DEBE o HABER)")
    activa = models.BooleanField(default=True, help_text="Indica si la cuenta está activa para nuevos asientos")

    @property
    def id(self):
        return self.codigo

    def __str__(self):
        return f"{self.codigo} - {self.nombre}"

    class Meta:
        verbose_name = "Cuenta"
        verbose_name_plural = "Cuentas"
        ordering = ['codigo']


from django.contrib.auth.models import User

class Asiento(models.Model):
    ESTADO_CHOICES = [
        ('BORRADOR', 'BORRADOR'),
        ('APROBADO', 'APROBADO'),
    ]
    fecha = models.DateField(help_text="Fecha de registro del asiento contable")
    glosa = models.TextField(help_text="Descripción o glosa general del movimiento")
    creado_por = models.ForeignKey(User, on_delete=models.PROTECT, related_name='asientos', help_text="Usuario que registró el asiento")
    estado = models.CharField(max_length=20, choices=ESTADO_CHOICES, default='APROBADO', help_text="Estado del asiento contable")

    def __str__(self):
        return f"Asiento #{self.id} - {self.fecha} - {self.glosa[:30]}"

    class Meta:
        verbose_name = "Asiento"
        verbose_name_plural = "Asientos"
        ordering = ['-fecha', '-id']


class DetalleAsiento(models.Model):
    asiento = models.ForeignKey(Asiento, on_delete=models.CASCADE, related_name='detalles', help_text="Asiento de cabecera")
    cuenta = models.ForeignKey(Cuenta, on_delete=models.PROTECT, related_name='detalles', help_text="Cuenta afectada")
    descripcion = models.CharField(max_length=255, blank=True, null=True, help_text="Descripción o concepto específico de esta línea")
    debe = models.DecimalField(max_digits=15, decimal_places=2, default=0.00, help_text="Monto cargado al Debe")
    haber = models.DecimalField(max_digits=15, decimal_places=2, default=0.00, help_text="Monto abonado al Haber")

    def __str__(self):
        return f"Detalle #{self.id} (Asiento #{self.asiento.id}) - Cuenta {self.cuenta_id} - Debe: {self.debe} - Haber: {self.haber}"

    class Meta:
        verbose_name = "Detalle de Asiento"
        verbose_name_plural = "Detalles de Asiento"

class DatosEmpresa(models.Model):
    nombre_empresa = models.CharField(max_length=255, default='Empresa Demo, C.A.')
    rif = models.CharField(max_length=50, default='J-00000000-0')
    direccion = models.TextField(blank=True, null=True)
    telefono = models.CharField(max_length=100, blank=True, null=True)
    correo = models.EmailField(blank=True, null=True)
    # Simulamos el logo con un string (URL/Base64) para simplificar almacenamiento o usamos ImageField si hay Media
    logo_base64 = models.TextField(blank=True, null=True, help_text="Logo en Base64 para evitar configuraciones complejas de Media en este MVP")

    class Meta:
        verbose_name = "Datos de Empresa"
        verbose_name_plural = "Datos de Empresa"

    @classmethod
    def get_solo(cls):
        obj, created = cls.objects.get_or_create(id=1)
        return obj

class AuditoriaLog(models.Model):
    usuario = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='logs')
    accion = models.CharField(max_length=255)
    fecha_hora = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-fecha_hora']
        verbose_name = "Log de Auditoría"
        verbose_name_plural = "Logs de Auditoría"

class SolicitudCuenta(models.Model):
    ACCION_CHOICES = [
        ('CREAR', 'CREAR'),
        ('EDITAR', 'EDITAR'),
        ('ELIMINAR', 'ELIMINAR'),
    ]
    usuario = models.ForeignKey(User, on_delete=models.CASCADE, related_name='solicitudes_cuenta')
    accion = models.CharField(max_length=10, choices=ACCION_CHOICES)
    datos_json = models.TextField(help_text="Datos de la cuenta en formato JSON")
    fecha_solicitud = models.DateTimeField(auto_now_add=True)
    atendida = models.BooleanField(default=False)
    aprobada = models.BooleanField(default=False)

    class Meta:
        ordering = ['-fecha_solicitud']
        verbose_name = "Solicitud de Cambio de Cuenta"
        verbose_name_plural = "Solicitudes de Cambio de Cuenta"

class SolicitudBackup(models.Model):
    TIPO_CHOICES = [
        ('RESPALDAR', 'RESPALDAR'),
        ('RESTAURAR', 'RESTAURAR'),
    ]
    TIPO_RESPALDO_CHOICES = [
        ('CONTABLE', 'CONTABLE'),
        ('SEGURIDAD', 'SEGURIDAD'),
        ('TOTAL', 'TOTAL'),
    ]
    usuario = models.ForeignKey(User, on_delete=models.CASCADE, related_name='solicitudes_backup')
    tipo = models.CharField(max_length=15, choices=TIPO_CHOICES)
    tipo_respaldo = models.CharField(max_length=15, choices=TIPO_RESPALDO_CHOICES, default='TOTAL')
    justificacion = models.TextField()
    archivo_nombre = models.CharField(max_length=255, blank=True, null=True, help_text="Nombre del archivo de respaldo")
    archivo_contenido = models.TextField(blank=True, null=True, help_text="Contenido en Base64 para archivo sql de restauración")
    fecha_solicitud = models.DateTimeField(auto_now_add=True)
    atendida = models.BooleanField(default=False)
    aprobada = models.BooleanField(default=False)

    class Meta:
        ordering = ['-fecha_solicitud']
        verbose_name = "Solicitud de Respaldo"
        verbose_name_plural = "Solicitudes de Respaldo"

class SolicitudCambioAsiento(models.Model):
    usuario = models.ForeignKey(User, on_delete=models.CASCADE, related_name='solicitudes_cambio_asiento')
    asiento = models.ForeignKey(Asiento, on_delete=models.CASCADE, related_name='solicitudes_cambio')
    datos_nuevos = models.TextField(help_text="Payload JSON con datos modificados del asiento y sus detalles")
    fecha_solicitud = models.DateTimeField(auto_now_add=True)
    atendida = models.BooleanField(default=False)
    aprobada = models.BooleanField(default=False)

    class Meta:
        ordering = ['-fecha_solicitud']
        verbose_name = "Solicitud de Cambio de Asiento"
        verbose_name_plural = "Solicitudes de Cambio de Asiento"

class PeriodoContable(models.Model):
    ESTADO_CHOICES = [
        ('ABIERTO', 'ABIERTO'),
        ('CERRADO', 'CERRADO'),
    ]
    ano = models.IntegerField(primary_key=True, help_text="Año fiscal")
    fecha_inicio = models.DateField(blank=True, null=True, help_text="Fecha de inicio del período")
    fecha_fin = models.DateField(blank=True, null=True, help_text="Fecha de fin del período")
    estado = models.CharField(max_length=10, choices=ESTADO_CHOICES, default='ABIERTO')
    fecha_cierre = models.DateTimeField(blank=True, null=True, help_text="Fecha y hora en que se ejecutó el cierre")

    def __str__(self):
        return f"Período {self.ano} - {self.estado}"

    class Meta:
        verbose_name = "Período Contable"
        verbose_name_plural = "Períodos Contables"
        ordering = ['-ano']
