# -*- coding: utf-8 -*-
"""
app.py — Backend Flask — Sistema de Telemetria RIT
"""
import os, io, json, hashlib
from datetime import datetime, timedelta, date
from functools import wraps

import jwt
import pymysql
from flask import Flask, request, jsonify, send_file, send_from_directory, g
from werkzeug.utils import secure_filename

from scripts.limpeza         import limpar_csv, ErroFormatoInesperado
from scripts.auditoria_mensal import auditar_mensal
from scripts.relatorio_pdf   import gerar_pdf_descartados, gerar_pdf_auditoria_mensal

app = Flask(__name__, static_folder="static")
app.config.update(
    SECRET_KEY         = os.environ.get("SECRET_KEY", "rit-2026"),
    DB_HOST            = os.environ.get("DB_HOST",     "localhost"),
    DB_USER            = os.environ.get("DB_USER",     "revolutionit_frotaadm"),
    DB_PASSWORD        = os.environ.get("DB_PASSWORD", "}{XYy6qyJHP#_ZXx"),
    DB_NAME            = os.environ.get("DB_NAME",     "revolutionit_frotaDB"),
    APP_ENV            = os.environ.get("APP_ENV",     "desenvolvimento"),
    UPLOAD_FOLDER      = os.path.join(os.path.dirname(__file__), "uploads", "temp"),
    MAX_CONTENT_LENGTH = 50 * 1024 * 1024,
    JWT_EXPIRES_HOURS  = 8,
)
os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
os.makedirs(os.path.join(os.path.dirname(__file__), "static", "logos"), exist_ok=True)

# ── Banco ─────────────────────────────────────────────────────
def get_db():
    if "db" not in g:
        g.db = pymysql.connect(
            host=app.config["DB_HOST"], user=app.config["DB_USER"],
            password=app.config["DB_PASSWORD"], database=app.config["DB_NAME"],
            charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor, autocommit=False,
        )
    return g.db

@app.teardown_appcontext
def close_db(e=None):
    db = g.pop("db", None)
    if db: db.close()

def query(sql, params=None, fetchall=True, commit=False):
    db = get_db()
    with db.cursor() as cur:
        cur.execute(sql, params or ())
        if commit:
            db.commit()
            return cur.lastrowid
        return cur.fetchall() if fetchall else cur.fetchone()

def get_config(chave, default=""):
    r = query("SELECT valor FROM configuracoes WHERE chave=%s", (chave,), fetchall=False)
    return r["valor"] if r else default

def get_limites():
    return {
        "Freada Brusca":         float(get_config("limite_freada",      "11")),
        "Excesso de Velocidade": float(get_config("limite_velocidade",  "85")),
        "RPM":                   float(get_config("limite_rpm",         "2100")),
    }

# ── Auditoria ─────────────────────────────────────────────────
def log_aud(acao, detalhe=None, uid=None, email=None):
    ip = request.headers.get("X-Forwarded-For", request.remote_addr)
    query("INSERT INTO auditoria (usuario_id,usuario_email,acao,detalhe,ip) VALUES(%s,%s,%s,%s,%s)",
          (uid, email, acao, detalhe, ip), commit=True)

# ── Senha ─────────────────────────────────────────────────────
def hash_senha(s): return hashlib.sha256(s.encode()).hexdigest()
def check_senha(s, h): return h != "__HASH_GERADO_PELO_APP__" and hash_senha(s) == h

# ── JWT ───────────────────────────────────────────────────────
def gerar_token(u):
    return jwt.encode({
        "id": u["id"], "email": u["email"], "perfil": u["perfil"],
        "exp": datetime.utcnow() + timedelta(hours=app.config["JWT_EXPIRES_HOURS"]),
    }, app.config["SECRET_KEY"], algorithm="HS256")

