#!/usr/bin/env python3
"""Genera Agenda DOCX + HTML Dashboard para Bruna Peru Weekly Review — 26 octubre 2026"""

import sys
sys.path.insert(0, '/home/node/.hermes/venv/lib/python3.13/site-packages')

from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import datetime, os

FECHA = "26 de octubre, 2026"
FECHA_FILE = "2026-10-26"
OUTPUT_DIR = "/home/node/workspace/bruna-peru/outputs"
os.makedirs(OUTPUT_DIR, exist_ok=True)

# ─── Colores ──────────────────────────────────────────────────────────
NAVY   = RGBColor(0x1B, 0x4F, 0x72)
ACCENT = RGBColor(0x2E, 0x86, 0xC1)
RED    = RGBColor(0xC0, 0x39, 0x2B)
ORANGE = RGBColor(0xE6, 0x7E, 0x22)
GREEN  = RGBColor(0x27, 0xAE, 0x60)
PURPLE = RGBColor(0x8E, 0x44, 0xAD)
YELLOW = RGBColor(0xF1, 0xC4, 0x0F)
GRAY   = RGBColor(0x95, 0xA5, 0xA6)
DARK   = RGBColor(0x2C, 0x3E, 0x50)

STATUS_COLORS = {
    "HECHO": GREEN,
    "AVANZADO": YELLOW,
    "NO AVANZADO": RED,
    "VERIFICAR": ORANGE,
    "NUEVO": PURPLE,
}

def add_heading(doc, text, level=1, color=NAVY):
    p = doc.add_paragraph()
    p.paragraph_format.space_before = Pt(12 if level == 1 else 8)
    p.paragraph_format.space_after = Pt(4)
    run = p.add_run(text)
    run.bold = True
    run.font.size = Pt(18 if level == 1 else 13 if level == 2 else 11)
    run.font.color.rgb = color
    return p

def add_status_item(doc, text, status, responsible="", indent_in=0.3):
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Inches(indent_in)
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after = Pt(2)
    badge = p.add_run(f"[{status}] ")
    badge.bold = True
    badge.font.color.rgb = STATUS_COLORS.get(status, DARK)
    badge.font.size = Pt(10)
    main = p.add_run(text)
    main.font.size = Pt(10)
    if responsible:
        rr = p.add_run(f"  \u2192 {responsible}")
        rr.font.color.rgb = ACCENT
        rr.font.size = Pt(9)
    return p

def add_divider(doc):
    p = doc.add_paragraph("\u2500" * 80)
    p.paragraph_format.space_before = Pt(4)
    p.paragraph_format.space_after = Pt(4)
    p.runs[0].font.color.rgb = ACCENT
    p.runs[0].font.size = Pt(7)

def add_bullet(doc, text):
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Inches(0.4)
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after = Pt(2)
    run = p.add_run(f"\u2022 {text}")
    run.font.size = Pt(10)
    return p

# ─── Inteligencia semana 20 – 26 oct 2026 ─────────────────────────────
# FUENTES ESCANEADAS (gmail-personal + icloud, INBOX + @SaneLater + All Mail):
# • CERO emails entrantes de clientes o prospectos Perú en las 2 bandejas (20–26 oct).
#   SEMANA 13 CONSECUTIVA DE SILENCIO COMERCIAL TOTAL. Solo Google Alerts + ruido.
# • Único thread comercial de la semana: decisión tomada por Andrés sobre proveedor
#   de trade-data (Globalwits, USD 9,000/año) — DECLINADO el 22-oct. Se mantiene la
#   plataforma existente. No volver a abrir el tema.
# • Google Alerts TiO2 (20–26 oct): señal ESTRUCTURAL. India reimpuso aranceles
#   antidumping al TiO2 chino de USD 460–681/ton por 5 años. Implicación doble:
#   (1) oferta china desplazada de India buscará otros destinos (LatAm incluido)
#   = más disponibilidad y presión de precios a favor del comprador peruano;
#   (2) refuerza la tesis de piso de precios para cerrar cotizaciones YA
#   (Universal Colors, Chemifabrik, oferta vs Billions 896 en Qroma).
# • Tronox: resultados Q3 el 4-nov — catalizador cercano para la narrativa de distress.

