import pandas as pd
from datetime import datetime

# === Configuración ===
archivo_excel = "pacientes.xlsx"  # el Excel que vas a subir
archivo_paciente      = "paciente.sql"
archivo_establec      = "establecimiento.sql"
archivo_ingreso       = "ingreso.sql"


def texto_a_sql(valor):
    """Devuelve un literal de texto SQL (o NULL si viene vacío)."""
    if pd.isna(valor):
        return "NULL"
    s = str(valor).strip()
    if s == "" or s.upper() == "NAN":
        return "NULL"
    s = s.replace("'", "''")
    return f"'{s}'"


def fecha_a_sql(valor):
    """Convierte una fecha a 'YYYY-MM-DD' (o NULL)."""
    if pd.isna(valor):
        return "NULL"
    if not isinstance(valor, (pd.Timestamp, datetime)):
        valor = pd.to_datetime(valor, dayfirst=True, errors="coerce")
    if pd.isna(valor):
        return "NULL"
    return f"'{valor.strftime('%Y-%m-%d')}'"


def main():
    df = pd.read_excel(archivo_excel, dtype=str)

    print("Columnas detectadas:", list(df.columns))

    sentencias_pac   = []
    sentencias_estab = []
    sentencias_ing   = []

    vistos_estab    = set()
    vistos_paciente = set()
    vistos_ingreso  = set()

    for i, fila in df.iterrows():
        # ---------- INTERNO ----------
        interno_raw = fila.get("INTERNO", "")
        if interno_raw is None or str(interno_raw).strip() == "":
            print(f"Fila {i}: sin INTERNO, se omite.")
            continue
        interno = str(interno_raw).strip()
        interno_sql = texto_a_sql(interno)

        # ---------- ESTABLECIMIENTO ----------
        cod_est_raw = fila.get("CODIGO_ESTABLECIMIENTO", "")
        cod_est = str(cod_est_raw).strip() if cod_est_raw is not None else ""

        if cod_est != "" and cod_est not in vistos_estab:
            cod_est_sql          = texto_a_sql(cod_est)
            nom_est_sql          = texto_a_sql(fila.get("NOMBRE_ESTABLECIMIENTO"))
            epc_ciudad_sql       = texto_a_sql(fila.get("EPC_CIUDAD"))
            epc_depart_sql       = texto_a_sql(fila.get("EPC_DEPARTAMENTO"))
            regional_sql         = texto_a_sql(fila.get("REGIONAL"))
            regional_norm_sql    = texto_a_sql(fila.get("REGIONAL_NORMALIZADA"))

            sentencia_e = (
                "INSERT INTO establecimiento "
                "(codigo_establecimiento, nombre_establecimiento, "
                "epc_ciudad, epc_departamento, regional, regional_normalizada) "
                f"VALUES ({cod_est_sql}, {nom_est_sql}, "
                f"{epc_ciudad_sql}, {epc_depart_sql}, "
                f"{regional_sql}, {regional_norm_sql}) "
                "ON CONFLICT (codigo_establecimiento) DO UPDATE SET "
                "nombre_establecimiento = EXCLUDED.nombre_establecimiento, "
                "epc_ciudad             = EXCLUDED.epc_ciudad, "
                "epc_departamento       = EXCLUDED.epc_departamento, "
                "regional               = EXCLUDED.regional, "
                "regional_normalizada   = EXCLUDED.regional_normalizada;"
            )
            sentencias_estab.append(sentencia_e)
            vistos_estab.add(cod_est)

        # ---------- PACIENTE ----------
        if interno not in vistos_paciente:
            tipo_doc_sql    = texto_a_sql(fila.get("TIPO_DOCUMENTO"))
            num_doc_sql     = texto_a_sql(fila.get("NUMERO_DOCUMENTO"))
            primer_ape_sql  = texto_a_sql(fila.get("PRIMER_APELLIDO"))
            segundo_ape_sql = texto_a_sql(fila.get("SEGUNDO_APELLIDO"))
            primer_nom_sql  = texto_a_sql(fila.get("PRIMER_NOMBRE"))
            segundo_nom_sql = texto_a_sql(fila.get("SEGUNDO_NOMBRE"))
            sexo_sql        = texto_a_sql(fila.get("SEXO"))
            fecha_nac_sql   = fecha_a_sql(fila.get("FECHA_NACIMIENTO"))

            sentencia_p = (
                "INSERT INTO paciente "
                "(interno, tipo_documento, numero_documento, "
                "primer_apellido, segundo_apellido, primer_nombre, segundo_nombre, "
                "fecha_nacimiento, edad, sexo, activo) "
                f"VALUES ({interno_sql}, {tipo_doc_sql}, {num_doc_sql}, "
                f"{primer_ape_sql}, {segundo_ape_sql}, "
                f"{primer_nom_sql}, {segundo_nom_sql}, "
                f"{fecha_nac_sql}, NULL, {sexo_sql}, true) "
                "ON CONFLICT (interno) DO UPDATE SET "
                "tipo_documento   = EXCLUDED.tipo_documento, "
                "numero_documento = EXCLUDED.numero_documento, "
                "primer_apellido  = EXCLUDED.primer_apellido, "
                "segundo_apellido = EXCLUDED.segundo_apellido, "
                "primer_nombre    = EXCLUDED.primer_nombre, "
                "segundo_nombre   = EXCLUDED.segundo_nombre, "
                "fecha_nacimiento = EXCLUDED.fecha_nacimiento, "
                "sexo             = EXCLUDED.sexo, "
                "activo           = true;"
            )
            sentencias_pac.append(sentencia_p)
            vistos_paciente.add(interno)

        # ---------- INGRESO ----------
        if interno not in vistos_ingreso:
            cod_est_sql_ing = texto_a_sql(cod_est) if cod_est != "" else "NULL"
            estado_sql      = texto_a_sql(fila.get("ESTADO"))
            fecha_ing_sql   = fecha_a_sql(fila.get("FECHA_INGRESO"))
            nac_sql         = texto_a_sql(fila.get("NACIONALIDAD"))

            sentencia_i = (
                "INSERT INTO ingreso "
                "(interno, codigo_establecimiento, estado, fecha_ingreso, nacionalidad) "
                f"VALUES ({interno_sql}, {cod_est_sql_ing}, {estado_sql}, "
                f"{fecha_ing_sql}, {nac_sql}) "
                "ON CONFLICT (interno) DO UPDATE SET "
                "codigo_establecimiento = EXCLUDED.codigo_establecimiento, "
                "estado                 = EXCLUDED.estado, "
                "fecha_ingreso          = EXCLUDED.fecha_ingreso, "
                "nacionalidad           = EXCLUDED.nacionalidad;"
            )
            sentencias_ing.append(sentencia_i)
            vistos_ingreso.add(interno)

    # ---------- Guardar archivos SQL ----------
    with open(archivo_establec, "w", encoding="utf-8") as f_est:
        f_est.write("-- UPSERTS TABLA ESTABLECIMIENTO\n")
        for s in sentencias_estab:
            f_est.write(s + "\n")

    with open(archivo_paciente, "w", encoding="utf-8") as f_pac:
        f_pac.write("-- UPSERTS TABLA PACIENTE\n")
        # Marcamos todos como inactivos, y los del Excel quedarán activos
        f_pac.write("UPDATE paciente SET activo = false;\n")
        for s in sentencias_pac:
            f_pac.write(s + "\n")

    with open(archivo_ingreso, "w", encoding="utf-8") as f_ing:
        f_ing.write("-- UPSERTS TABLA INGRESO\n")
        for s in sentencias_ing:
            f_ing.write(s + "\n")

    print("Archivos generados:")
    print("  ", archivo_establec, f"({len(sentencias_estab)} sentencias)")
    print("  ", archivo_paciente, f"({len(sentencias_pac)} sentencias + UPDATE activo=false)")
    print("  ", archivo_ingreso, f"({len(sentencias_ing)} sentencias)")


if __name__ == "__main__":
    main()
