#!/bin/bash
BASE="/home/revolutionit/frota.revolutionit.com.br"

# ── limpeza.py ────────────────────────────────────────────────
cat > $BASE/scripts/limpeza.py << 'EOF'
import pandas as pd
import io

MAPA_TIPO = {
    "(TO) Freada Brusca":         "Freada Brusca",
    "(TO) Excesso de Velocidade": "Excesso de Velocidade",
    "Fora da Faixa Verde VW":     "RPM",
}

LIMITES_MINIMOS = {
    "Freada Brusca":         11,
    "Excesso de Velocidade": 85,
    "RPM":                 2100,
}

COLUNAS_OBRIGATORIAS = [
    "AssetName","EventStartDate","EventStartTime",
    "EventDescription","EventValue","TotalOccurs","StartOdo",
]

class ErroFormatoInesperado(Exception):
    pass

def _detectar_separador(dados_bytes):
    try:
        linhas = dados_bytes.decode("utf-8-sig", errors="replace").splitlines()
        linha = linhas[1] if len(linhas) > 1 else linhas[0]
        return "," if linha.count(",") > linha.count(";") else ";"
    except:
        return ","

def _converter_numero_br(serie):
    def _conv(v):
        v = str(v).strip().strip('"')
        if v in ('','nan','None','-','NaN'): return None
        if ',' in v: v = v.replace('.','').replace(',','.')
        elif v.count('.') > 1: v = v.replace('.','')
        try: return float(v)
        except: return None
    return serie.apply(_conv)

def limpar_csv(dados_bytes, limites=None):
    if limites is None:
        limites = LIMITES_MINIMOS.copy()
    avisos = []
    sep = _detectar_separador(dados_bytes)
    avisos.append(f"Separador detectado: {'virgula' if sep==',' else 'ponto-e-virgula'}")
    df = pd.read_csv(io.BytesIO(dados_bytes), sep=sep, encoding="utf-8-sig", dtype=str, on_bad_lines="skip")
    df.columns = [c.strip() for c in df.columns]
    total_bruto = len(df)
    faltando = [c for c in COLUNAS_OBRIGATORIAS if c not in df.columns]
    if faltando:
        raise ErroFormatoInesperado(f"Colunas ausentes: {faltando}")
    df = df.dropna(how="all")
    df["_mot"] = df["AssetName"].astype(str).str.strip().str.upper().str.replace(r"\s+", " ", regex=True)
    mask_sem = df["_mot"].isin(["UNKNOWN","NAN","","NONE","-"])
    df_desc = df[mask_sem].copy()
    df = df[~mask_sem].copy()
    qtd_sem = len(df_desc)
    if qtd_sem:
        avisos.append(f"{qtd_sem} evento(s) sem motorista identificado.")
    df["tipo"] = df["EventDescription"].map(MAPA_TIPO)
    df = df.dropna(subset=["tipo"])
    df["data"] = pd.to_datetime(df["EventStartDate"], dayfirst=True, errors="coerce")
    df = df.dropna(subset=["data"])
    df["hora"] = df["EventStartTime"].astype(str).str.strip()
    df["valor"] = _converter_numero_br(df["EventValue"])
    df["odometro"] = _converter_numero_br(df["StartOdo"])
    df["total_occurs"] = pd.to_numeric(df["TotalOccurs"], errors="coerce").fillna(1)
    df = df.dropna(subset=["valor"])
    lim_linha = df["tipo"].map(limites)
    mask_baixo = df["valor"] < lim_linha
    qtd_baixo = int(mask_baixo.sum())
    if qtd_baixo:
        avisos.append(f"{qtd_baixo} evento(s) abaixo do limite minimo.")
    df = df[~mask_baixo].copy()
    df["motorista"] = df["_mot"]
    df["chave_evento"] = (
        df["motorista"] + "|" +
        df["data"].dt.strftime("%Y-%m-%d") + "|" +
        df["hora"] + "|" +
        df["tipo"] + "|" +
        df["valor"].astype(str) + "|" +
        df["odometro"].fillna(0).astype(str)
    )
    df = df.drop_duplicates(subset=["chave_evento"])
    df_limpo = df[["chave_evento","motorista","data","hora","tipo","valor","total_occurs"]].reset_index(drop=True)
    cols_rel = [c for c in ["AssetName","EventStartDate","EventStartTime","EventDescription","EventValue","FleetNumber","F_StartCity","F_StartRegion"] if c in df_desc.columns]
    df_desc_rel = df_desc[cols_rel].rename(columns={"AssetName":"Motorista","EventStartDate":"Data","EventStartTime":"Hora","EventDescription":"Tipo de Evento","EventValue":"Valor","FleetNumber":"Frota","F_StartCity":"Cidade","F_StartRegion":"Estado"}).reset_index(drop=True)
    stats = {
        "total_bruto": total_bruto,
        "sem_motorista": qtd_sem,
        "abaixo_limite": qtd_baixo,
        "validos": len(df_limpo),
        "motoristas_unicos": int(df_limpo["motorista"].nunique()),
        "breakdown": df_limpo["tipo"].value_counts().to_dict(),
        "periodo_inicio": str(df_limpo["data"].min().date()) if len(df_limpo) else None,
        "periodo_fim": str(df_limpo["data"].max().date()) if len(df_limpo) else None,
    }
    return {"df_limpo": df_limpo, "df_descartados": df_desc_rel, "stats": stats, "avisos": avisos}
