import { supabaseBrowser } from "../supabase/client"; import { invokeEdge } from "../supabase/invokeEdge"; import { throwIfError, requireData } from "./_helpers"; import type { Asignatura, BibliografiaAsignatura, CambioAsignatura, TipoAsignatura, UUID, } from "../types/domain"; import type { DocumentoResult } from "./plans.api"; const EDGE = { subjects_create_manual: "subjects_create_manual", ai_generate_subject: "ai_generate_subject", subjects_persist_from_ai: "subjects_persist_from_ai", subjects_clone_from_existing: "subjects_clone_from_existing", subjects_import_from_file: "subjects_import_from_file", subjects_update_fields: "subjects_update_fields", subjects_update_contenido: "subjects_update_contenido", subjects_update_bibliografia: "subjects_update_bibliografia", subjects_generate_document: "subjects_generate_document", subjects_get_document: "subjects_get_document", } as const; export async function subjects_get(subjectId: UUID): Promise { const supabase = supabaseBrowser(); const { data, error } = await supabase .from("asignaturas") .select( ` id,plan_estudio_id,estructura_id,facultad_propietaria_id,codigo,nombre,tipo,creditos,horas_semana,numero_ciclo,linea_plan_id,orden_celda,datos,contenido_tematico,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en, planes_estudio( id,carrera_id,estructura_id,nombre,nivel,tipo_ciclo,numero_ciclos,datos,estado_actual_id,activo,tipo_origen,meta_origen,creado_por,actualizado_por,creado_en,actualizado_en, carreras(id,facultad_id,nombre,nombre_corto,clave_sep,activa, facultades(id,nombre,nombre_corto,color,icono)) ), estructuras_asignatura(id,nombre,version,definicion) ` ) .eq("id", subjectId) .single(); throwIfError(error); return requireData(data, "Materia no encontrada."); } export async function subjects_history(subjectId: UUID): Promise { const supabase = supabaseBrowser(); const { data, error } = await supabase .from("cambios_asignatura") .select( "id,asignatura_id,cambiado_por,cambiado_en,tipo,campo,valor_anterior,valor_nuevo,fuente,interaccion_ia_id" ) .eq("asignatura_id", subjectId) .order("cambiado_en", { ascending: false }); throwIfError(error); return data ?? []; } export async function subjects_bibliografia_list(subjectId: UUID): Promise { const supabase = supabaseBrowser(); const { data, error } = await supabase .from("bibliografia_asignatura") .select("id,asignatura_id,tipo,cita,tipo_fuente,biblioteca_item_id,creado_por,creado_en,actualizado_en") .eq("asignatura_id", subjectId) .order("tipo", { ascending: true }) .order("creado_en", { ascending: true }); throwIfError(error); return data ?? []; } /** Wizard: crear materia manual (Edge Function) */ export type SubjectsCreateManualInput = { planId: UUID; datosBasicos: { nombre: string; clave?: string; tipo: TipoAsignatura; creditos: number; horasSemana?: number; estructuraId: UUID; }; }; export async function subjects_create_manual(payload: SubjectsCreateManualInput): Promise { return invokeEdge(EDGE.subjects_create_manual, payload); } export async function ai_generate_subject(payload: { planId: UUID; datosBasicos: { nombre: string; clave?: string; tipo: TipoAsignatura; creditos: number; horasSemana?: number; estructuraId: UUID; }; iaConfig: { descripcionEnfoque: string; notasAdicionales?: string; archivosExistentesIds?: UUID[]; repositoriosIds?: UUID[]; archivosAdhocIds?: UUID[]; usarMCP?: boolean; }; }): Promise { return invokeEdge(EDGE.ai_generate_subject, payload); } export async function subjects_persist_from_ai(payload: { planId: UUID; jsonMateria: any }): Promise { return invokeEdge(EDGE.subjects_persist_from_ai, payload); } export async function subjects_clone_from_existing(payload: { materiaOrigenId: UUID; planDestinoId: UUID; overrides?: Partial<{ nombre: string; codigo: string; tipo: TipoAsignatura; creditos: number; horas_semana: number; }>; }): Promise { return invokeEdge(EDGE.subjects_clone_from_existing, payload); } export async function subjects_import_from_file(payload: { planId: UUID; archivoWordMateriaId: UUID; archivosAdicionalesIds?: UUID[]; }): Promise { return invokeEdge(EDGE.subjects_import_from_file, payload); } /** Guardado de tarjetas/fields (Edge: merge server-side en asignaturas.datos y columnas) */ export type SubjectsUpdateFieldsPatch = Partial<{ codigo: string | null; nombre: string; tipo: TipoAsignatura; creditos: number; horas_semana: number | null; numero_ciclo: number | null; linea_plan_id: UUID | null; datos: Record; }>; export async function subjects_update_fields(subjectId: UUID, patch: SubjectsUpdateFieldsPatch): Promise { return invokeEdge(EDGE.subjects_update_fields, { subjectId, patch }); } export async function subjects_update_contenido(subjectId: UUID, unidades: any[]): Promise { return invokeEdge(EDGE.subjects_update_contenido, { subjectId, unidades }); } export type BibliografiaUpsertInput = Array<{ id?: UUID; tipo: "BASICA" | "COMPLEMENTARIA"; cita: string; tipo_fuente?: "MANUAL" | "BIBLIOTECA"; biblioteca_item_id?: string | null; }>; export async function subjects_update_bibliografia( subjectId: UUID, entries: BibliografiaUpsertInput ): Promise<{ ok: true }> { return invokeEdge<{ ok: true }>(EDGE.subjects_update_bibliografia, { subjectId, entries }); } /** Documento SEP materia */ /* export type DocumentoResult = { archivoId: UUID; signedUrl: string; mimeType?: string; nombre?: string; }; */ export async function subjects_generate_document(subjectId: UUID): Promise { return invokeEdge(EDGE.subjects_generate_document, { subjectId }); } export async function subjects_get_document(subjectId: UUID): Promise { return invokeEdge(EDGE.subjects_get_document, { subjectId }); }