import { createServerFn } from "@tanstack/react-start";
import { requireSupabaseAuth } from "@/integrations/supabase/auth-middleware";

export const listMyEnrollments = createServerFn({ method: "GET" })
  .middleware([requireSupabaseAuth])
  .handler(async ({ context }) => {
    const { supabase, userId } = context;
    const [enrollments, progress] = await Promise.all([
      supabase
        .from("enrollments")
        .select("course_id, created_at, courses(id, slug, title, summary, category_slug, level, lessons)")
        .eq("user_id", userId)
        .order("created_at", { ascending: false }),
      supabase.from("course_progress").select("course_id, lesson_index").eq("user_id", userId),
    ]);
    if (enrollments.error) throw new Error(enrollments.error.message);
    if (progress.error) throw new Error(progress.error.message);

    return (enrollments.data ?? []).map((row) => {
      const course = row.courses;
      const lessonCount = Array.isArray(course?.lessons) ? course.lessons.length : 0;
      const completed = (progress.data ?? []).filter((p) => p.course_id === row.course_id).length;
      return { course, lessonCount, completed };
    });
  });

/** True when the user's plan unlocks courses above Foundation level. */
async function hasProAccess(
  supabase: { from: (t: string) => any },
  userId: string,
): Promise<boolean> {
  const { data } = await supabase
    .from("profiles")
    .select("plan_tier")
    .eq("id", userId)
    .maybeSingle();
  return data?.plan_tier === "pro" || data?.plan_tier === "team";
}

export const getMyCourse = createServerFn({ method: "GET" })
  .middleware([requireSupabaseAuth])
  .inputValidator((data: { slug: string }) => data)
  .handler(async ({ data, context }) => {
    const { supabase, userId } = context;
    const { data: course, error } = await supabase
      .from("courses")
      .select("*")
      .eq("slug", data.slug)
      .maybeSingle();
    if (error) throw new Error(error.message);
    if (!course)
      return { course: null, enrolled: false, completedLessons: [] as number[], locked: false };

    const [enrollment, progress, isPro] = await Promise.all([
      supabase
        .from("enrollments")
        .select("id")
        .eq("user_id", userId)
        .eq("course_id", course.id)
        .maybeSingle(),
      supabase
        .from("course_progress")
        .select("lesson_index")
        .eq("user_id", userId)
        .eq("course_id", course.id),
      hasProAccess(supabase, userId),
    ]);
    if (enrollment.error) throw new Error(enrollment.error.message);
    if (progress.error) throw new Error(progress.error.message);

    const locked = course.credential_level !== "Foundation" && !isPro;

    return {
      course: locked ? { ...course, lessons: [], description: course.summary } : course,
      enrolled: Boolean(enrollment.data),
      completedLessons: (progress.data ?? []).map((p) => p.lesson_index),
      locked,
    };
  });

export const enrollInCourse = createServerFn({ method: "POST" })
  .middleware([requireSupabaseAuth])
  .inputValidator((data: { courseId: string }) => data)
  .handler(async ({ data, context }) => {
    const { supabase, userId } = context;

    const { data: course, error: courseError } = await supabase
      .from("courses")
      .select("id, credential_level")
      .eq("id", data.courseId)
      .maybeSingle();
    if (courseError) throw new Error(courseError.message);
    if (!course) throw new Error("Course not found");

    if (course.credential_level !== "Foundation" && !(await hasProAccess(supabase, userId))) {
      throw new Error("This course is part of the Pro catalogue. Upgrade your plan to enrol.");
    }

    const { error } = await supabase
      .from("enrollments")
      .upsert({ user_id: userId, course_id: data.courseId }, { onConflict: "user_id,course_id" });
    if (error) throw new Error(error.message);
    return { enrolled: true };
  });


export const setLessonComplete = createServerFn({ method: "POST" })
  .middleware([requireSupabaseAuth])
  .inputValidator((data: { courseId: string; lessonIndex: number; complete: boolean }) => data)
  .handler(async ({ data, context }) => {
    const { supabase, userId } = context;
    if (data.complete) {
      const { error } = await supabase.from("course_progress").upsert(
        { user_id: userId, course_id: data.courseId, lesson_index: data.lessonIndex },
        { onConflict: "user_id,course_id,lesson_index" },
      );
      if (error) throw new Error(error.message);
    } else {
      const { error } = await supabase
        .from("course_progress")
        .delete()
        .eq("user_id", userId)
        .eq("course_id", data.courseId)
        .eq("lesson_index", data.lessonIndex);
      if (error) throw new Error(error.message);
    }
    return { ok: true };
  });