urgentes = [
    "COMPROMISOS VISITA 9-OCT — SEMANA 3 SIN EJECUCIÓN VISIBLE: (1) fórmulas neopreno Arlanxeo con Qroma (hito nov), (2) muestra epóxica 1 kg + cotización al 50% con IGV a Chemifabrik, (3) oferta TiO2 contra Billions 896 por los 3 MT de Erica. Cero emails de seguimiento de ninguna de las partes. Víctor + Jennifer: reportar HOY estado real de cada compromiso. Quedan ~5 días hábiles para el hito de noviembre.",
    "Daryza — cotización OVERDUE 32 SEMANAS. Reportar HOY: ¿visita presencial comprometida? Si NO, Jennifer + Andrés deciden esta semana SIN excepción: visita o cierre formal de la cuenta.",
    "Oral Care Diego Gómez — req formal planeamiento Lurín OVERDUE 17 SEMANAS. Jorge: reportar en los primeros 10 minutos. Si no hay confirmación escrita esta semana, cuenta en pausa hasta nuevo sponsor.",
    "PO Norway — OVERDUE 26 SEMANAS. Carlos: propuesta de cierre o cancelación lista HOY. Fecha límite improrrogable.",
    "Finka Metals (Volcán) — lista 13 productos CF OVERDUE 13 SEMANAS. Víctor: confirmar si se envió. Si NO: enviar los primeros 15 minutos de la reunión.",
    "DocuSign VCB S.A.C. — verificar firma de Contrato + KYC (enviado 20 ago). Apertura cuenta bancaria VCB sigue bloqueada hasta confirmar.",
    "HubSpot CRM — adopción OVERDUE 12 semanas (acuerdo 23 jul). Andrés: decisión final esta semana por call con Víctor — implementar o seleccionar alternativa.",
    "SILENCIO COMERCIAL SEMANA 13 — Decimotercera semana consecutiva sin un solo email entrante de cliente o prospecto (escaneo completo: INBOX, SaneLater, All Mail, 40+ keywords). Víctor: mínimo 3 contactos activos esta semana CON evidencia (nombre, fecha, resultado). Sin reporte = escalación formal a Andrés.",
]

intel_correos = [
    ("Google Alerts TiO2 (20–26 oct) — India antidumping", "SEÑAL ESTRUCTURAL: India reimpuso aranceles antidumping al TiO2 chino de USD 460–681/ton por 5 años. Consecuencia directa: volumen chino desplazado de India buscará otros destinos, incluida LatAm. Para Bruna Perú esto es munición doble: (1) más oferta china disponible y presionada = mejor posición de negociación para los compradores peruanos; (2) refuerza la tesis de piso de precios — nadie gana dinero a estos niveles. Usar en las cotizaciones Universal Colors, Chemifabrik y en la oferta contra Billions 896 (Qroma) ESTA SEMANA."),
    ("Tronox — catalizador 4-nov", "Recordatorio: Tronox reporta resultados Q3 el 4 de noviembre. Tras el downgrade a Strong Sell (Zacks, 15-oct) y el target de USD 4.00 (Goldman), el mercado espera confirmación de distress. Si se confirma, el argumento de piso de precios queda blindado para el cierre de Q4. Preparar la cita para las propuestas."),
    ("Trade-data (Globalwits) — decisión cerrada", "Andrés declinó la propuesta de USD 9,000/año (22-oct): ya existe plataforma de trade-data y analítica interna. TEMA CERRADO — no volver a presentar proveedores de datos de aduanas sin instrucción expresa."),
    ("Silencio comercial SEMANA 13 (20–26 oct)", "SEMANA 13 DE SILENCIO COMERCIAL TOTAL. Cero emails entrantes de clientes o prospectos en gmail-personal ni icloud (INBOX, @SaneLater, All Mail, 40+ keywords). Tres meses seguidos sin demanda entrante por email: el pipeline depende 100% de la generación activa del equipo — visitas, llamadas, cotizaciones. El funnel no se llena solo."),
]

