"""
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)

    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,
        }


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,
        }
