"""Pasos manuales y comandos Windows según el tipo de hallazgo."""
from __future__ import annotations

from typing import Dict, List, Tuple

# Escenarios → pasos numerados con comandos opcionales
MANUAL_GUIDES: Dict[str, List[str]] = {
    "fluidez_lag_wifi": [
        "1. ESCANEAR RED → boton «Fluidez / Lag» (mide ping+jitter y lee bitrate ONVIF).",
        "2. Ordene por score bajo: priorice camaras WiFi con score < 70.",
        "3. En cada camara Dahua WiFi (http://IP): Configurar → Codificacion/Video:",
        "   - Main: H.265 o H.264, CBR 1024–1536 kbps, 1280x720 o 1080p, 10–15 fps, I-frame = FPS",
        "   - Sub: CBR 512–768 kbps, D1/720p, 10–15 fps",
        "3b. O pulse «Caudal 12-16 (aplicar)»: simule y luego aplique CBR en las Dahua (clave temporal).",
        "4. En CADA NVR PNI: vista en vivo = sub-stream; grabacion = main (si no, 8 NVR saturan la red).",
        "5. Tenda: solo SSID CCTV; sin MOVISTAR_EXT; aislamiento clientes OFF; canal 1/6/11 @ 20 MHz.",
        "6. Cudy 3000: modo AP/bridge, DHCP OFF, cable al Askey (un solo DHCP 192.168.1.1).",
        "7. Cable PoE bien / WiFi mal → no es el NVR principal: es WiFi+bitrate+carga multi-NVR.",
        "8. Si 1–2 camaras «desaparecen» a ratos: Fluidez + Monitorizacion 15 min + arp -a (conflicto IP).",
        "9. Tras bajar bitrates: repetir Fluidez / Lag y confirme scores WiFi > 75.",
    ],
    "caudal_12_16": [
        "1. ESCANEAR RED → boton «Caudal 12-16 (aplicar)» (deje SIMULAR la primera vez).",
        "2. Perfil Auto o «Visor IP816 12-16»: Main ~1536 kbps 720p; Extra 512 kbps D1.",
        "3. Si hay muchas WiFi Tenda: perfil «WiFi Tenda» Extra 384 kbps.",
        "4. Usuario/clave = admin de la CAMARA Dahua (no del NVR). No se guarda.",
        "5. Desmarque simular y aplique. CGI Dahua primero; si falla, ONVIF SetVideoEncoder.",
        "6. En CADA visor IP816 HDMI: Extra/Sub en vivo. Sin esto, 16 x Main satura el 100M.",
        "7. Channel Type 16x5MP; grabacion OFF en visores.",
        "8. FAIL en una IP: abra http://IP → Codificacion y ponga a mano los kbps del informe.",
        "9. Fluidez/Lag para comprobar Extra ~384-512 y scores WiFi.",
    ],
    "switch_7_camaras": [
        "1. NO configure nada especial en Movistar (192.168.1.1 DHCP ON).",
        "2. Cudy FS1018PS1: selector VLAN OFF, Extend OFF, Watchdog ON. Espere 1-2 min.",
        "3. PC cable al D-Link → ping -t 192.168.1.126 + ConfigTool. Anote si coinciden.",
        "4. D-Link http://192.168.1.2: solo VLAN 1 Untagged, PVID 1, Asymmetric VLAN Disabled.",
        "5. Port Statistics: puerto→Cudy y puerto→TVT (Rx/Tx Errors, CRC, Drops). No cambie nada.",
        "6. Prueba: desconecte Cudy M300; si aparecen todas rapido → enfoque WiFi/AP.",
        "7. NVR conocidos: .62 Salon1, .64 Salon2, .76 Dormitorio, .57 Escalera — Extra/Sub en vivo.",
        "8. NO active Storm Control / IGMP / Jumbo / VLAN nuevas hasta tener A/B/C claro.",
        "9. Boton app «Switches / 7 cams» para el checklist completo.",
    ],
    "ip816_visores": [
        "1. Marque SOLO el NVR PRINCIPAL (☑) — tipico .62 NVR1 Salon — → «IP816 visores».",
        "2. Visores conocidos: .64 Salon TV2, .76 Dormitorio, .57 Escalera (+ otros si hay).",
        "3. Digital → Channel Type = 16 x 5MP (NO 10 x 8MP si ese TV ve mas de 10 camaras).",
        "4. IP Channel → ONVIF → Buscar + Agregar manual (IP, puerto 80, user/clave Dahua).",
        "5. Encode/Preview: Extra stream / Sub en TODOS los canales (NUNCA Main en visores).",
        "6. Record: Disable. Graba el principal. El IP816 es 10/100 Mbps: Main x16 satura el visor.",
        "6b. Boton «Caudal 12-16»: Extra 384-512 kbps en camaras para que 12-16 quepan en el visor.",
        "7. Channel status en verde. Si lag solo en ese TV: sigue en Main → cambie a Extra.",
        "8. Si solo ven ~7 camaras: primero «Switches / 7 cams» (Cudy VLAN OFF), no el NVR.",
    ],
    "plan_red_perfecta": [
        "1. ESCANEAR → boton «Plan red perfecta» (capacidad + checklist).",
        "2. Askey 192.168.1.1: unico DHCP. Camaras reservadas .40-.70; familia .100-.200.",
        "3. Tenda: AP, DHCP OFF, SSID CCTV 2.4 canal 1/6/11 @ 20 MHz, aislamiento OFF. Sin _EXT.",
        "4. Cudy 3000: AP/mesh, DHCP OFF, cable al Askey. Moviles de la casa al Cudy, no al Tenda.",
        "5. 8 NVR y PoE al switch por CABLE 1 Gbps. Ningun NVR en WiFi.",
        "6. Dahua WiFi: Main CBR 1024-1536 kbps, 15 fps, H.265; Sub 512-768 (boton Caudal 12-16).",
        "7. EN TODOS LOS NVR: visualizacion = sub-stream. MAIN solo grabacion (mejor en 1 NVR principal).",
        "8. Si un TV sigue con lag: ese NVR sigue en main — cambie a sub. No es 'mas router'.",
        "9. Fluidez/Lag hasta scores WiFi >= 75. Conflictos IP si desaparecen 1-2 camaras.",
        "10. Hora punta: monitorizar 20 min. Objetivo: sin OFFLINE en bloque ni jitter alto.",
    ],
    "nvr_informe_checklist": [
        "1. ESCANEAR RED con el PC por cable al mismo switch que el NVR.",
        "2. Marque (☑) el NVR en la tabla o seleccione su fila.",
        "3. Pulse «Informe desde NVR» → lea checklist de IPs a anadir manual.",
        "4. En NVR PNI HDMI: Configuracion -> Canal IP -> ONVIF -> Anadir manual.",
        "5. Para cada IP listada: IP, puerto 80, usuario admin, clave Dahua de la camara.",
        "6. Si la lista dice «ping OK pero no discovery»: arregle WiFi (Tenda, sin _EXT) y anada por IP.",
        "7. Compare el numero «Buscar» del informe con la pantalla del NVR.",
        "8. Exporte el HTML del informe (carpeta reports/) para llevarlo en campo.",
    ],
    "nvr_ve_pocas_camaras": [
        "1. Conecte el portátil por CABLE al MISMO switch que el NVR que ve pocas cámaras.",
        "2. En NVR Net Diag: ESCANEAR RED → botón Topología / Vista NVR.",
        "3. Compare: cámaras por ping (unicast) vs cámaras por WS-Discovery (Buscar).",
        "4. Si ping ve muchas pero discovery pocas: el NVR Buscar fallará igual → añadir por IP fija.",
        "5. Desactive aislamiento de clientes WiFi en Tenda/Askey; un solo SSID para CCTV (sin _EXT).",
        "6. Compruebe que ese NVR no está en otra VLAN/subred (misma 192.168.1.x).",
        "7. En el NVR: Canal IP → añadir manual IP/usuario/clave de las que faltan.",
        "8. Si hay 8 NVR: cada uno puede montar hasta 16 canales; no implica que la red esté partida.",
        "9. Vuelva a Topología tras cambios y compare la vista de ese NVR con otro que sí vea todas.",
    ],
    "conflicto_ip": [
        "1. Abra CMD (no hace falta admin) y ejecute: arp -a",
        "2. Busque la IP conflictiva. Si la misma IP aparece con MAC distinta en distintos momentos → conflicto real.",
        "3. En el router Askey (192.168.1.1): menú LAN / DHCP → Reserva de IP (bind MAC↔IP) para CADA cámara.",
        "4. En el Tenda: modo AP/repetidor con cable al Askey; DESACTIVE DHCP en el Tenda (solo el Askey reparte IP).",
        "5. En cada cámara Dahua (web http://IP-cámara → Red → WiFi): IP estática O deje DHCP pero con reserva en Askey.",
        "6. Apague y enciende las cámaras una a una; vuelva a ejecutar: arp -a | findstr 192.168.1",
        "7. Compruebe que cada IP tiene UNA sola MAC y que no cambia tras 5 minutos.",
        "Comando verificación continua (PowerShell): ping -n 1 192.168.1.44; arp -a | findstr 192.168.1.44",
    ],
    "caida_multiple_wifi": [
        "1. NO use el SSID del repetidor (MOVISTAR-WIFI6-6C08_EXT) para cámaras.",
        "2. Conecte TODAS las cámaras al mismo SSID: Tenda_2724C0 (o un SSID CCTV 2,4 GHz único).",
        "3. En cada cámara Dahua: Red → WiFi → modo Manual (no Auto); SSID fijo; gateway 192.168.1.1.",
        "4. Cable Ethernet del Tenda al Askey (LAN-LAN, no WAN del Tenda).",
        "5. NVR PNI IP816: cable Ethernet al Askey/switch, nunca WiFi.",
        "6. En el Askey: WiFi 2,4 GHz → canal fijo 1, 6 u 11; ancho 20 MHz (no 40/80 para muchas cámaras).",
        "7. Tras el cambio: reinicie cámaras; en NVR → Canal IP → Buscar/ONVIF → volver a añadir.",
        "8. Vuelva a monitorizar 15 min con NVR Net Diag.",
        "Comando test desde PC: ping -t 192.168.1.44  (Ctrl+C para parar; mirar si hay 'timeout')",
    ],
    "dhcp_doble": [
        "1. ipconfig /all  → anote 'Servidor DHCP' y 'Puerta de enlace'.",
        "2. Solo debe haber UN servidor DHCP (normalmente 192.168.1.1 = Askey).",
        "3. Si el Tenda da DHCP: entrar al Tenda → desactivar DHCP → modo AP.",
        "4. Si hay repetidor TP-Link con DHCP accidental: desactivar DHCP en el repetidor.",
        "5. Reinicie cámaras; compruebe que gateway de cada cámara es 192.168.1.1 (web cámara → Red).",
        "Comando: ipconfig /all | findstr /i \"DHCP Gateway\"",
    ],
    "degradado_wifi": [
        "1. En cada cámara Dahua: Configurar → Video → CBR main 1024 kbps, sub 512 kbps, I-frame = FPS.",
        "2. En router/Tenda: fijar canal WiFi 2,4 GHz (1/6/11), ancho 20 MHz.",
        "3. Aleje cámaras del repetidor; acérquelas al AP Tenda si hace falta.",
        "4. Desde CMD: ping -n 50 192.168.1.XX  → mirar % perdidos y latencia máxima.",
        "5. Si pérdida >5%: cambiar canal WiFi o bajar a 720p en main stream.",
        "Comando: ping -n 50 192.168.1.44",
    ],
    "una_camara_offline": [
        "1. ping 192.168.1.XX  → si falla, el problema NO es solo el NVR.",
        "2. Compruebe alimentación 12V de la cámara y LED.",
        "3. En la cámara (si responde a veces): WiFi → SSID Manual al Tenda, no _EXT.",
        "4. arp -a | findstr 192.168.1.XX  → ¿aparece MAC Dahua?",
        "5. Si no aparece en ARP tras ping: cámara desconectada del WiFi o IP distinta.",
        "6. Busque la cámara en el escaneo de la app o en lista de clientes del Askey/Tenda.",
    ],
    "nvr_inalcanzable_ping_ok": [
        "1. Confirme: ping desde PC a la cámara OK mientras el NVR dice 'red inalcanzable'.",
        "2. NVR debe estar en cable al mismo switch/router (misma 192.168.1.x).",
        "3. En el NVR PNI: menú Canal IP → eliminar canal → Buscar ONVIF → añadir de nuevo con IP fija.",
        "4. Credenciales Dahua por defecto suele ser admin + contraseña que configuró (no la de la app).",
        "5. Puerto ONVIF 80; RTSP 554. Desde PC: Test puertos en la app o telnet (si instalado).",
        "6. Reinicie el NVR (último recurso) con cámaras ya estables en red.",
        "7. Compruebe que el NVR no tiene límite de carga (muchas cámaras 5MP WiFi al mismo tiempo).",
        "Comando: ping 192.168.1.44  y comparar con ping al NVR (ip del NVR en la tabla de escaneo).",
    ],
    "monitorizar": [
        "1. En la app: ESCANEAR RED → marcar cámaras (☑) → INICIAR MONITORIZACIÓN.",
        "2. Intervalo 1–2 s; dejar 15–30 min MIENTRAS falla el NVR.",
        "3. EXPORTAR INFORME → abrir HTML en Chrome/Edge.",
        "4. Leer pestaña 'Preguntas clave' y sección 'Pasos manuales' del informe.",
        "5. Aplicar solo los pasos que coincidan con lo detectado (conflicto / múltiple / etc.).",
    ],
    "reserva_ip_askey": [
        "1. Abrir navegador: http://192.168.1.1 (Askey Movistar).",
        "2. Iniciar sesión (credenciales del router).",
        "3. Buscar: LAN, DHCP, 'Reserva de direcciones' o 'Static DHCP' o 'Asignación fija'.",
        "4. Para cada cámara: MAC (de la app o arp -a) + IP deseada (ej. 192.168.1.44).",
        "5. Guardar y reiniciar cámara; verificar con arp -a que la IP y MAC coinciden.",
    ],
    "camara_dahua_wifi": [
        "1. Conectar PC a la misma red; abrir http://192.168.1.XX (IP de la cámara).",
        "2. Configurar → Red → WiFi → Habilitar.",
        "3. Seleccionar SSID (Tenda_2724C0); modo Manual (NO Auto).",
        "4. Contraseña WiFi; Gateway 192.168.1.1; Máscara 255.255.255.0.",
        "5. IP: estática en el rango 192.168.1.41–.60 o DHCP con reserva en router.",
        "6. Guardar; la cámara puede reiniciar. Vuelva a ping y añadir en NVR.",
    ],
    "nvr_pni_canal_ip": [
        "1. Menú del NVR (ratón en pantalla HDMI) → Configuración / Canal IP / Digital.",
        "2. Protocolo: ONVIF.",
        "3. Buscar / Search → deben aparecer cámaras en 192.168.1.x.",
        "4. Si no aparecen: Añadir manual → IP, puerto 80, usuario/contraseña Dahua.",
        "5. Stream: usar sub-stream para vista en vivo si hay lag; main para grabación.",
        "6. Si 'red inalcanzable': borrar canal, ping la IP desde otro PC, volver a añadir.",
    ],
}