pendientes = {
    "Víctor Alfaro": {
        "rol": "Gerente General Lima",
        "items": [
            ("QROMA — seguimiento visita 9-oct: fórmulas neopreno Arlanxeo (hito nov) + acompañar oferta TiO2 vs Billions 896 (3 MT Erica)", "NUEVO"),
            ("Reportar mínimo 3 contactos activos con evidencia (nombre, fecha, resultado). Semana 12 de silencio. Sin reporte = escalación a Andrés.", "VERIFICAR"),
            ("Cafetal — status satisfacción post-entrega y próxima orden K2CO3 (6,600 kg restantes)", "VERIFICAR"),
            ("Universal Colors — TiO2 588 + óxidos hierro: cerrar cotización con argumento de piso de precios y oferta líquida (LB Group/Hartlepool refuerza la tesis)", "VERIFICAR"),
            ("Prospectos pintura — Chemifabrik ya abrió puerta multi-línea: replicar modelo de visita en 2 prospectos más (Anipsa, Perupaint, Soprint, Interpaint)", "VERIFICAR"),
            ("Minería — status reunión + propuesta MIBC, xantatos: reportar avance", "VERIFICAR"),
        ]
    },
    "Jennifer Segura": {
        "rol": "Líder Mercado Perú",
        "items": [
            ("CRÍTICO NUEVO: Chemifabrik — muestra epóxica 100% sólidos 1 kg + cotización epóxicas al 50% (precio con IGV). Tarea P4 del panel. Esta semana.", "NUEVO"),
            ("CRÍTICO OVERDUE 32 SEM: Daryza — reportar HOY si se hizo visita presencial. Si NO: decisión esta semana con Andrés sobre cierre o visita inminente.", "NO AVANZADO"),
            ("Aurora Paint — resinas epóxicas VYTA BPA: 13 semanas silencio. Recontactar o suspender oficialmente esta semana.", "NO AVANZADO"),
            ("Alimentos (Pursuit, JAVA, Creafoods) — mínimo 1 contacto + reporte", "VERIFICAR"),
            ("Profinne — status cotización MPs especiales: update en reunión", "VERIFICAR"),
        ]
    },
    "Andrés Bruna": {
        "rol": "Director Nuevos Mercados",
        "items": [
            ("Confirmar si DocuSign VCB fue firmado (enviado 20 ago, 9 semanas). Si NO: firmar esta semana, sin excusa de viaje.", "NO AVANZADO"),
            ("HubSpot CRM — decisión FINAL por call con Víctor esta semana. 12 semanas OVERDUE. Prerrequisito de la operación local 2027 (P6).", "NO AVANZADO"),
            ("QROMA P1 — fórmulas neopreno Arlanxeo (hito nov 2026): definir equipo, muestras y cronograma esta semana", "NUEVO"),
            ("CHEMIFABRIK P5 — evaluar envases 19 L + robótica como servicio (alcance, costo, decisión go/no-go)", "NUEVO"),
            ("VCB P6 — plan de operación local 2027: primer borrador de estructura y requerimientos", "NUEVO"),
            ("Grupo Romero (Rafa Villa, Pedro Clay, Estefanía Loza) — briefs R1/R2 listos 23-24 sep: convertir en reunión confirmada esta semana.", "NO AVANZADO"),
            ("Daryza — si Jenny no confirmó visita presencial, escalar a decisión esta semana", "VERIFICAR"),
        ]
    },
    "Jorge Bruna": {
        "rol": "Empaques / Oral Care",
        "items": [
            ("Oral Care Diego Gómez — OVERDUE 17 SEM: reportar si hay confirmación escrita req formal Lurín. Si NO: llamada hoy.", "NO AVANZADO"),
            ("Coordinar prueba impresión + armado tubos en Lurín (prensa flexo) — fecha concreta esta semana", "VERIFICAR"),
            ("Verificar energía superficial + linaje muestras antes de impresión", "VERIFICAR"),
            ("Romex/Nico — liners y tapas: status producción y calidad semana", "VERIFICAR"),
        ]
    },
    "Carlos Artavia": {
        "rol": "Logística / SPU",
        "items": [
            ("PO Norway OVERDUE 25 SEM: propuesta formal cierre o cancelación a Andrés HOY. Última semana.", "NO AVANZADO"),
            ("Cafetal K2CO3 — 6,600 kg restantes: confirmar coordinación CargoFlex + próxima fecha entrega", "VERIFICAR"),
            ("Confirmar pago impuestos + liberación carga (Ileana) — status hito Cafetal", "VERIFICAR"),
        ]
    },
    "Vanessa García": {
        "rol": "BDU / Soporte Comercial",
        "items": [
            ("Org chart Grupo Romero actualizado + costos reales policloropreno — OVERDUE. Entregar esta semana.", "VERIFICAR"),
            ("QROMA — actualizar data policloropreno SN242A/SN244X con hallazgos visita 9-oct antes del hito Arlanxeo", "NUEVO"),
        ]
    },
    "Mildred": {
        "rol": "Admin",
        "items": [
            ("Portal Evis — pagos y facturación pendientes: revisar y reportar status", "VERIFICAR"),
        ]
    },
    "Lourdes Arley": {
        "rol": "Finanzas",
        "items": [
            ("Cuenta bancaria VCB — confirmar si Andrés firmó DocuSign. Coordinar siguientes pasos.", "VERIFICAR"),
            ("Confirmación pagos/fondeos VCB S.A.C. semana en curso", "VERIFICAR"),
        ]
    },
}