def requer_auth(*perfis):
    def dec(f):
        @wraps(f)
        def wrap(*a, **kw):
            h = request.headers.get("Authorization","")
            token = h[7:] if h.startswith("Bearer ") else None
            if not token: return jsonify({"erro":"Token não fornecido"}), 401
            try:
                g.usuario = jwt.decode(token, app.config["SECRET_KEY"], algorithms=["HS256"])
            except jwt.ExpiredSignatureError:
                return jsonify({"erro":"Sessão expirada"}), 401
            except jwt.InvalidTokenError:
                return jsonify({"erro":"Token inválido"}), 401
            if perfis and g.usuario["perfil"] not in perfis:
                return jsonify({"erro":"Acesso negado"}), 403
            return f(*a, **kw)
        return wrap
    return dec

# ── CORS ──────────────────────────────────────────────────────
@app.after_request
def cors(r):
    r.headers["Access-Control-Allow-Origin"]  = "*"
    r.headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
    r.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
    return r

@app.route("/api/<path:p>", methods=["OPTIONS"])
def opt(p): return "", 200

# ═══════════════════════════════════════════════════════════════
#  AUTH
# ═══════════════════════════════════════════════════════════════
@app.route("/api/auth/login", methods=["POST"])
def login():
    d = request.get_json(force=True)
    email = (d.get("email") or "").strip().lower()
    senha = d.get("senha","")
    if not email or not senha:
        return jsonify({"erro":"E-mail e senha obrigatórios"}), 400
    u = query("SELECT * FROM usuarios WHERE email=%s AND ativo=1", (email,), fetchall=False)
    if u and u["senha_hash"] == "__HASH_GERADO_PELO_APP__":
        query("UPDATE usuarios SET senha_hash=%s,ultimo_login=NOW() WHERE id=%s",
              (hash_senha(senha), u["id"]), commit=True)
        log_aud("primeiro_login", f"Usuário {email} definiu sua senha", u["id"], email)
        return jsonify({"token": gerar_token(u), "usuario": {"nome":u["nome"],"email":u["email"],"perfil":u["perfil"]}})
    if not u or not check_senha(senha, u["senha_hash"]):
        log_aud("login_falhou", f"email: {email}")
        return jsonify({"erro":"E-mail ou senha incorretos"}), 401
    query("UPDATE usuarios SET ultimo_login=NOW() WHERE id=%s", (u["id"],), commit=True)
    log_aud("login", None, u["id"], email)
    return jsonify({"token": gerar_token(u), "usuario": {"nome":u["nome"],"email":u["email"],"perfil":u["perfil"]}})

@app.route("/api/auth/me")
@requer_auth()
def me(): return jsonify(g.usuario)

# ═══════════════════════════════════════════════════════════════
#  USUÁRIOS
# ═══════════════════════════════════════════════════════════════
@app.route("/api/usuarios")
@requer_auth("superadmin","admin")
def listar_usuarios():
    rows = query("SELECT id,nome,email,perfil,ativo,criado_em,ultimo_login FROM usuarios ORDER BY nome")
    for r in rows:
        r["criado_em"]    = r["criado_em"].isoformat()    if r["criado_em"]    else None
        r["ultimo_login"] = r["ultimo_login"].isoformat() if r["ultimo_login"] else None
    return jsonify(rows)

@app.route("/api/usuarios", methods=["POST"])
@requer_auth("superadmin","admin")
def criar_usuario():
    d = request.get_json(force=True)
    nome  = (d.get("nome")  or "").strip()
    email = (d.get("email") or "").strip().lower()
    perfil= d.get("perfil","visualizador")
    senha = d.get("senha","Rit@2026")
    if not nome or not email: return jsonify({"erro":"Nome e e-mail obrigatórios"}), 400
    if perfil not in ("superadmin","admin","uploader","visualizador"):
        return jsonify({"erro":"Perfil inválido"}), 400
    if perfil == "superadmin" and g.usuario["perfil"] != "superadmin":
        return jsonify({"erro":"Apenas superadmin pode criar superadmin"}), 403
    try:
        uid = query("INSERT INTO usuarios(nome,email,senha_hash,perfil) VALUES(%s,%s,%s,%s)",
                    (nome, email, hash_senha(senha), perfil), commit=True)
    except pymysql.err.IntegrityError:
        return jsonify({"erro":"E-mail já cadastrado"}), 409
    log_aud("criar_usuario", f"{email} ({perfil})", g.usuario["id"], g.usuario["email"])
    return jsonify({"id":uid,"mensagem":f"Usuário criado. Senha inicial: {senha}"}), 201

