from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
from . import db

class Usuario(db.Model):
    __tablename__ = 'usuarios'

    # 4 Authentication Roles Constants (Dev, Admin, Multiplicador, Visualizador)
    ROLE_DEV = 'dev'
    ROLE_ADMIN = 'admin'
    ROLE_MULTIPLICADOR = 'cadastrador'
    ROLE_VISUALIZADOR = 'visualizador'
    
    # Constantes de compatibilidade com versões anteriores
    ROLE_ADMIN_1 = 'admin'
    ROLE_ADMIN_2 = 'admin'
    ROLE_CADASTRADOR = 'cadastrador'
    ROLE_COMUM = 'comum'

    id = db.Column(db.Integer, primary_key=True)
    nome = db.Column(db.String(150), nullable=False)
    cpf = db.Column(db.String(14), unique=True, nullable=True)
    email = db.Column(db.String(150), unique=True, nullable=True)
    senha_hash = db.Column(db.String(255), nullable=False)
    perfil = db.Column(db.String(50), nullable=False, default=ROLE_CADASTRADOR)
    telefone = db.Column(db.String(30), nullable=True)
    ativo = db.Column(db.Boolean, default=True)
    solicitou_reset = db.Column(db.Boolean, default=False)
    
    # Preparação para Sistema Futuro de Convites por E-mail
    email_verificado = db.Column(db.Boolean, default=False)
    convite_token = db.Column(db.String(100), nullable=True)
    convite_expira_em = db.Column(db.DateTime, nullable=True)
    primeiro_acesso = db.Column(db.Boolean, default=True)
    
    campanha_id = db.Column(db.Integer, db.ForeignKey('campanhas.id'), nullable=True)
    
    # 1. Autoria da conta
    criado_por_id = db.Column(db.Integer, db.ForeignKey('usuarios.id'), nullable=True)
    
    # 2. Superior hierárquico na árvore
    cadastrador_pai_id = db.Column(db.Integer, db.ForeignKey('usuarios.id'), nullable=True)
    
    criado_em = db.Column(db.DateTime, default=datetime.utcnow)

    # Relationships
    cadastros = db.relationship('Pessoa', backref='cadastrador', lazy=True, foreign_keys='Pessoa.cadastrador_id')
    sub_cadastradores = db.relationship('Usuario', backref=db.backref('cadastrador_pai', remote_side=[id]), lazy=True, foreign_keys=[cadastrador_pai_id])

    def set_senha(self, senha):
        self.senha_hash = generate_password_hash(senha)

    def check_senha(self, senha):
        return check_password_hash(self.senha_hash, senha)

    @property
    def is_dev(self):
        return self.perfil in [self.ROLE_DEV, 'superadmin_dev']

    @property
    def is_admin(self):
        return self.perfil in [self.ROLE_DEV, self.ROLE_ADMIN, 'admin_1', 'admin_2', 'superadmin_dev']

    @property
    def is_admin_1(self):
        return self.is_admin

    @property
    def is_admin_2(self):
        return self.is_admin

    @property
    def is_visualizador(self):
        return self.perfil == self.ROLE_VISUALIZADOR

    @property
    def is_cadastrador(self):
        return self.perfil in [self.ROLE_MULTIPLICADOR, self.ROLE_CADASTRADOR]

    def can_configure_campaign(self):
        return self.is_admin

    def can_manage_campaign(self):
        return self.is_admin

    def can_manage_users(self):
        return self.is_admin

    def can_create_cadastrador(self):
        return self.perfil in [self.ROLE_DEV, self.ROLE_ADMIN, self.ROLE_MULTIPLICADOR, 'admin_1', 'admin_2', 'cadastrador', 'superadmin_dev']

    def can_write(self):
        return self.perfil in [self.ROLE_DEV, self.ROLE_ADMIN, self.ROLE_MULTIPLICADOR, 'admin_1', 'admin_2', 'cadastrador', 'superadmin_dev']

    def total_sub_tree_cadastros(self):
        total = len(self.cadastros)
        for sub in self.sub_cadastradores:
            total += sub.total_sub_tree_cadastros()
        return total

    def to_dict(self):
        return {
            'id': self.id,
            'nome': self.nome,
            'cpf': self.cpf,
            'email': self.email,
            'perfil': self.perfil,
            'telefone': self.telefone,
            'ativo': self.ativo,
            'solicitou_reset': self.solicitou_reset,
            'campanha_id': self.campanha_id,
            'criado_por_id': self.criado_por_id,
            'cadastrador_pai_id': self.cadastrador_pai_id,
            'email_verificado': self.email_verificado,
            'primeiro_acesso': self.primeiro_acesso,
            'total_diretos': len(self.cadastros),
            'total_sub_tree': self.total_sub_tree_cadastros()
        }