EOF

echo "limpeza.py OK"

# ── auditoria_mensal.py ───────────────────────────────────────
cat > $BASE/scripts/auditoria_mensal.py << 'EOF'
import pandas as pd

def auditar_mensal(df_limpo, db_query_fn):
    if len(df_limpo) == 0:
        return {"dias_ok":[],"dias_divergentes":[],"eventos_novos":pd.DataFrame(),"resumo":{"ok":0,"divergentes":0,"novos":0}}
    data_ini = str(df_limpo["data"].min().date())
    data_fim = str(df_limpo["data"].max().date())
    rows_banco = db_query_fn(
        "SELECT chave_evento, DATE_FORMAT(data_evento,'%%Y-%%m-%%d') as data FROM eventos WHERE data_evento BETWEEN %s AND %s",
        (data_ini, data_fim)
    )
    chaves_banco = set(r["chave_evento"] for r in rows_banco)
    banco_por_dia = {}
    for r in rows_banco:
        d = r["data"]
        banco_por_dia[d] = banco_por_dia.get(d,0) + 1
    mensal_por_dia = {}
    for _, row in df_limpo.iterrows():
        d = str(row["data"].date()) if hasattr(row["data"],"date") else str(row["data"])[:10]
        mensal_por_dia[d] = mensal_por_dia.get(d,0) + 1
    todos_dias = sorted(set(list(banco_por_dia.keys()) + list(mensal_por_dia.keys())))
    dias_ok = []
    dias_divergentes = []
    for dia in todos_dias:
        qb = banco_por_dia.get(dia,0)
        qm = mensal_por_dia.get(dia,0)
        if qb == qm:
            dias_ok.append({"data":dia,"quantidade":qm})
        else:
            dias_divergentes.append({"data":dia,"banco":qb,"mensal":qm,"diferenca":qm-qb})
    mask_novo = ~df_limpo["chave_evento"].isin(chaves_banco)
    eventos_novos = df_limpo[mask_novo].copy()
    resumo = {
        "periodo_inicio": data_ini,
        "periodo_fim": data_fim,
        "ok": len(dias_ok),
        "divergentes": len(dias_divergentes),
        "novos": len(eventos_novos),
        "total_banco": len(rows_banco),
        "total_mensal": len(df_limpo),
    }
    return {"dias_ok":dias_ok,"dias_divergentes":dias_divergentes,"eventos_novos":eventos_novos,"resumo":resumo}
EOF

echo "auditoria_mensal.py OK"

# ── relatorio_pdf.py ──────────────────────────────────────────
cat > $BASE/scripts/relatorio_pdf.py << 'EOF'
import io
from datetime import datetime
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, HRFlowable
from reportlab.lib.enums import TA_CENTER, TA_LEFT

