"""
Genera cronograma.xlsx — Cronograma de Ejecución del Proyecto
Laboratorio Ximena / WhatsApp Bot Manager
Inicio: 2 de marzo de 2026
"""
from datetime import date, timedelta
from openpyxl import Workbook
from openpyxl.styles import (PatternFill, Font, Alignment, Border, Side,
                              GradientFill)
from openpyxl.utils import get_column_letter

# ─── CONFIGURACIÓN DEL PROYECTO ─────────────────────────────────────────────

INICIO = date(2026, 3, 2)

FASES = [
    # (fase, tarea, inicio_offset_dias, duracion_dias, estado)
    # Estado: 'done' | 'active' | 'pending'
    ("Fase 1 – Sistema de Roles", "Diseño BD (roles, modules)",              0,  4, "done"),
    ("Fase 1 – Sistema de Roles", "APIs roles y usuarios",                   4,  4, "done"),
    ("Fase 1 – Sistema de Roles", "UI lab_usuarios.php",                     6,  4, "done"),
    ("Fase 1 – Sistema de Roles", "Unificación panel admin",                 8,  3, "done"),

    ("Fase 2 – Portal Enfermero", "Corrección login enfermero",              11, 2, "done"),
    ("Fase 2 – Portal Enfermero", "Fix SyntaxError botón formulario",        11, 2, "done"),
    ("Fase 2 – Portal Enfermero", "Submit idempotente (ya completado)",       13, 2, "done"),
    ("Fase 2 – Portal Enfermero", "Firma digital — canvas",                  15, 3, "done"),
    ("Fase 2 – Portal Enfermero", "Firma por foto (opcional)",               18, 2, "active"),

    ("Fase 3 – Formularios Avanz.", "Campos dinámicos tipo fecha/selector",  21, 4, "pending"),
    ("Fase 3 – Formularios Avanz.", "Historial de envíos por paciente",      25, 3, "pending"),
    ("Fase 3 – Formularios Avanz.", "Descarga PDF de formulario enviado",    25, 4, "pending"),

    ("Fase 4 – Agendamiento",      "Calendario de domicilios",              32, 5, "pending"),
    ("Fase 4 – Agendamiento",      "Mensajes programados WhatsApp",         36, 4, "pending"),
    ("Fase 4 – Agendamiento",      "Recordatorios automáticos",             38, 3, "pending"),

    ("Fase 5 – Reportes",          "Dashboard métricas laboratorio",        44, 4, "pending"),
    ("Fase 5 – Reportes",          "Exportación Excel / CSV",               46, 3, "pending"),
    ("Fase 5 – Reportes",          "Reportes por enfermera",                48, 3, "pending"),

    ("Fase 6 – QA y Despliegue",   "Pruebas integrales",                    53, 4, "pending"),
    ("Fase 6 – QA y Despliegue",   "Corrección de bugs",                    55, 3, "pending"),
    ("Fase 6 – QA y Despliegue",   "Despliegue en producción",              58, 3, "pending"),
    ("Fase 6 – QA y Despliegue",   "Capacitación y entrega",                60, 2, "pending"),
]

# ─── COLORES ────────────────────────────────────────────────────────────────

COLORES_FASE = {
    "Fase 1 – Sistema de Roles":   {"header": "1565C0", "barra_done":  "42A5F5", "barra_active": "1E88E5", "barra_pending": "90CAF9"},
    "Fase 2 – Portal Enfermero":   {"header": "2E7D32", "barra_done":  "66BB6A", "barra_active": "43A047", "barra_pending": "A5D6A7"},
    "Fase 3 – Formularios Avanz.": {"header": "6A1B9A", "barra_done":  "AB47BC", "barra_active": "8E24AA", "barra_pending": "CE93D8"},
    "Fase 4 – Agendamiento":       {"header": "E65100", "barra_done":  "FFA726", "barra_active": "FB8C00", "barra_pending": "FFCC80"},
    "Fase 5 – Reportes":           {"header": "00695C", "barra_done":  "26A69A", "barra_active": "00897B", "barra_pending": "80CBC4"},
    "Fase 6 – QA y Despliegue":    {"header": "B71C1C", "barra_done":  "EF5350", "barra_active": "E53935", "barra_pending": "EF9A9A"},
}