cuentas = [
    ("Grupo Romero — Pintura / Polímeros", "AVANZADO", [
        ("Lufarol, CaCO3, 12 productos aprobados — briefs R1 Laundry + R2 HPC listos (23-24 sep): agendar reunión YA", "Andrés / Jennifer", "P1"),
        ("Org chart + costos policloropreno OVERDUE — sin entregar", "Vanessa García", "P2"),
        ("Rafa Villa, Pedro Clay, Estefanía Loza — contacto esta semana", "Andrés Bruna", "P1"),
    ]),
    ("Cafetal (K2CO3 grado oral)", "AVANZADO", [
        ("CargoFlex: 6,600 kg restantes — confirmar próxima entrega + fecha", "Carlos Artavia", "P1"),
        ("Pago impuestos + liberación carga (Ileana) — confirmar status", "Carlos Artavia", "P1"),
        ("Post-entrega 1ra partida: satisfacción + próxima orden", "Víctor Alfaro", "P2"),
    ]),
    ("Romex / Nico", "VERIFICAR", [
        ("Liners y tapas — status producción y control calidad", "Jorge Bruna", "P1"),
        ("Cambios técnicos o de precio pendientes", "Jorge Bruna", "P2"),
    ]),
    ("Daryza", "NO AVANZADO", [
        ("Lista 30+ MPs — cotización formal OVERDUE 31 SEMANAS", "Jennifer Segura", "P1"),
        ("MPs prioritarias: LSE 82t, Ac. Sulfónico 58t, NaOH 46t, PEAD 38t", "", "P1"),
        ("DECISION ESTA SEMANA: visita presencial o cuenta cerrada", "Jennifer / Andrés", "P1"),
    ]),
    ("Aurora Paint", "NO AVANZADO", [
        ("Resinas epóxicas VYTA BPA — 12 semanas silencio total", "Jennifer Segura", "P1"),
        ("Recontactar o suspender oficialmente esta semana", "Jennifer Segura", "P1"),
    ]),
    ("Universal Colors", "VERIFICAR", [
        ("TiO2 588 + óxidos hierro — cerrar cotización con argumento piso de precios", "Jennifer / Víctor", "P1"),
        ("Argumento NUEVO: distress financiero del mayor productor occidental de TiO2 (Tronox Strong Sell, target USD 4) = piso confirmado + clientes buscando alternativas. Cerrar YA", "", "P1"),
    ]),
    ("Qroma", "AVANZADO", [
        ("NUEVO — Visita 9-oct: neopreno Arlanxeo como referencia, hito noviembre 2026 (sobre 3 SKUs aprobados; pipeline SN242/SN244X $165,600)", "Andrés Bruna", "P1"),
        ("NUEVO — Erica Caballero compra 3 MT Billions 896 (competidor TiO2): preparar oferta contra ese precio", "Víctor Alfaro", "P1"),
        ("NUEVO — Caro revisa Virutex/Longato (sustitución/mezcla): seguimiento", "Víctor Alfaro", "P2"),
        ("Neopreno, caucho clorado, parafina — follow-up reunión Baldión pendiente", "Víctor Alfaro", "P2"),
    ]),
    ("Prospectos Pintura", "NUEVO", [
        ("NUEVO — CHEMIFABRIK abrió puerta multi-línea (visita 9-oct): epóxicas 50% + TiO2 + sílica + PVA; volumen 16+16 MT por confirmar", "Jennifer / Andrés", "P1"),
        ("Anipsa, Perupaint, Soprint, Interpaint — mínimo 2 cold visits esta semana con el modelo Qroma/Chemifabrik", "Víctor Alfaro", "P3"),
    ]),
    ("Plásticos", "VERIFICAR", [
        ("Tigre, Andinaplast, Nicoll — cera PE, TiO2, masterbatch: status cotizaciones", "Víctor Alfaro", "P3"),
        ("Inproplast — contacto inicial pendiente", "Víctor Alfaro", "P3"),
    ]),
    ("Minería", "VERIFICAR", [
        ("Contacto principal (MIBC, xantatos) — confirmar status reunión esta semana", "Víctor Alfaro", "P1"),
        ("Finka Metals lista 13 productos CF OVERDUE 13 SEM — enviar HOY", "Víctor Alfaro", "P1"),
    ]),
    ("Oral Care", "NO AVANZADO", [
        ("Diego Gómez req formal planeamiento Lurín OVERDUE 17 semanas", "Jorge Bruna", "P1"),
        ("Muestras en lab sin usar — confirmar fecha prueba impresión Lurín", "Jorge Bruna", "P1"),
        ("Ruby, fórmula, equipos — status pipeline", "Andrés Bruna", "P2"),
    ]),
    ("Alimentos", "VERIFICAR", [
        ("Pursuit, JAVA, Creafoods — ácidos y especialidades: mínimo 1 contacto + update", "Jennifer / Víctor", "P3"),
    ]),
]

