import jwt
import hashlib
import os
import functools
from datetime import datetime, timedelta, timezone
from flask import request, jsonify
from app.config import Config
from app.database import db

def hash_password(password: str, salt: str = "duobi_salt_2026") -> str:
    """Gera hash SHA-256 com salt fixo/seguro."""
    return hashlib.sha256(f"{password}{salt}".encode("utf-8")).hexdigest()

def verify_password(password: str, hashed: str, salt: str = "duobi_salt_2026") -> bool:
    """Verifica a senha informada contra o hash salvo (suporta salt novo e legado)."""
    return hash_password(password, salt) == hashed or hash_password(password, "oliveira_bi_salt_2026") == hashed

def generate_jwt(user_dict: dict, expires_in_hours: int = 24) -> str:
    """Gera token JWT contendo payload do usuário."""
    exp = datetime.now(timezone.utc) + timedelta(hours=expires_in_hours)
    payload = {
        "id": user_dict["id"],
        "nome": user_dict["nome"],
        "email": user_dict["email"],
        "role": user_dict.get("role", "admin"),
        "cargo": user_dict.get("cargo", "Gestor de BI"),
        "exp": exp
    }
    return jwt.encode(payload, Config.JWT_SECRET, algorithm="HS256")

def decode_jwt(token: str) -> dict:
    """Decodifica e valida token JWT."""
    try:
        return jwt.decode(token, Config.JWT_SECRET, algorithms=["HS256"])
    except jwt.ExpiredSignatureError:
        return None
    except jwt.InvalidTokenError:
        return None

def login_required(f):
    """Decorator para rotas que exigem autenticação JWT."""
    @functools.wraps(f)
    def decorated_function(*args, **kwargs):
        auth_header = request.headers.get("Authorization")
        if not auth_header:
            return jsonify({"success": False, "error": "Token de autenticação ausente."}), 401
        
        parts = auth_header.split(" ")
        if len(parts) != 2 or parts[0].lower() != "bearer":
            return jsonify({"success": False, "error": "Formato de token inválido. Use 'Bearer <token>'."}), 401
        
        token = parts[1]
        payload = decode_jwt(token)
        if not payload:
            return jsonify({"success": False, "error": "Sessão expirada ou token inválido."}), 401
        
        request.current_user = payload
        return f(*args, **kwargs)
    return decorated_function

def init_default_users():
    """Garante que existam usuários padrões cadastrados."""
    try:
        users = db.execute_query("SELECT id, email FROM usuarios")
        existing_emails = {u["email"] for u in users} if users else set()

        default_users = [
            {
                "nome": "DuoBI Admin",
                "email": "admin@duobi.com.br",
                "senha": "admin",
                "cargo": "Head de Inteligência & CRM",
                "role": "admin",
                "avatar": "https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150&auto=format&fit=crop&q=80"
            },
            {
                "nome": "Carlos Gestor",
                "email": "supervisor@duotalk.com.br",
                "senha": "123",
                "cargo": "Supervisor de Operações",
                "role": "supervisor",
                "avatar": "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&auto=format&fit=crop&q=80"
            },
            {
                "nome": "DuoBI Admin (Legado)",
                "email": "admin@oliveirabi.com.br",
                "senha": "admin",
                "cargo": "Head de Inteligência & CRM",
                "role": "admin",
                "avatar": "https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=150&auto=format&fit=crop&q=80"
            }
        ]

        for u in default_users:
            if u["email"] not in existing_emails:
                pw_hash = hash_password(u["senha"])
                if db.active_driver == "mysql":
                    db.execute_insert(
                        """INSERT INTO usuarios (nome, email, senha_hash, cargo, role, avatar)
                           VALUES (%s, %s, %s, %s, %s, %s)""",
                        (u["nome"], u["email"], pw_hash, u["cargo"], u["role"], u["avatar"])
                    )
                else:
                    db.execute_insert(
                        """INSERT INTO usuarios (nome, email, senha_hash, cargo, role, avatar)
                           VALUES (?, ?, ?, ?, ?, ?)""",
                        (u["nome"], u["email"], pw_hash, u["cargo"], u["role"], u["avatar"])
                    )
        print("[AUTH] Usuários padrão prontos: admin@duobi.com.br / supervisor@duotalk.com.br")
    except Exception as e:
        print(f"[AUTH ERROR] Falha ao inicializar usuários: {e}")