ESTADO_LABEL = {"done": "✅ Completado", "active": "🔄 En curso", "pending": "⏳ Pendiente"}
ESTADO_FILL  = {
    "done":    "D0F0C0",
    "active":  "FFF9C4",
    "pending": "F5F5F5",
}

# ─── HELPERS ────────────────────────────────────────────────────────────────

def fecha(offset): return INICIO + timedelta(days=offset)
def col_for_date(d, week_cols_start, all_weeks):
    """Devuelve columna Excel (1-based) para una fecha dada."""
    for i, w in enumerate(all_weeks):
        if w <= d < w + timedelta(days=7):
            return week_cols_start + i
    return None

def thin():
    s = Side(style='thin', color='CCCCCC')
    return Border(left=s, right=s, top=s, bottom=s)

def fill(hex_color):
    return PatternFill("solid", fgColor=hex_color)

# ─── GENERAR SEMANAS ────────────────────────────────────────────────────────

max_offset = max(t[3] + t[2] for t in FASES)
num_weeks  = (max_offset // 7) + 2
all_weeks  = [INICIO + timedelta(weeks=i) for i in range(num_weeks)]

# ─── WORKBOOK ───────────────────────────────────────────────────────────────

wb = Workbook()

# ════════════════════════════════════════════════════════════════════════════
# HOJA 1 — GANTT
# ════════════════════════════════════════════════════════════════════════════
ws = wb.active
ws.title = "Gantt"

TASK_COLS    = 4   # Fase | Tarea | Inicio | Estado
WEEK_COL_START = TASK_COLS + 1  # columna Excel donde empiezan las semanas

# ── Dimensiones ─────────────────────────────────────────────────────────────
ws.column_dimensions['A'].width = 26
ws.column_dimensions['B'].width = 38
ws.column_dimensions['C'].width = 13
ws.column_dimensions['D'].width = 16

for i in range(num_weeks):
    cl = get_column_letter(WEEK_COL_START + i)
    ws.column_dimensions[cl].width = 5.5

# ── Fila 1 — Título ─────────────────────────────────────────────────────────
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=WEEK_COL_START + num_weeks - 1)
ws['A1'] = "CRONOGRAMA DE EJECUCIÓN — Laboratorio Ximena"
ws['A1'].font      = Font(bold=True, size=14, color="FFFFFF")
ws['A1'].fill      = fill("0D47A1")
ws['A1'].alignment = Alignment(horizontal="center", vertical="center")
ws.row_dimensions[1].height = 28

# ── Fila 2 — Sub-título ─────────────────────────────────────────────────────
ws.merge_cells(start_row=2, start_column=1, end_row=2, end_column=WEEK_COL_START + num_weeks - 1)
ws['A2'] = f"Inicio: {INICIO.strftime('%d de %B de %Y')}   |   Total estimado: {num_weeks} semanas"
ws['A2'].font      = Font(italic=True, size=10, color="444444")
ws['A2'].fill      = fill("E3F2FD")
ws['A2'].alignment = Alignment(horizontal="center", vertical="center")
ws.row_dimensions[2].height = 18

# ── Fila 3 — Encabezados columnas texto ─────────────────────────────────────
heads = ["Fase", "Tarea", "Inicio", "Estado"]
for c, h in enumerate(heads, 1):
    cell = ws.cell(row=3, column=c, value=h)
    cell.font      = Font(bold=True, size=10, color="FFFFFF")
    cell.fill      = fill("37474F")
    cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
    cell.border    = thin()

# ── Fila 3 — Encabezados semanas ────────────────────────────────────────────
for i, w in enumerate(all_weeks):
    col  = WEEK_COL_START + i
    cell = ws.cell(row=3, column=col, value=w.strftime("%-d/%m"))
    cell.font      = Font(bold=True, size=8, color="FFFFFF")
    cell.fill      = fill("546E7A")
    cell.alignment = Alignment(horizontal="center", vertical="center", text_rotation=60)
    cell.border    = thin()
ws.row_dimensions[3].height = 44

# ── Filas de datos ───────────────────────────────────────────────────────────
ROW = 4
prev_fase = None

