import { api } from "@/lib/api-client";
import { asPaginated, asRecordData } from "@/lib/odoo-api";
import type { User } from "@/types/auth";
import type {
  Course,
  Batch,
  TimetableSession,
  AttendanceRecord,
  GradeRecord,
  CourseCreateRequest,
  PaginatedResponse,
  PaginationParams,
  ApiSuccessResponse,
  LmsStudentRecord,
  LmsTeacherRecord,
  LmsStudentCreateRequest,
  LmsTeacherCreateRequest,
} from "@/types";

function mapCourseRaw(r: Record<string, unknown>): Course {
  const status = (r.status as Course["status"]) || "draft";
  const enrolled = Number(r.student_count ?? 0);
  const maxCap = Number(r.max_capacity ?? 0);
  return {
    id: r.id as number,
    title: (r.title as string) || (r.name as string) || "",
    code: (r.code as string) || "",
    subject_id: Array.isArray(r.subject_ids) && (r.subject_ids as number[]).length ? (r.subject_ids as number[])[0] : undefined,
    subject_name: Array.isArray(r.subject_names) ? String((r.subject_names as string[])[0] || "") : "",
    instructor_id: 0,
    instructor_name: "",
    description: (r.description as string) || "",
    level: "Beginner",
    modules: [],
    enrolled,
    max_capacity: maxCap,
    status,
    start_date: "",
    end_date: "",
  };
}

function mapBatchRaw(r: Record<string, unknown>): Batch {
  const st = String(r.status || "draft");
  const statusMap: Record<string, Batch["status"]> = {
    draft: "upcoming",
    active: "active",
    completed: "completed",
  };
  return {
    id: r.id as number,
    name: String(r.name || ""),
    course_id: Number(r.course_id || 0),
    course_name: String(r.course_name || ""),
    teacher_id: 0,
    teacher_name: "",
    student_ids: [],
    student_count: 0,
    start_date: String(r.start_date || ""),
    end_date: String(r.end_date || ""),
    schedule: "",
    status: statusMap[st] || "upcoming",
    capacity: Number(r.max_students ?? 0),
  };
}

/** Map OpenEduCat student for screens that still expect `User` (admin tables). */
export function lmsStudentToUser(s: LmsStudentRecord): User {
  const active = s.status === "active";
  return {
    id: s.id,
    name: s.name,
    email: s.email || "",
    login: s.email || "",
    user_type: "student",
    phone: s.phone || undefined,
    gender: s.gender || undefined,
    student_id: String(s.id),
    is_verified: active,
    entities:
      s.batch_id != null
        ? [{ id: s.batch_id, name: s.batch_name || "Batch" }]
        : [],
    classrooms: [],
  };
}

export function lmsTeacherToUser(t: LmsTeacherRecord): User {
  return {
    id: t.id,
    name: t.name,
    email: t.email || "",
    login: t.email || "",
    user_type: "teacher",
    phone: t.phone || undefined,
    gender: t.gender || undefined,
    is_verified: true,
    entities: t.department_id ? [{ id: t.department_id, name: t.department_name || "Department" }] : [],
    classrooms: [],
  };
}