overdue_cronicos = [
    ("Daryza — cotización formal (30+ MPs lista José Urbina)", "32 SEMANAS", "Jennifer Segura"),
    ("PO Norway — inventario status + propuesta cierre/cancelación", "26 SEMANAS", "Carlos Artavia"),
    ("Oral Care — req formal Diego Gómez a planeamiento Lurín", "17 SEMANAS", "Jorge Bruna"),
    ("Finka Metals — envío lista 13 productos CF a Volcán", "13 SEMANAS", "Víctor Alfaro"),
    ("Aurora Paint — recontacto resinas epóxicas VYTA BPA", "13 SEMANAS SILENCIO", "Jennifer Segura"),
    ("HubSpot — adopción CRM definitiva", "12 SEMANAS", "Andrés Bruna"),
    ("DocuSign VCB — firmar Contrato + KYC (enviado 20 ago)", "9 SEMANAS", "Andrés Bruna"),
    ("Silencio comercial total — ningún email entrante cliente/prospecto", "13 SEMANAS", "Todo el equipo"),
]

# ─── GENERAR DOCX ─────────────────────────────────────────────────────
doc = Document()

for section in doc.sections:
    section.top_margin = Inches(0.8)
    section.bottom_margin = Inches(0.8)
    section.left_margin = Inches(1.0)
    section.right_margin = Inches(1.0)