for (fase, tarea, start_off, dur, estado) in FASES:
    colores = COLORES_FASE[fase]

    # Separador de fase (cuando cambia)
    if fase != prev_fase:
        ws.merge_cells(start_row=ROW, start_column=1,
                       end_row=ROW, end_column=WEEK_COL_START + num_weeks - 1)
        cell = ws.cell(row=ROW, column=1, value=f"  {fase}")
        cell.font      = Font(bold=True, size=10, color="FFFFFF")
        cell.fill      = fill(colores["header"])
        cell.alignment = Alignment(vertical="center")
        cell.border    = thin()
        ws.row_dimensions[ROW].height = 20
        ROW += 1
        prev_fase = fase

    # Calcular fechas
    d_ini  = fecha(start_off)
    d_fin  = fecha(start_off + dur - 1)
    row_fill = fill(ESTADO_FILL[estado])

    # Columna A — Fase (vacía, ya fue el encabezado)
    c_fase = ws.cell(row=ROW, column=1, value="")
    c_fase.fill   = row_fill
    c_fase.border = thin()

    # Columna B — Tarea
    c_task = ws.cell(row=ROW, column=2, value=tarea)
    c_task.font      = Font(size=9)
    c_task.fill      = row_fill
    c_task.alignment = Alignment(vertical="center", wrap_text=True)
    c_task.border    = thin()

    # Columna C — Fecha inicio
    c_date = ws.cell(row=ROW, column=3, value=d_ini.strftime("%-d %b"))
    c_date.font      = Font(size=9)
    c_date.fill      = row_fill
    c_date.alignment = Alignment(horizontal="center", vertical="center")
    c_date.border    = thin()

    # Columna D — Estado
    c_est = ws.cell(row=ROW, column=4, value=ESTADO_LABEL[estado])
    c_est.font      = Font(size=9, bold=(estado == "active"))
    c_est.fill      = row_fill
    c_est.alignment = Alignment(horizontal="center", vertical="center")
    c_est.border    = thin()

    # Barras de Gantt
    barra_color = colores[f"barra_{estado}"]
    w_ini = col_for_date(d_ini, WEEK_COL_START, all_weeks)
    w_fin = col_for_date(d_fin, WEEK_COL_START, all_weeks)
    if w_ini is None: w_ini = WEEK_COL_START
    if w_fin is None: w_fin = WEEK_COL_START + num_weeks - 1

    for col in range(WEEK_COL_START, WEEK_COL_START + num_weeks):
        cell = ws.cell(row=ROW, column=col, value="")
        if w_ini <= col <= w_fin:
            cell.fill = fill(barra_color)
        else:
            cell.fill = fill("F5F5F5")
        cell.border = thin()

    ws.row_dimensions[ROW].height = 18
    ROW += 1

# ── Leyenda ──────────────────────────────────────────────────────────────────
ROW += 1
leyenda = [
    ("✅ Completado", "D0F0C0"),
    ("🔄 En curso",   "FFF9C4"),
    ("⏳ Pendiente",  "F5F5F5"),
]
ws.cell(row=ROW, column=1, value="Leyenda:").font = Font(bold=True, size=10)
for i, (txt, color) in enumerate(leyenda, 2):
    cell = ws.cell(row=ROW, column=i, value=txt)
    cell.fill   = fill(color)
    cell.border = thin()
    cell.font   = Font(size=9)
    cell.alignment = Alignment(horizontal="center")

# Freeze panes
ws.freeze_panes = "E4"

# ════════════════════════════════════════════════════════════════════════════
# HOJA 2 — RESUMEN POR FASE
# ════════════════════════════════════════════════════════════════════════════
ws2 = wb.create_sheet("Resumen por Fase")
ws2.column_dimensions['A'].width = 30
ws2.column_dimensions['B'].width = 14
ws2.column_dimensions['C'].width = 14
ws2.column_dimensions['D'].width = 14
ws2.column_dimensions['E'].width = 16
ws2.column_dimensions['F'].width = 16

# Título
ws2.merge_cells("A1:F1")
ws2['A1'] = "RESUMEN POR FASE"
ws2['A1'].font      = Font(bold=True, size=13, color="FFFFFF")
ws2['A1'].fill      = fill("0D47A1")
ws2['A1'].alignment = Alignment(horizontal="center", vertical="center")
ws2.row_dimensions[1].height = 26

# Encabezados
enc2 = ["Fase", "Inicio", "Fin", "Duración (días)", "Tareas", "Estado"]
for c, h in enumerate(enc2, 1):
    cell = ws2.cell(row=2, column=c, value=h)
    cell.font      = Font(bold=True, size=10, color="FFFFFF")
    cell.fill      = fill("37474F")
    cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
    cell.border    = thin()