export const lmsService = {
  async listCourses(params?: PaginationParams & { status?: string }): Promise<PaginatedResponse<Course>> {
    const raw = await api.get<unknown>("/courses", params as Record<string, string | number | boolean | undefined>);
    const p = asPaginated<Record<string, unknown>>(raw);
    return { ...p, items: p.items.map(mapCourseRaw) };
  },

  async getCourse(id: number): Promise<Course> {
    const raw = await api.get<unknown>(`/courses/${id}`);
    return mapCourseRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async createCourse(data: CourseCreateRequest): Promise<Course> {
    const raw = await api.post<unknown>("/courses", {
      name: data.title,
      code: data.code,
      description: data.description,
      max_capacity: data.max_capacity,
      status: "draft",
    });
    return mapCourseRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async updateCourse(id: number, data: Partial<CourseCreateRequest>): Promise<Course> {
    const body: Record<string, unknown> = {};
    if (data.title != null) body.name = data.title;
    if (data.code != null) body.code = data.code;
    if (data.description != null) body.description = data.description;
    if (data.max_capacity != null) body.max_capacity = data.max_capacity;
    const raw = await api.patch<unknown>(`/courses/${id}`, body);
    return mapCourseRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async deleteCourse(id: number): Promise<ApiSuccessResponse> {
    return api.delete<ApiSuccessResponse>(`/courses/${id}`);
  },

  async aiGenerateCourse(data: { title: string; subject_id?: number; level?: string }): Promise<{ outline: unknown }> {
    return api.post("/courses/ai-generate", data);
  },

  async listBatches(params?: PaginationParams): Promise<PaginatedResponse<Batch>> {
    const raw = await api.get<unknown>("/batches", params as Record<string, string | number | boolean | undefined>);
    const p = asPaginated<Record<string, unknown>>(raw);
    return { ...p, items: p.items.map(mapBatchRaw) };
  },

  async getBatch(id: number): Promise<Batch> {
    const raw = await api.get<unknown>(`/batches/${id}`);
    return mapBatchRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async createBatch(data: Partial<Batch>): Promise<Batch> {
    const raw = await api.post<unknown>("/batches", data);
    return mapBatchRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async updateBatch(id: number, data: Partial<Batch>): Promise<Batch> {
    const raw = await api.patch<unknown>(`/batches/${id}`, data);
    return mapBatchRaw(asRecordData<Record<string, unknown>>(raw));
  },

  async deleteBatch(id: number): Promise<ApiSuccessResponse> {
    return api.delete<ApiSuccessResponse>(`/batches/${id}`);
  },

  async listStudents(params?: PaginationParams & { search?: string; batch_id?: number }): Promise<PaginatedResponse<LmsStudentRecord>> {
    const raw = await api.get<unknown>("/students", params as Record<string, string | number | boolean | undefined>);
    return asPaginated<LmsStudentRecord>(raw);
  },

  async getStudent(id: number): Promise<LmsStudentRecord> {
    const raw = await api.get<unknown>(`/students/${id}`);
    return asRecordData<LmsStudentRecord>(raw);
  },

  async createStudent(data: LmsStudentCreateRequest): Promise<LmsStudentRecord> {
    const raw = await api.post<unknown>("/students", data);
    return asRecordData<LmsStudentRecord>(raw);
  },

  async updateStudent(id: number, data: Partial<LmsStudentCreateRequest & { status?: string }>): Promise<LmsStudentRecord> {
    const raw = await api.patch<unknown>(`/students/${id}`, data);
    return asRecordData<LmsStudentRecord>(raw);
  },

  async listTeachers(params?: PaginationParams & { search?: string }): Promise<PaginatedResponse<LmsTeacherRecord>> {
    const raw = await api.get<unknown>("/teachers", params as Record<string, string | number | boolean | undefined>);
    return asPaginated<LmsTeacherRecord>(raw);
  },

  async createTeacher(data: LmsTeacherCreateRequest): Promise<LmsTeacherRecord> {
    const raw = await api.post<unknown>("/teachers", data);
    return asRecordData<LmsTeacherRecord>(raw);
  },

  async getTimetable(params?: { course_id?: number; teacher_id?: number; batch_id?: number }): Promise<TimetableSession[]> {
    const raw = await api.get<{ data: TimetableSession[] } | TimetableSession[]>("/timetable", params as Record<string, string | number | boolean | undefined>);
    return Array.isArray(raw) ? raw : (raw as { data: TimetableSession[] }).data ?? [];
  },

  async createTimetableSession(data: Partial<TimetableSession>): Promise<TimetableSession> {
    return api.post<TimetableSession>("/timetable", data);
  },

  async deleteTimetableSession(id: number): Promise<ApiSuccessResponse> {
    return api.delete<ApiSuccessResponse>(`/timetable/${id}`);
  },

  async getAttendance(params?: { course_id?: number; student_id?: number; date?: string }): Promise<AttendanceRecord[]> {
    const raw = await api.get<{ data: AttendanceRecord[] } | AttendanceRecord[]>("/attendance", params as Record<string, string | number | boolean | undefined>);
    return Array.isArray(raw) ? raw : (raw as { data: AttendanceRecord[] }).data ?? [];
  },

  async recordAttendance(data: { course_id: number; date: string; records: { student_id: number; status: string }[] }): Promise<ApiSuccessResponse> {
    return api.post<ApiSuccessResponse>("/attendance", data);
  },

  async getGrades(params?: { course_id?: number; student_id?: number }): Promise<GradeRecord[]> {
    const raw = await api.get<{ data: GradeRecord[] } | GradeRecord[]>("/grades", params as Record<string, string | number | boolean | undefined>);
    return Array.isArray(raw) ? raw : (raw as { data: GradeRecord[] }).data ?? [];
  },
};