# Mapa hallazgo → claves de guía
def guides_for_situation(
    has_conflict: bool,
    multi_drop: bool,
    dhcp_notes: bool,
    degraded: bool,
    single_offline: bool,
    nvr_vs_ping: bool,
) -> List[str]:
    keys: List[str] = []
    if has_conflict:
        keys.append("conflicto_ip")
        keys.append("reserva_ip_askey")
    if multi_drop:
        keys.append("caida_multiple_wifi")
        keys.append("camara_dahua_wifi")
    if dhcp_notes:
        keys.append("dhcp_doble")
    if degraded:
        keys.append("degradado_wifi")
    if single_offline:
        keys.append("una_camara_offline")
    if nvr_vs_ping:
        keys.append("nvr_inalcanzable_ping_ok")
        keys.append("nvr_pni_canal_ip")
    if not keys:
        keys.append("monitorizar")
    return keys


def format_manual_section(
    conflicts: list,
    timeline: list,
    dhcp_notes: List[str],
    devices: list,
) -> str:
    """Texto plano con pasos manuales para informe y GUI."""
    offline = [d for d in devices if getattr(d, "status", "") == "OFFLINE"]
    degraded = [d for d in devices if getattr(d, "status", "") == "DEGRADADO"]
    cams = [d for d in devices if getattr(d, "status", "") in ("ONLINE", "DEGRADADO")]
    offs = [t for t in timeline if getattr(t, "kind", "") == "offline"]
    multi_drop = len({t.ip for t in offs[-10:]}) >= 3
    has_conflict = bool(conflicts)
    nvr_vs_ping = bool(offline and cams)
    single_off = len(offline) == 1 and not multi_drop and not has_conflict

    keys = guides_for_situation(
        has_conflict,
        multi_drop,
        bool(dhcp_notes),
        bool(degraded),
        single_off,
        nvr_vs_ping,
    )
    nvr_count = sum(1 for d in devices if getattr(d, "device_type", "") == "NVR")
    if nvr_count >= 2 or nvr_vs_ping:
        keys.insert(0, "nvr_ve_pocas_camaras")
    cam_count = sum(1 for d in devices if getattr(d, "device_type", "") == "Camara")
    if cam_count >= 8 or any(getattr(d, "status", "") == "DEGRADADO" for d in devices):
        keys.insert(0, "fluidez_lag_wifi")
    if nvr_count >= 2 and cam_count >= 8:
        keys.insert(0, "plan_red_perfecta")
    if nvr_count >= 2:
        keys.insert(0, "ip816_visores")
    if cam_count >= 8:
        keys.insert(0, "caudal_12_16")
    if nvr_count >= 1 or cam_count >= 5:
        keys.insert(0, "switch_7_camaras")

    lines = ["PASOS MANUALES (aplicar según lo detectado)", "=" * 50, ""]
    seen = set()
    for key in keys:
        if key in seen:
            continue
        seen.add(key)
        title = key.replace("_", " ").upper()
        lines.append(f"--- {title} ---")
        for step in MANUAL_GUIDES.get(key, []):
            lines.append(step)
        lines.append("")

    lines.extend(
        [
            "--- COMANDOS ÚTILES WINDOWS (CMD) ---",
            "ipconfig /all          → IP, máscara, gateway, DHCP",
            "arp -a                 → tabla IP ↔ MAC",
            "ping 192.168.1.44      → prueba una cámara",
            "ping -n 50 192.168.1.44→ pérdida % y latencia",
            "ping -t 192.168.1.44   → monitor continuo (Ctrl+C parar)",
            "arp -a | findstr 192.168.1.44  → MAC de esa IP",
            "",
            "La app NVR Net Diag automatiza ping/ARP/monitor; estos comandos sirven para verificar a mano.",
        ]
    )
    return "\n".join(lines)


def manual_for_diagnosis_text(diagnosis_key: str) -> str:
    """Guía por tipo (para botón ayuda en GUI)."""
    if diagnosis_key in MANUAL_GUIDES:
        return "\n".join(MANUAL_GUIDES[diagnosis_key])
    return format_manual_section([], [], [], [])