# Título
title = doc.add_paragraph()
title.alignment = WD_ALIGN_PARAGRAPH.CENTER
tr = title.add_run("\U0001f1f5\U0001f1ea  BRUNA PERU \u2014 WEEKLY REVIEW")
tr.bold = True
tr.font.size = Pt(22)
tr.font.color.rgb = NAVY

sub = doc.add_paragraph()
sub.alignment = WD_ALIGN_PARAGRAPH.CENTER
sr = sub.add_run(f"Agenda Ejecutiva | {FECHA} | Causita Intelligence")
sr.font.size = Pt(11)
sr.font.color.rgb = GRAY

add_divider(doc)

# ─── URGENTES ─────────────────────────────────────────────────────────
add_heading(doc, "\U0001f534  URGENTE ESTA SEMANA", 1, RED)
for u in urgentes:
    add_bullet(doc, u)

add_divider(doc)

# ─── INTEL EMAIL ──────────────────────────────────────────────────────
add_heading(doc, "\U0001f4ec  INTEL DE CORREOS (20 oct \u2013 26 oct 2026)", 1, NAVY)
for fuente, txt in intel_correos:
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Inches(0.4)
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after = Pt(2)
    label = p.add_run(f"[{fuente}] ")
    label.bold = True
    label.font.color.rgb = ACCENT
    label.font.size = Pt(9)
    body = p.add_run(txt)
    body.font.size = Pt(10)

add_divider(doc)

# ─── CUENTAS ──────────────────────────────────────────────────────────
add_heading(doc, "\U0001f4cb  ESTADO DE CUENTAS (12 cuentas activas)", 1, NAVY)
for nombre, status, subtareas in cuentas:
    add_heading(doc, f"  {nombre}", 2,
        RED if status == "NO AVANZADO" else
        GREEN if status == "HECHO" else
        YELLOW if status == "AVANZADO" else
        PURPLE if status == "NUEVO" else ORANGE)
    for tarea, resp, prioridad in subtareas:
        add_status_item(doc, f"[{prioridad}] {tarea}", status,
            responsible=resp if resp else "")

add_divider(doc)

# ─── OVERDUE CRÓNICO ──────────────────────────────────────────────────
add_heading(doc, "\u23f0  OVERDUE CR\u00d3NICO", 1, RED)
for item, semanas, resp in overdue_cronicos:
    p = doc.add_paragraph()
    p.paragraph_format.left_indent = Inches(0.4)
    p.paragraph_format.space_before = Pt(2)
    p.paragraph_format.space_after = Pt(2)
    badge = p.add_run(f"[{semanas}] ")
    badge.bold = True
    badge.font.color.rgb = RED
    badge.font.size = Pt(10)
    main = p.add_run(item)
    main.font.size = Pt(10)
    rr = p.add_run(f"  \u2192 {resp}")
    rr.font.color.rgb = ACCENT
    rr.font.size = Pt(9)

add_divider(doc)

# ─── PENDIENTES POR RESPONSABLE ───────────────────────────────────────
add_heading(doc, "\U0001f465  PENDIENTES POR RESPONSABLE", 1, NAVY)
for persona, data in pendientes.items():
    add_heading(doc, f"  {persona} \u2014 {data['rol']}", 2, DARK)
    for tarea, status in data["items"]:
        add_status_item(doc, tarea, status)

add_divider(doc)