NAVY  = colors.HexColor("#1C1E3B")
BLUE  = colors.HexColor("#1CA6FC")
GRAY  = colors.HexColor("#ECECEC")
RED   = colors.HexColor("#DC2626")
GREEN = colors.HexColor("#16A34A")
AMBER = colors.HexColor("#F59E0B")
WHITE = colors.white
DARK  = colors.HexColor("#2D2D2D")

def _tabela_padrao(dados, col_widths=None):
    n = len(dados[0]) if dados else 1
    cw = col_widths or [17*cm/n]*n
    t = Table(dados, colWidths=cw, repeatRows=1)
    t.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,0),NAVY),
        ("TEXTCOLOR",(0,0),(-1,0),WHITE),
        ("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
        ("FONTSIZE",(0,0),(-1,-1),8),
        ("ALIGN",(0,0),(-1,-1),"CENTER"),
        ("VALIGN",(0,0),(-1,-1),"MIDDLE"),
        ("ROWBACKGROUNDS",(0,1),(-1,-1),[WHITE,GRAY]),
        ("GRID",(0,0),(-1,-1),0.3,colors.HexColor("#CCCCCC")),
        ("TOPPADDING",(0,0),(-1,-1),4),
        ("BOTTOMPADDING",(0,0),(-1,-1),4),
    ]))
    return t

def gerar_pdf_descartados(df_desc, stats, nome_arquivo, nome_empresa="RevolutionIT"):
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(buffer, pagesize=A4, leftMargin=2*cm, rightMargin=2*cm, topMargin=2*cm, bottomMargin=2*cm)
    styles = getSampleStyleSheet()
    story = []
    s_tit = ParagraphStyle("t", fontName="Helvetica-Bold", fontSize=18, textColor=NAVY, alignment=TA_CENTER, spaceAfter=4)
    s_sub = ParagraphStyle("s", fontName="Helvetica", fontSize=11, textColor=BLUE, alignment=TA_CENTER, spaceAfter=2)
    s_meta = ParagraphStyle("m", fontName="Helvetica", fontSize=9, textColor=DARK, alignment=TA_CENTER, spaceAfter=12)
    s_alert = ParagraphStyle("al", fontName="Helvetica-Bold", fontSize=10, textColor=RED, spaceAfter=10)
    s_footer = ParagraphStyle("f", fontName="Helvetica", fontSize=8, textColor=colors.HexColor("#808080"), alignment=TA_CENTER, spaceBefore=4)
    story.append(Paragraph(nome_empresa, s_tit))
    story.append(Paragraph("Relatorio de Eventos sem Motorista Identificado", s_sub))
    story.append(Paragraph(f"Arquivo: {nome_arquivo} | Gerado: {datetime.now().strftime('%d/%m/%Y %H:%M')}", s_meta))
    story.append(HRFlowable(width="100%", thickness=2, color=NAVY))
    story.append(Spacer(1, 0.4*cm))
    story.append(Paragraph(f"ATENCAO: {stats.get('sem_motorista',0)} evento(s) descartados por falta de motorista identificado.", s_alert))
    if df_desc is not None and len(df_desc) > 0:
        cols = list(df_desc.columns)
        dados = [cols] + df_desc.fillna("-").values.tolist()
        story.append(_tabela_padrao(dados))
    story.append(Spacer(1, 0.8*cm))
    story.append(HRFlowable(width="100%", thickness=1, color=NAVY))
    story.append(Paragraph("Desenvolvido por RevolutionIT Solucoes em TI | revolutionit.com.br", s_footer))
    doc.build(story)
    buffer.seek(0)
    return buffer.read()

