from sqlalchemy import text


def customization_state(db, matter_id: int, entity_id: int | None) -> dict:
    if not entity_id:
        return {"entidad_id": None, "requisitos_personalizados": False,
                "campos_plantilla_personalizados": False}
    row = db.execute(text("""
      SELECT requisitos_personalizados,campos_plantilla_personalizados
      FROM configuraciones_servicio_entidad
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"matter": matter_id, "entity": entity_id}).mappings().first()
    return {"entidad_id": entity_id,
            "requisitos_personalizados": bool(row and row["requisitos_personalizados"]),
            "campos_plantilla_personalizados": bool(row and row["campos_plantilla_personalizados"])}


def _ensure_state(db, matter_id: int, entity_id: int, user_id: int) -> None:
    db.execute(text("""
      INSERT INTO configuraciones_servicio_entidad
        (notaria_id,materia_id,actualizado_por)
      VALUES (:entity,:matter,:user)
      ON DUPLICATE KEY UPDATE actualizado_por=VALUES(actualizado_por)
    """), {"entity": entity_id, "matter": matter_id, "user": user_id})


def ensure_requirements_customized(db, matter_id: int, entity_id: int, user_id: int) -> None:
    _ensure_state(db, matter_id, entity_id, user_id)
    state = customization_state(db, matter_id, entity_id)
    if state["requisitos_personalizados"]:
        return
    db.execute(text("""
      UPDATE requisitos_documentos SET activo=FALSE
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"matter": matter_id, "entity": entity_id})
    db.execute(text("""
      INSERT INTO requisitos_documentos
        (materia_id,notaria_id,tipo_requisito_id,codigo,nombre,descripcion,requerido,
         cantidad_maxima,mime_permitidos,tamano_maximo_bytes,orden,activo)
      SELECT materia_id,:entity,tipo_requisito_id,codigo,nombre,descripcion,requerido,
             cantidad_maxima,mime_permitidos,tamano_maximo_bytes,orden,activo
      FROM requisitos_documentos
      WHERE materia_id=:matter AND notaria_id IS NULL
      ON DUPLICATE KEY UPDATE tipo_requisito_id=VALUES(tipo_requisito_id),
        nombre=VALUES(nombre),descripcion=VALUES(descripcion),requerido=VALUES(requerido),
        cantidad_maxima=VALUES(cantidad_maxima),mime_permitidos=VALUES(mime_permitidos),
        tamano_maximo_bytes=VALUES(tamano_maximo_bytes),orden=VALUES(orden),activo=VALUES(activo)
    """), {"entity": entity_id, "matter": matter_id})
    db.execute(text("""
      UPDATE configuraciones_servicio_entidad
      SET requisitos_personalizados=TRUE,actualizado_por=:user
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"user": user_id, "matter": matter_id, "entity": entity_id})


def ensure_fields_template_customized(db, matter_id: int, entity_id: int, user_id: int) -> None:
    _ensure_state(db, matter_id, entity_id, user_id)
    state = customization_state(db, matter_id, entity_id)
    if state["campos_plantilla_personalizados"]:
        return
    db.execute(text("""
      UPDATE campos_materias SET activo=FALSE
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"matter": matter_id, "entity": entity_id})
    db.execute(text("""
      INSERT INTO campos_materias
        (materia_id,notaria_id,tipo_de_dato_id,codigo,etiqueta,ayuda,placeholder,requerido,
         aplica_a,orden,largo_minimo,largo_maximo,valor_minimo,valor_maximo,patron_regex,
         opciones_json,activo)
      SELECT materia_id,:entity,tipo_de_dato_id,codigo,etiqueta,ayuda,placeholder,requerido,
             aplica_a,orden,largo_minimo,largo_maximo,valor_minimo,valor_maximo,patron_regex,
             opciones_json,activo
      FROM campos_materias
      WHERE materia_id=:matter AND notaria_id IS NULL
      ON DUPLICATE KEY UPDATE tipo_de_dato_id=VALUES(tipo_de_dato_id),etiqueta=VALUES(etiqueta),
        ayuda=VALUES(ayuda),placeholder=VALUES(placeholder),requerido=VALUES(requerido),
        aplica_a=VALUES(aplica_a),orden=VALUES(orden),largo_minimo=VALUES(largo_minimo),
        largo_maximo=VALUES(largo_maximo),valor_minimo=VALUES(valor_minimo),
        valor_maximo=VALUES(valor_maximo),patron_regex=VALUES(patron_regex),
        opciones_json=VALUES(opciones_json),activo=VALUES(activo)
    """), {"entity": entity_id, "matter": matter_id})
    template = db.execute(text("""
      SELECT nombre,contenido FROM plantillas_materias
      WHERE materia_id=:matter AND notaria_id IS NULL AND activa=TRUE
      ORDER BY version DESC LIMIT 1
    """), {"matter": matter_id}).mappings().first()
    if template:
        version = db.execute(text("""
          SELECT COALESCE(MAX(version),0)+1 FROM plantillas_materias
          WHERE materia_id=:matter AND notaria_id=:entity
        """), {"matter": matter_id, "entity": entity_id}).scalar_one()
        db.execute(text("""
          UPDATE plantillas_materias SET activa=FALSE
          WHERE materia_id=:matter AND notaria_id=:entity AND activa=TRUE
        """), {"matter": matter_id, "entity": entity_id})
        db.execute(text("""
          INSERT INTO plantillas_materias(materia_id,notaria_id,nombre,contenido,version,activa)
          VALUES (:matter,:entity,:name,:content,:version,TRUE)
        """), {"matter": matter_id, "entity": entity_id, "name": template["nombre"],
                  "content": template["contenido"], "version": version})
    db.execute(text("""
      UPDATE configuraciones_servicio_entidad
      SET campos_plantilla_personalizados=TRUE,actualizado_por=:user
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"user": user_id, "matter": matter_id, "entity": entity_id})


def reset_customization(db, matter_id: int, entity_id: int, section: str, user_id: int) -> None:
    _ensure_state(db, matter_id, entity_id, user_id)
    column = "requisitos_personalizados" if section == "requirements" else "campos_plantilla_personalizados"
    db.execute(text(f"""
      UPDATE configuraciones_servicio_entidad
      SET {column}=FALSE,actualizado_por=:user
      WHERE materia_id=:matter AND notaria_id=:entity
    """), {"user": user_id, "matter": matter_id, "entity": entity_id})


def effective_entity_id(db, matter_id: int, entity_id: int | None, section: str) -> int | None:
    if not entity_id:
        return None
    state = customization_state(db, matter_id, entity_id)
    key = "requisitos_personalizados" if section == "requirements" else "campos_plantilla_personalizados"
    return entity_id if state[key] else None