# ─── CIERRE ───────────────────────────────────────────────────────────
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
cr = p.add_run(f"Causita \u00b7 Bruna Per\u00fa / VCB S.A.C. \u00b7 Weekly Review {FECHA} \u00b7 Confidencial")
cr.font.size = Pt(8)
cr.font.color.rgb = GRAY

docx_path = f"{OUTPUT_DIR}/Agenda_BrunaPeru_{FECHA_FILE}.docx"
doc.save(docx_path)
print(f"DOCX generado: {docx_path}")

# ─── HTML DASHBOARD ───────────────────────────────────────────────────
def status_badge(st):
    colors = {
        "NO AVANZADO": ("#C0392B", "#fff"),
        "AVANZADO": ("#d4ac0d", "#000"),
        "HECHO": ("#1e8449", "#fff"),
        "VERIFICAR": ("#E67E22", "#fff"),
        "NUEVO": ("#8E44AD", "#fff"),
    }
    bg, fg = colors.get(st, ("#555", "#fff"))
    return f'<span style="background:{bg};color:{fg};padding:2px 7px;border-radius:4px;font-size:11px;font-weight:bold;">{st}</span>'

html = f"""<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bruna Peru Dashboard — {FECHA}</title>
<style>
  body {{ font-family: 'Segoe UI', Arial, sans-serif; background: #f0f2f5; color: #2c3e50; margin: 0; padding: 0; }}
  .header {{ background: linear-gradient(135deg,#1b4f72,#2e86c1); color: #fff; padding: 28px 40px; }}
  .header h1 {{ margin:0; font-size:26px; letter-spacing:1px; }}
  .header p {{ margin:6px 0 0; opacity:0.85; font-size:13px; }}
  .container {{ max-width: 1100px; margin: 0 auto; padding: 24px 20px; }}
  .section {{ background:#fff; border-radius:10px; margin-bottom:22px; box-shadow:0 2px 8px rgba(0,0,0,0.08); overflow:hidden; }}
  .section-header {{ padding:14px 20px; font-weight:700; font-size:15px; border-bottom:1px solid #eaeaea; }}
  .urgent {{ background:#fdf3f2; border-left:5px solid #c0392b; }}
  .urgent .section-header {{ background:#fdf3f2; color:#c0392b; }}
  .intel {{ border-left:5px solid #2e86c1; }}
  .intel .section-header {{ background:#eaf4fb; color:#1b4f72; }}
  .overdue {{ border-left:5px solid #e67e22; }}
  .overdue .section-header {{ background:#fef9f0; color:#e67e22; }}
  .cuentas {{ border-left:5px solid #1b4f72; }}
  .cuentas .section-header {{ background:#eaf0f6; color:#1b4f72; }}
  .resp-section {{ border-left:5px solid #8e44ad; }}
  .resp-section .section-header {{ background:#f5eef8; color:#8e44ad; }}
  .item {{ padding:9px 20px; border-bottom:1px solid #f0f0f0; font-size:13.5px; }}
  .item:last-child {{ border-bottom:none; }}
  .item .label {{ font-weight:600; color:#2e86c1; font-size:11px; margin-right:6px; }}
  .tag {{ font-size:11px; color:#888; margin-left:8px; }}
  .cuenta-row {{ display:flex; justify-content:space-between; align-items:center; padding:10px 20px; border-bottom:1px solid #eee; }}
  .cuenta-name {{ font-weight:600; font-size:13.5px; }}
  .cuenta-tasks {{ font-size:12px; color:#555; margin-top:3px; }}
  .grid2 {{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }}
  @media(max-width:700px){{ .grid2 {{ grid-template-columns:1fr; }} }}
  .resp-person {{ padding:12px 20px; border-bottom:1px solid #f0f0f0; }}
  .resp-person h4 {{ margin:0 0 6px 0; font-size:13px; color:#1b4f72; }}
  .resp-item {{ font-size:12.5px; padding:2px 0 2px 12px; border-left:3px solid #eee; margin:3px 0; }}
  .travel-banner {{ background:#1b4f72; color:#fff; padding:10px 20px; border-radius:8px; margin-bottom:18px; font-size:13px; font-weight:600; }}
  footer {{ text-align:center; padding:16px; font-size:11px; color:#aaa; }}
</style>
</head>
<body>
<div class="header">
  <h1>🇵🇪 BRUNA PERÚ &nbsp;|&nbsp; WEEKLY REVIEW</h1>
  <p>Dashboard Operativo &nbsp;·&nbsp; {FECHA} &nbsp;·&nbsp; Causita Intelligence &nbsp;·&nbsp; Confidencial</p>
</div>
<div class="container">
<div class="travel-banner">⚡ SEMANA 3 POST-VISITA 9-OCT: los 3 compromisos (epóxicas 50% Chemifabrik, TiO2 vs Billions 896, fórmulas Arlanxeo) siguen sin ejecución visible. Hito noviembre en ~5 días hábiles. Señal de mercado: India reimpuso antidumping al TiO2 chino (USD 460–681/ton, 5 años) = más oferta china buscando destino + piso de precios confirmado. Cerrar cotizaciones YA.</div>
"""