def gerar_pdf_auditoria_mensal(resultado_auditoria, nome_arquivo, nome_empresa="RevolutionIT"):
    buffer = io.BytesIO()
    resumo = resultado_auditoria.get("resumo",{})
    doc = SimpleDocTemplate(buffer, pagesize=A4, leftMargin=2*cm, rightMargin=2*cm, topMargin=2*cm, bottomMargin=2*cm)
    story = []
    s_tit = ParagraphStyle("t", fontName="Helvetica-Bold", fontSize=18, textColor=NAVY, alignment=TA_CENTER, spaceAfter=4)
    s_sub = ParagraphStyle("s", fontName="Helvetica", fontSize=11, textColor=BLUE, alignment=TA_CENTER, spaceAfter=2)
    s_meta = ParagraphStyle("m", fontName="Helvetica", fontSize=9, textColor=DARK, alignment=TA_CENTER, spaceAfter=12)
    s_sec = ParagraphStyle("sec", fontName="Helvetica-Bold", fontSize=11, textColor=NAVY, spaceAfter=6)
    s_footer = ParagraphStyle("f", fontName="Helvetica", fontSize=8, textColor=colors.HexColor("#808080"), alignment=TA_CENTER, spaceBefore=4)
    story.append(Paragraph(nome_empresa, s_tit))
    story.append(Paragraph("Relatorio de Auditoria Mensal", s_sub))
    story.append(Paragraph(f"Periodo: {resumo.get('periodo_inicio','')} a {resumo.get('periodo_fim','')} | Gerado: {datetime.now().strftime('%d/%m/%Y %H:%M')}", s_meta))
    story.append(HRFlowable(width="100%", thickness=2, color=NAVY))
    story.append(Spacer(1, 0.4*cm))
    dados_res = [["Dias OK","Dias c/ Divergencia","Eventos Novos"],[str(resumo.get("ok",0)),str(resumo.get("divergentes",0)),str(resumo.get("novos",0))]]
    t_res = Table(dados_res, colWidths=[5.67*cm]*3)
    t_res.setStyle(TableStyle([
        ("BACKGROUND",(0,0),(-1,0),NAVY),("TEXTCOLOR",(0,0),(-1,0),WHITE),
        ("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),("FONTSIZE",(0,0),(-1,0),9),
        ("ALIGN",(0,0),(-1,-1),"CENTER"),("VALIGN",(0,0),(-1,-1),"MIDDLE"),
        ("FONTNAME",(0,1),(-1,1),"Helvetica-Bold"),("FONTSIZE",(0,1),(-1,1),24),
        ("TEXTCOLOR",(0,1),(0,1),GREEN),("TEXTCOLOR",(1,1),(1,1),RED),("TEXTCOLOR",(2,1),(2,1),AMBER),
        ("BACKGROUND",(0,1),(-1,1),GRAY),("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#CCCCCC")),
        ("TOPPADDING",(0,0),(-1,-1),10),("BOTTOMPADDING",(0,0),(-1,-1),10),
    ]))
    story.append(t_res)
    story.append(Spacer(1, 0.5*cm))
    divs = resultado_auditoria.get("dias_divergentes",[])
    if divs:
        story.append(Paragraph("Dias com Divergencia", s_sec))
        dados_div = [["Data","No Banco","No Mensal","Diferenca"]]
        for d in divs:
            cor_dif = f"+{d['diferenca']}" if d['diferenca']>0 else str(d['diferenca'])
            dados_div.append([d["data"],str(d["banco"]),str(d["mensal"]),cor_dif])
        story.append(_tabela_padrao(dados_div,[4*cm,3.5*cm,3.5*cm,3.5*cm]))
        story.append(Spacer(1,0.4*cm))
    dias_ok = resultado_auditoria.get("dias_ok",[])
    if dias_ok:
        story.append(Paragraph("Dias Conferidos e OK", s_sec))
        dados_ok = [["Data","Quantidade de Eventos"]]
        for d in dias_ok:
            dados_ok.append([d["data"],str(d["quantidade"])])
        story.append(_tabela_padrao(dados_ok,[8.5*cm,8.5*cm]))
    story.append(Spacer(1, 0.8*cm))
    story.append(HRFlowable(width="100%", thickness=1, color=NAVY))
    story.append(Paragraph("Desenvolvido por RevolutionIT Solucoes em TI | revolutionit.com.br", s_footer))
    doc.build(story)
    buffer.seek(0)
    return buffer.read()
EOF

echo "relatorio_pdf.py OK"

echo ""
echo "✅ Todos os scripts criados!"
ls -la $BASE/scripts/