@app.route("/api/usuarios/<int:uid>", methods=["PUT"])
@requer_auth("superadmin","admin")
def editar_usuario(uid):
    d = request.get_json(force=True)
    campos, vals = [], []
    if "nome"   in d: campos.append("nome=%s");       vals.append(d["nome"].strip())
    if "perfil" in d:
        if d["perfil"]=="superadmin" and g.usuario["perfil"]!="superadmin":
            return jsonify({"erro":"Apenas superadmin pode conceder este perfil"}), 403
        campos.append("perfil=%s"); vals.append(d["perfil"])
    if "ativo"  in d: campos.append("ativo=%s");      vals.append(int(d["ativo"]))
    if "senha"  in d and d["senha"]: campos.append("senha_hash=%s"); vals.append(hash_senha(d["senha"]))
    if not campos: return jsonify({"erro":"Nada para atualizar"}), 400
    vals.append(uid)
    query(f"UPDATE usuarios SET {', '.join(campos)} WHERE id=%s", vals, commit=True)
    log_aud("editar_usuario", f"id={uid}", g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem":"Usuário atualizado"})

@app.route("/api/usuarios/<int:uid>", methods=["DELETE"])
@requer_auth("superadmin")
def deletar_usuario(uid):
    if uid == g.usuario["id"]: return jsonify({"erro":"Não pode excluir sua própria conta"}), 400
    query("DELETE FROM usuarios WHERE id=%s", (uid,), commit=True)
    log_aud("deletar_usuario", f"id={uid}", g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem":"Usuário excluído"})

# ═══════════════════════════════════════════════════════════════
#  UPLOAD DIÁRIO
# ═══════════════════════════════════════════════════════════════
@app.route("/api/upload", methods=["POST"])
@requer_auth("superadmin","admin","uploader")
def upload():
    if "arquivo" not in request.files:
        return jsonify({"erro":"Nenhum arquivo enviado"}), 400
    f = request.files["arquivo"]
    if not f.filename.lower().endswith(".csv"):
        return jsonify({"erro":"Apenas arquivos .csv são aceitos"}), 400

    conteudo = f.read()
    nome     = secure_filename(f.filename)
    limites  = get_limites()

    try:
        res = limpar_csv(conteudo, limites)
    except ErroFormatoInesperado as e:
        log_aud("upload_erro", str(e), g.usuario["id"], g.usuario["email"])
        return jsonify({"erro": f"Formato inválido: {e}"}), 422

    df_limpo = res["df_limpo"]
    df_desc  = res["df_descartados"]
    stats    = res["stats"]
    avisos   = res["avisos"]

    # PDF descartados
    pdf_bytes = pdf_nome = None
    if len(df_desc) > 0:
        empresa = get_config("empresa_nome","RevolutionIT Soluções em TI")
        pdf_bytes = gerar_pdf_descartados(df_desc, stats, nome, empresa)
        pdf_nome  = f"descartados_{nome.replace('.csv','')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"

    imp_id = query(
        """INSERT INTO importacoes
           (usuario_id,nome_arquivo,tipo_upload,total_bruto,sem_motorista,abaixo_limite,
            validos,status,mensagem,pdf_descartados,pdf_nome,pdf_disponivel)
           VALUES(%s,%s,'diario',%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
        (g.usuario["id"], nome, stats["total_bruto"], stats["sem_motorista"],
         stats["abaixo_limite"], stats["validos"], "sucesso", "; ".join(avisos),
         pdf_bytes, pdf_nome, 1 if pdf_bytes else 0), commit=True
    )

    db = get_db()
    inseridos = duplicados = 0
    with db.cursor() as cur:
        for _, row in df_limpo.iterrows():
            cur.execute(
                """INSERT IGNORE INTO eventos
                   (chave_evento,motorista,data_evento,hora_evento,tipo,valor,total_occurs,importacao_id)
                   VALUES(%s,%s,%s,%s,%s,%s,%s,%s)""",
                (row["chave_evento"], row["motorista"],
                 row["data"].date() if hasattr(row["data"],"date") else row["data"],
                 row["hora"], row["tipo"], float(row["valor"]), int(row["total_occurs"]), imp_id)
            )
            if cur.rowcount > 0: inseridos += 1
            else: duplicados += 1
        db.commit()

    query("UPDATE importacoes SET duplicados=%s WHERE id=%s", (duplicados, imp_id), commit=True)
    log_aud("upload_diario", f"{nome} | válidos:{inseridos} | dup:{duplicados} | desc:{stats['sem_motorista']}",
            g.usuario["id"], g.usuario["email"])

    return jsonify({
        "importacao_id":  imp_id,
        "stats":          stats,
        "avisos":         avisos,
        "inseridos":      inseridos,
        "duplicados":     duplicados,
        "pdf_disponivel": pdf_bytes is not None,
        "pdf_url":        f"/api/upload/pdf/{imp_id}" if pdf_bytes else None,
    })

# ═══════════════════════════════════════════════════════════════
#  UPLOAD MENSAL — AUDITORIA
# ═══════════════════════════════════════════════════════════════
@app.route("/api/upload/mensal", methods=["POST"])
@requer_auth("superadmin","admin","uploader")
def upload_mensal():
    if "arquivo" not in request.files:
        return jsonify({"erro":"Nenhum arquivo enviado"}), 400
    f = request.files["arquivo"]
    if not f.filename.lower().endswith(".csv"):
        return jsonify({"erro":"Apenas .csv aceito"}), 400

    conteudo = f.read()
    nome     = secure_filename(f.filename)
    limites  = get_limites()

    try:
        res = limpar_csv(conteudo, limites)
    except ErroFormatoInesperado as e:
        return jsonify({"erro": f"Formato inválido: {e}"}), 422

    df_limpo = res["df_limpo"]
    df_desc  = res["df_descartados"]
    stats    = res["stats"]
    avisos   = res["avisos"]

    # Auditoria — comparar com banco
    resultado_aud = auditar_mensal(df_limpo, query)

    # PDF descartados
    pdf_d_bytes = pdf_d_nome = None
    if len(df_desc) > 0:
        empresa = get_config("empresa_nome","RevolutionIT Soluções em TI")
        pdf_d_bytes = gerar_pdf_descartados(df_desc, stats, nome, empresa)
        pdf_d_nome  = f"desc_mensal_{nome.replace('.csv','')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"

    # PDF auditoria
    empresa = get_config("empresa_nome","RevolutionIT Soluções em TI")
    pdf_a_bytes = gerar_pdf_auditoria_mensal(resultado_aud, nome, empresa)
    pdf_a_nome  = f"auditoria_{nome.replace('.csv','')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"

    imp_id = query(
        """INSERT INTO importacoes
           (usuario_id,nome_arquivo,tipo_upload,total_bruto,sem_motorista,abaixo_limite,
            validos,auditoria_ok,auditoria_div,auditoria_novos,auditoria_json,
            status,mensagem,
            pdf_descartados,pdf_nome,pdf_disponivel,
            pdf_auditoria,pdf_aud_nome,pdf_aud_disp)
           VALUES(%s,%s,'mensal',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)""",
        (g.usuario["id"], nome, stats["total_bruto"], stats["sem_motorista"],
         stats["abaixo_limite"], stats["validos"],
         resultado_aud["resumo"]["ok"], resultado_aud["resumo"]["divergentes"],
         resultado_aud["resumo"]["novos"], json.dumps(resultado_aud, default=str),
         "auditoria_pendente", "; ".join(avisos),
         pdf_d_bytes, pdf_d_nome, 1 if pdf_d_bytes else 0,
         pdf_a_bytes, pdf_a_nome, 1), commit=True
    )

    log_aud("upload_mensal",
            f"{nome} | ok:{resultado_aud['resumo']['ok']} | div:{resultado_aud['resumo']['divergentes']} | novos:{resultado_aud['resumo']['novos']}",
            g.usuario["id"], g.usuario["email"])

    return jsonify({
        "importacao_id":   imp_id,
        "stats":           stats,
        "avisos":          avisos,
        "auditoria":       {
            "resumo":            resultado_aud["resumo"],
            "dias_ok":           resultado_aud["dias_ok"],
            "dias_divergentes":  resultado_aud["dias_divergentes"],
            "eventos_novos_qtd": resultado_aud["resumo"]["novos"],
        },
        "pdf_desc_url":    f"/api/upload/pdf/{imp_id}"        if pdf_d_bytes else None,
        "pdf_aud_url":     f"/api/upload/pdf-auditoria/{imp_id}",
    })

@app.route("/api/upload/mensal/confirmar/<int:imp_id>", methods=["POST"])
@requer_auth("superadmin","admin","uploader")
def confirmar_mensal(imp_id):
    """Inserir eventos novos encontrados na auditoria mensal após confirmação do operador."""
    imp = query("SELECT * FROM importacoes WHERE id=%s AND tipo_upload='mensal'",
                (imp_id,), fetchall=False)
    if not imp: return jsonify({"erro":"Importação não encontrada"}), 404
    if imp["status"] != "auditoria_pendente":
        return jsonify({"erro":"Esta importação já foi processada"}), 409

    aud_json = json.loads(imp["auditoria_json"])
    novos_raw = aud_json.get("eventos_novos", [])

    inseridos = 0
    db = get_db()
    with db.cursor() as cur:
        for ev in novos_raw:
            cur.execute(
                """INSERT IGNORE INTO eventos
                   (chave_evento,motorista,data_evento,hora_evento,tipo,valor,total_occurs,importacao_id)
                   VALUES(%s,%s,%s,%s,%s,%s,%s,%s)""",
                (ev["chave_evento"], ev["motorista"], ev["data"][:10],
                 ev["hora"], ev["tipo"], float(ev["valor"]), int(ev["total_occurs"]), imp_id)
            )
            if cur.rowcount > 0: inseridos += 1
        db.commit()

    query("UPDATE importacoes SET status='sucesso' WHERE id=%s", (imp_id,), commit=True)
    log_aud("mensal_confirmado", f"imp_id={imp_id} | inseridos:{inseridos}",
            g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem": f"{inseridos} evento(s) inserido(s) com sucesso.", "inseridos": inseridos})

# ── Download PDFs ─────────────────────────────────────────────
@app.route("/api/upload/pdf/<int:imp_id>")
@requer_auth("superadmin","admin","uploader")
def baixar_pdf_desc(imp_id):
    r = query("SELECT pdf_descartados,pdf_nome,pdf_disponivel FROM importacoes WHERE id=%s",
              (imp_id,), fetchall=False)
    if not r or not r["pdf_disponivel"]: return jsonify({"erro":"PDF não disponível"}), 404
    pdf = r["pdf_descartados"]
    nome = r["pdf_nome"] or "relatorio.pdf"
    query("UPDATE importacoes SET pdf_descartados=NULL,pdf_disponivel=0 WHERE id=%s", (imp_id,), commit=True)
    log_aud("download_pdf_desc", f"imp_id={imp_id}", g.usuario["id"], g.usuario["email"])
    return send_file(io.BytesIO(pdf), mimetype="application/pdf",
                     as_attachment=True, download_name=nome)

@app.route("/api/upload/pdf-auditoria/<int:imp_id>")
@requer_auth("superadmin","admin","uploader")
def baixar_pdf_aud(imp_id):
    r = query("SELECT pdf_auditoria,pdf_aud_nome,pdf_aud_disp FROM importacoes WHERE id=%s",
              (imp_id,), fetchall=False)
    if not r or not r["pdf_aud_disp"]: return jsonify({"erro":"PDF não disponível"}), 404
    pdf  = r["pdf_auditoria"]
    nome = r["pdf_aud_nome"] or "auditoria.pdf"
    return send_file(io.BytesIO(pdf), mimetype="application/pdf",
                     as_attachment=True, download_name=nome)

@app.route("/api/importacoes")
@requer_auth("superadmin","admin","uploader")
def listar_importacoes():
    rows = query("""
        SELECT i.id,i.nome_arquivo,i.tipo_upload,i.total_bruto,i.sem_motorista,
               i.abaixo_limite,i.duplicados,i.validos,i.auditoria_ok,i.auditoria_div,
               i.auditoria_novos,i.status,i.pdf_disponivel,i.pdf_aud_disp,i.criado_em,
               u.nome AS usuario_nome
        FROM importacoes i JOIN usuarios u ON u.id=i.usuario_id
        ORDER BY i.criado_em DESC LIMIT 100
    """)
    for r in rows: r["criado_em"] = r["criado_em"].isoformat()
    return jsonify(rows)

# ═══════════════════════════════════════════════════════════════
#  DASHBOARD
# ═══════════════════════════════════════════════════════════════
def _filtro():
    p    = request.args.get("periodo","mes")
    hoje = date.today()
    if p == "personalizado":
        return request.args.get("inicio", str(hoje.replace(day=1))), request.args.get("fim", str(hoje))
    if p == "mes":       return str(hoje.replace(day=1)), str(hoje)
    if p == "trimestre": return str(hoje.replace(month=((hoje.month-1)//3)*3+1, day=1)), str(hoje)
    if p == "semestre":  return str(hoje.replace(month=1 if hoje.month<=6 else 7, day=1)), str(hoje)
    if p == "anual":     return str(hoje.replace(month=1, day=1)), str(hoje)
    return str(hoje.replace(day=1)), str(hoje)

@app.route("/api/dashboard/resumo")
@requer_auth()
def resumo():
    ini, fim = _filtro()
    r = query("""SELECT COUNT(*) AS total_eventos,
        COUNT(DISTINCT motorista) AS total_motoristas,
        SUM(CASE WHEN tipo='Freada Brusca' THEN 1 ELSE 0 END) AS freadas,
        SUM(CASE WHEN tipo='Excesso de Velocidade' THEN 1 ELSE 0 END) AS velocidades,
        SUM(CASE WHEN tipo='RPM' THEN 1 ELSE 0 END) AS rpms
        FROM eventos WHERE data_evento BETWEEN %s AND %s""", (ini,fim), fetchall=False)
    return jsonify({**r, "periodo": {"inicio":ini,"fim":fim}})

@app.route("/api/dashboard/ranking")
@requer_auth()
def ranking():
    ini, fim  = _filtro()
    ordem = request.args.get("ordem","desc")
    limit = int(request.args.get("limit",10))
    dir_  = "DESC" if ordem=="desc" else "ASC"
    rows  = query(f"""SELECT motorista,COUNT(*) AS total_eventos,
        SUM(CASE WHEN tipo='Freada Brusca' THEN 1 ELSE 0 END) AS freadas,
        SUM(CASE WHEN tipo='Excesso de Velocidade' THEN 1 ELSE 0 END) AS velocidades,
        SUM(CASE WHEN tipo='RPM' THEN 1 ELSE 0 END) AS rpms
        FROM eventos WHERE data_evento BETWEEN %s AND %s
        GROUP BY motorista ORDER BY total_eventos {dir_} LIMIT %s""", (ini,fim,limit))
    return jsonify(rows)

@app.route("/api/dashboard/evolucao")
@requer_auth()
def evolucao():
    ini, fim = _filtro()
    rows = query("""SELECT DATE_FORMAT(data_evento,'%%Y-%%m-%%d') AS dia,
        SUM(CASE WHEN tipo='Freada Brusca' THEN 1 ELSE 0 END) AS freadas,
        SUM(CASE WHEN tipo='Excesso de Velocidade' THEN 1 ELSE 0 END) AS velocidades,
        SUM(CASE WHEN tipo='RPM' THEN 1 ELSE 0 END) AS rpms,
        COUNT(*) AS total
        FROM eventos WHERE data_evento BETWEEN %s AND %s
        GROUP BY dia ORDER BY dia""", (ini,fim))
    return jsonify(rows)

# ═══════════════════════════════════════════════════════════════
#  TELÃO — PÚBLICO
# ═══════════════════════════════════════════════════════════════
@app.route("/api/tv")
def tv():
    hoje = date.today()
    p    = get_config("tv_periodo","mes")
    if p == "hoje":    ini = fim = str(hoje)
    elif p == "semana": ini = str(hoje - timedelta(days=hoje.weekday())); fim = str(hoje)
    else:              ini = str(hoje.replace(day=1)); fim = str(hoje)

    resumo_r = query("""SELECT COUNT(*) AS total_eventos,
        COUNT(DISTINCT motorista) AS total_motoristas,
        SUM(CASE WHEN tipo='Freada Brusca' THEN 1 ELSE 0 END) AS freadas,
        SUM(CASE WHEN tipo='Excesso de Velocidade' THEN 1 ELSE 0 END) AS velocidades,
        SUM(CASE WHEN tipo='RPM' THEN 1 ELSE 0 END) AS rpms
        FROM eventos WHERE data_evento BETWEEN %s AND %s""", (ini,fim), fetchall=False)

    exibir_nomes   = get_config("tv_exibir_nomes","1") == "1"
    exibir_piores  = get_config("tv_exibir_ranking_piores","1") == "1"
    exibir_melhores= get_config("tv_exibir_ranking_melhores","1") == "1"

    def mascara(rows):
        if exibir_nomes: return rows
        return [{"motorista": f"Motorista #{i+1}", "total": r["total"]} for i,r in enumerate(rows)]

    piores = melhores = []
    if exibir_piores:
        raw = query("SELECT motorista,COUNT(*) AS total FROM eventos WHERE data_evento BETWEEN %s AND %s GROUP BY motorista ORDER BY total DESC LIMIT 5", (ini,fim))
        piores = mascara(raw)
    if exibir_melhores:
        raw = query("SELECT motorista,COUNT(*) AS total FROM eventos WHERE data_evento BETWEEN %s AND %s GROUP BY motorista ORDER BY total ASC LIMIT 5", (ini,fim))
        melhores = mascara(raw)

    return jsonify({
        "resumo":    resumo_r,
        "piores":    piores,
        "melhores":  melhores,
        "config": {
            "logo_nome":        get_config("logo_nome","RevolutionIT"),
            "empresa_nome":     get_config("empresa_nome","RevolutionIT Soluções em TI"),
            "refresh_seg":      int(get_config("tv_refresh_seg","300")),
            "exibir_nomes":     exibir_nomes,
            "exibir_freadas":   get_config("tv_exibir_freadas","1")=="1",
            "exibir_veloc":     get_config("tv_exibir_veloc","1")=="1",
            "exibir_rpm":       get_config("tv_exibir_rpm","1")=="1",
            "exibir_piores":    exibir_piores,
            "exibir_melhores":  exibir_melhores,
        },
        "atualizado": datetime.now().isoformat(),
        "periodo":   {"inicio":ini,"fim":fim},
    })

# ═══════════════════════════════════════════════════════════════
#  CONFIGURAÇÕES
# ═══════════════════════════════════════════════════════════════
@app.route("/api/config")
@requer_auth()
def get_configs():
    rows = query("SELECT chave,valor,descricao FROM configuracoes ORDER BY chave")
    return jsonify({r["chave"]:{"valor":r["valor"],"descricao":r["descricao"]} for r in rows})

@app.route("/api/config", methods=["PUT"])
@requer_auth("superadmin","admin")
def update_config():
    d = request.get_json(force=True)
    for k,v in d.items():
        query("UPDATE configuracoes SET valor=%s WHERE chave=%s", (str(v),k), commit=True)
    log_aud("update_config", str(list(d.keys())), g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem":"Configurações salvas"})

@app.route("/api/config/logo", methods=["POST"])
@requer_auth("superadmin","admin")
def upload_logo():
    if "logo" not in request.files: return jsonify({"erro":"Nenhuma imagem enviada"}), 400
    f = request.files["logo"]
    ext = os.path.splitext(f.filename)[1].lower()
    if ext not in (".png",".jpg",".jpeg",".svg",".webp"):
        return jsonify({"erro":"Formato inválido. Use PNG, JPG ou SVG"}), 400
    logo_dir = os.path.join(app.static_folder,"logos")
    os.makedirs(logo_dir, exist_ok=True)
    nome = f"logo_custom{ext}"
    f.save(os.path.join(logo_dir, nome))
    query("UPDATE configuracoes SET valor=%s WHERE chave='logo_arquivo'", (nome,), commit=True)
    log_aud("upload_logo", nome, g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem":"Logo atualizado","arquivo":nome})

# ═══════════════════════════════════════════════════════════════
#  RESET DE BASE (só superadmin + só em desenvolvimento)
# ═══════════════════════════════════════════════════════════════
@app.route("/api/admin/reset", methods=["POST"])
@requer_auth("superadmin")
def reset_base():
    if app.config["APP_ENV"] == "producao":
        return jsonify({"erro":"Operação bloqueada em ambiente de produção"}), 403
    d = request.get_json(force=True)
    if d.get("confirmacao") != "CONFIRMO RESET COMPLETO":
        return jsonify({"erro":"Confirmação incorreta"}), 400
    query("DELETE FROM eventos",     commit=True)
    query("DELETE FROM importacoes", commit=True)
    log_aud("RESET_BASE", "Base zerada pelo superadmin", g.usuario["id"], g.usuario["email"])
    return jsonify({"mensagem":"Base zerada com sucesso. Usuários e configurações mantidos."})

# ═══════════════════════════════════════════════════════════════
#  AUDITORIA
# ═══════════════════════════════════════════════════════════════
@app.route("/api/auditoria")
@requer_auth("superadmin")
def listar_auditoria():
    limit = int(request.args.get("limit",200))
    rows  = query("SELECT id,usuario_email,acao,detalhe,ip,criado_em FROM auditoria ORDER BY criado_em DESC LIMIT %s", (limit,))
    for r in rows: r["criado_em"] = r["criado_em"].isoformat()
    return jsonify(rows)

# ═══════════════════════════════════════════════════════════════
#  STATIC / SPA
# ═══════════════════════════════════════════════════════════════
@app.route("/static/logos/<path:fn>")
def logos(fn): return send_from_directory(os.path.join(app.static_folder,"logos"), fn)

@app.route("/tv")
def tv_page(): return send_from_directory(app.static_folder, "tv.html")

@app.route("/", defaults={"path":""})
@app.route("/<path:path>")
def spa(path):
    if path.startswith("api/") or path.startswith("static/"): return jsonify({"erro":"Not found"}), 404
    idx = os.path.join(app.static_folder,"index.html")
    if os.path.exists(idx): return send_from_directory(app.static_folder,"index.html")
    return "Build do frontend não encontrado.", 404

if __name__ == "__main__":
    app.run(debug=True, port=5000)