ws2.row_dimensions[2].height = 22

# Agrupar por fase
from collections import defaultdict
fases_data = defaultdict(list)
for row in FASES:
    fases_data[row[0]].append(row)

ROW2 = 3
for fase_name, tareas in fases_data.items():
    ini_fase  = fecha(min(t[2] for t in tareas))
    fin_fase  = fecha(max(t[2] + t[3] - 1 for t in tareas))
    dur_total = (fin_fase - ini_fase).days + 1
    n_tareas  = len(tareas)
    estados   = [t[4] for t in tareas]
    if all(e == "done" for e in estados):
        estado_fase = "✅ Completada"
        fc = "D0F0C0"
    elif any(e == "active" for e in estados):
        estado_fase = "🔄 En curso"
        fc = "FFF9C4"
    else:
        estado_fase = "⏳ Pendiente"
        fc = "F5F5F5"

    colores = COLORES_FASE[fase_name]
    fondo   = fill(colores["header"] if estado_fase == "✅ Completada" else fc)

    data = [fase_name, ini_fase.strftime("%-d %b %Y"), fin_fase.strftime("%-d %b %Y"),
            dur_total, n_tareas, estado_fase]
    for c, v in enumerate(data, 1):
        cell = ws2.cell(row=ROW2, column=c, value=v)
        cell.alignment = Alignment(horizontal="center" if c > 1 else "left",
                                   vertical="center", wrap_text=True)
        cell.border = thin()
        cell.font   = Font(size=10, bold=(c == 1),
                           color=("FFFFFF" if estado_fase == "✅ Completada" else "222222"))
        cell.fill   = PatternFill("solid", fgColor=colores["header"]) if estado_fase == "✅ Completada" \
                      else fill(fc)
    ws2.row_dimensions[ROW2].height = 22
    ROW2 += 1

# ════════════════════════════════════════════════════════════════════════════
# HOJA 3 — DETALLE DE TAREAS
# ════════════════════════════════════════════════════════════════════════════
ws3 = wb.create_sheet("Detalle Tareas")
ws3.column_dimensions['A'].width = 28
ws3.column_dimensions['B'].width = 40
ws3.column_dimensions['C'].width = 14
ws3.column_dimensions['D'].width = 14
ws3.column_dimensions['E'].width = 12
ws3.column_dimensions['F'].width = 16

ws3.merge_cells("A1:F1")
ws3['A1'] = "DETALLE DE TAREAS"
ws3['A1'].font      = Font(bold=True, size=13, color="FFFFFF")
ws3['A1'].fill      = fill("0D47A1")
ws3['A1'].alignment = Alignment(horizontal="center", vertical="center")
ws3.row_dimensions[1].height = 26

enc3 = ["Fase", "Tarea", "Inicio", "Fin", "Días", "Estado"]
for c, h in enumerate(enc3, 1):
    cell = ws3.cell(row=2, column=c, value=h)
    cell.font      = Font(bold=True, size=10, color="FFFFFF")
    cell.fill      = fill("37474F")
    cell.alignment = Alignment(horizontal="center", vertical="center")
    cell.border    = thin()
ws3.row_dimensions[2].height = 22

ROW3 = 3
for (fase, tarea, start_off, dur, estado) in FASES:
    d_ini = fecha(start_off)
    d_fin = fecha(start_off + dur - 1)
    colores = COLORES_FASE[fase]
    fc = ESTADO_FILL[estado]

    data = [fase, tarea, d_ini.strftime("%-d %b %Y"), d_fin.strftime("%-d %b %Y"),
            dur, ESTADO_LABEL[estado]]
    for c, v in enumerate(data, 1):
        cell = ws3.cell(row=ROW3, column=c, value=v)
        cell.alignment = Alignment(horizontal="center" if c > 2 else "left",
                                   vertical="center", wrap_text=True)
        cell.border = thin()
        cell.font   = Font(size=9)
        cell.fill   = fill(fc)
    ws3.row_dimensions[ROW3].height = 18
    ROW3 += 1

# ─── GUARDAR ─────────────────────────────────────────────────────────────────
out = "/Users/lizandro/Documents/GitHub/whatsapp/cronograma.xlsx"
wb.save(out)
print(f"✅  Archivo generado: {out}")
