"""
Modelos SQLAlchemy de LicenciasMIG.

Mantiene los nombres de columnas que el cliente MIG espera (nit, razonsocial,
nombrecomercial, etc.) para que las consultas SOAP no requieran traduccion.
"""
from datetime import datetime

from flask_login import UserMixin
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import check_password_hash, generate_password_hash


db = SQLAlchemy()


class Empresa(db.Model):
    __tablename__ = 'Empresas'

    EmpresaID          = db.Column(db.Integer, primary_key=True, autoincrement=True)
    nit                = db.Column(db.String(50),  nullable=False, unique=True, index=True)
    razonsocial        = db.Column(db.String(200), index=True)
    nombrecomercial    = db.Column(db.String(200), index=True)
    direccion          = db.Column(db.String(200))
    telefono           = db.Column(db.String(50))
    celular            = db.Column(db.String(50))
    mensualidad        = db.Column(db.Boolean, default=False, nullable=False)
    regulariza         = db.Column(db.Boolean, default=False, nullable=False)
    tipotpv            = db.Column(db.String(30))
    fecharegistro      = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    fechaactualizacion = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    claveproducto      = db.Column(db.UnicodeText)
    nombreequipo       = db.Column(db.UnicodeText)
    osversion          = db.Column(db.UnicodeText)
    # Periodo (YYYY-MM) por el que la mensualidad esta paga/activa. El boton
    # "Activar mes" del panel lo pone en el mes actual; ValidarLicenciaMensual
    # solo entrega la clave si periodopagado == mes actual.
    periodopagado      = db.Column(db.String(7))

    def to_dict(self):
        return {
            'EmpresaID':          self.EmpresaID,
            'nit':                self.nit,
            'razonsocial':        self.razonsocial,
            'nombrecomercial':    self.nombrecomercial,
            'direccion':          self.direccion,
            'telefono':           self.telefono,
            'celular':            self.celular,
            'mensualidad':        bool(self.mensualidad),
            'regulariza':         bool(self.regulariza),
            'tipotpv':            self.tipotpv,
            'fecharegistro':      self.fecharegistro.strftime('%Y-%m-%d %H:%M:%S') if self.fecharegistro else None,
            'fechaactualizacion': self.fechaactualizacion.strftime('%Y-%m-%d %H:%M:%S') if self.fechaactualizacion else None,
            'claveproducto':      self.claveproducto,
            'nombreequipo':       self.nombreequipo,
            'osversion':          self.osversion,
            'periodopagado':      self.periodopagado,
        }


class LicenciaEmpresa(db.Model):
    __tablename__ = 'LicenciasEmpresas'

    LicenciaID        = db.Column(db.Integer, primary_key=True, autoincrement=True)
    nit               = db.Column(db.String(50), nullable=False, index=True)
    razonsocial       = db.Column(db.String(200))
    nombrecomercial   = db.Column(db.String(200))
    direccion         = db.Column(db.String(200))
    telefono          = db.Column(db.String(50))
    celular           = db.Column(db.String(50))
    iddepartamento    = db.Column(db.String(10))
    idciudad          = db.Column(db.String(10))
    licenciatemporal  = db.Column(db.Boolean, default=False, nullable=False)
    fecharegistro     = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    responsable       = db.Column(db.String(500))
    correoresponsable = db.Column(db.String(500))
    telefonoponsable  = db.Column(db.String(500))
    motivolicencia    = db.Column(db.String(500))
    claveproducto     = db.Column(db.UnicodeText)
    nombreequipo      = db.Column(db.UnicodeText)
    osversion         = db.Column(db.UnicodeText)
    clavemes          = db.Column(db.String(500), index=True)
    licenciaactiva    = db.Column(db.Boolean, default=True,  nullable=False)
    bloquearlicencia  = db.Column(db.Boolean, default=False, nullable=False)

    def to_dict(self):
        return {
            'LicenciaID':        self.LicenciaID,
            'nit':               self.nit,
            'razonsocial':       self.razonsocial,
            'nombrecomercial':   self.nombrecomercial,
            'direccion':         self.direccion,
            'telefono':          self.telefono,
            'celular':           self.celular,
            'iddepartamento':    self.iddepartamento,
            'idciudad':          self.idciudad,
            'licenciatemporal':  bool(self.licenciatemporal),
            'fecharegistro':     self.fecharegistro.strftime('%Y-%m-%d %H:%M:%S') if self.fecharegistro else None,
            'responsable':       self.responsable,
            'correoresponsable': self.correoresponsable,
            'telefonoponsable':  self.telefonoponsable,
            'motivolicencia':    self.motivolicencia,
            'claveproducto':     self.claveproducto,
            'nombreequipo':      self.nombreequipo,
            'osversion':         self.osversion,
            'clavemes':          self.clavemes,
            'licenciaactiva':    bool(self.licenciaactiva),
            'bloquearlicencia':  bool(self.bloquearlicencia),
        }


class Usuario(UserMixin, db.Model):
    __tablename__ = 'Usuarios'

    UsuarioID      = db.Column(db.Integer, primary_key=True, autoincrement=True)
    Username       = db.Column(db.String(50), nullable=False, unique=True)
    PasswordHash   = db.Column(db.String(255), nullable=False)
    NombreCompleto = db.Column(db.String(200))
    Email          = db.Column(db.String(100))
    Rol            = db.Column(db.String(50), default='Admin', nullable=False)
    Activo         = db.Column(db.Boolean, default=True, nullable=False)
    FechaCreacion  = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
    UltimoAcceso   = db.Column(db.DateTime)

    def set_password(self, password: str) -> None:
        self.PasswordHash = generate_password_hash(password)

    def check_password(self, password: str) -> bool:
        return check_password_hash(self.PasswordHash, password)

    def get_id(self):
        return str(self.UsuarioID)

    def to_dict(self):
        return {
            'UsuarioID':      self.UsuarioID,
            'Username':       self.Username,
            'NombreCompleto': self.NombreCompleto,
            'Email':          self.Email,
            'Rol':            self.Rol,
            'Activo':         bool(self.Activo),
            'FechaCreacion':  self.FechaCreacion.strftime('%Y-%m-%d %H:%M:%S') if self.FechaCreacion else None,
            'UltimoAcceso':   self.UltimoAcceso.strftime('%Y-%m-%d %H:%M:%S')  if self.UltimoAcceso  else None,
        }


class WebServiceLog(db.Model):
    __tablename__ = 'WebServiceLogs'

    LogID        = db.Column(db.BigInteger, primary_key=True, autoincrement=True)
    Fecha        = db.Column(db.DateTime, default=datetime.utcnow, nullable=False, index=True)
    Metodo       = db.Column(db.String(50), nullable=False, index=True)
    nit          = db.Column(db.String(50), index=True)
    IpCliente    = db.Column(db.String(45))
    nombreequipo = db.Column(db.String(200))
    Resultado    = db.Column(db.String(20))
    Mensaje      = db.Column(db.UnicodeText)
    DuracionMs   = db.Column(db.Integer)

    def to_dict(self):
        return {
            'LogID':        self.LogID,
            'Fecha':        self.Fecha.strftime('%Y-%m-%d %H:%M:%S') if self.Fecha else None,
            'Metodo':       self.Metodo,
            'nit':          self.nit,
            'IpCliente':    self.IpCliente,
            'nombreequipo': self.nombreequipo,
            'Resultado':    self.Resultado,
            'Mensaje':      self.Mensaje,
            'DuracionMs':   self.DuracionMs,
        }