# URGENTES
html += '<div class="section urgent"><div class="section-header">🔴 URGENTE ESTA SEMANA (Semana 13)</div>'
for u in urgentes:
    html += f'<div class="item">⚡ {u}</div>'
html += '</div>'

# INTEL
html += '<div class="section intel"><div class="section-header">📬 INTEL DE CORREOS — 20 oct – 26 oct 2026</div>'
for fuente, txt in intel_correos:
    html += f'<div class="item"><span class="label">[{fuente}]</span>{txt}</div>'
html += '</div>'

# CUENTAS
html += '<div class="section cuentas"><div class="section-header">📋 ESTADO DE CUENTAS (12 cuentas)</div>'
for nombre, status, subtareas in cuentas:
    html += f'<div class="cuenta-row"><div><div class="cuenta-name">{nombre}</div>'
    html += f'<div class="cuenta-tasks">' + ' &nbsp;|&nbsp; '.join([t[0][:70]+"…" if len(t[0])>70 else t[0] for t in subtareas[:2]]) + '</div></div>'
    html += f'<div>{status_badge(status)}</div></div>'
html += '</div>'

# OVERDUE
html += '<div class="section overdue"><div class="section-header">⏰ OVERDUE CRÓNICO</div>'
for item, semanas, resp in overdue_cronicos:
    html += f'<div class="item">{status_badge("NO AVANZADO")} <strong>[{semanas}]</strong> {item} <span class="tag">→ {resp}</span></div>'
html += '</div>'

# RESPONSABLES
html += '<div class="section resp-section"><div class="section-header">👥 PENDIENTES POR RESPONSABLE</div><div class="grid2">'
for persona, data in pendientes.items():
    html += f'<div class="resp-person"><h4>{persona} &mdash; {data["rol"]}</h4>'
    for tarea, status in data["items"]:
        html += f'<div class="resp-item">{status_badge(status)} {tarea}</div>'
    html += '</div>'
html += '</div></div>'

html += f'<footer>Causita · Bruna Perú / VCB S.A.C. · Weekly Review {FECHA} · Confidencial</footer>'
html += '</div></body></html>'

html_path = f"{OUTPUT_DIR}/Dashboard_BrunaPeru_{FECHA_FILE}.html"
with open(html_path, "w", encoding="utf-8") as f:
    f.write(html)
print(f"HTML generado: {html_path}")

# Validate
from docx import Document as DocxDoc
d = DocxDoc(docx_path)
print(f"DOCX validation OK | paragrafos: {len(d.paragraphs)}")
print(f"DOCX size: {os.path.getsize(docx_path):,} bytes")
print(f"HTML size: {os.path.getsize(html_path):,} bytes")
