import { query, request } from "../utils"
import type {
  Student,
  StudentResponse,
  CreateStudentData,
  UpdateStudentData,
  Order,
  CoursesResponse,
  OrdersResponse,
  Course,
  ClassSession,
  ClassSessionsResponse,
  ClassAttendance,
  ClassAttendancesResponse,
} from "../types"

/**
 * Get all students
 * @returns Promise with array of students
 */
export const getStudents = async (): Promise<Student[]> => {
  try {
    console.log("[students] Fetching students...")
    // query() already extracts response.data if it exists
    const studentsArray = await query("students")

    console.log("[students] Raw response from query():", studentsArray)

    if (Array.isArray(studentsArray)) {
      console.log(`[students] Fetched ${studentsArray.length} students`)
      return studentsArray
    }

    console.warn("[students] Response is not an array:", studentsArray)
    return []
  } catch (error) {
    console.error("[students] Error fetching students:", error)
    return []
  }
}

/**
 * Get student by ID
 * @param id Student ID
 * @returns Promise with student object
 */
export const getStudentById = async (id: number): Promise<StudentResponse> => {
  const response: StudentResponse = await query(`students/${id}`, "GET")
  return response
}

/**
 * Get student by User ID
 * @param userId User ID
 * @returns Promise with student object
 */
export const getStudentByUserId = async (userId: number): Promise<Student> => {
  const response: StudentResponse = await query(`students/byUserId/${userId}`, "GET")
  return response.data
}

/**
 * Get current logged-in student
 * @returns Promise with current student object
 */
export const getCurrentStudent = async (): Promise<Student> => {
  try {
    console.log("[students] Fetching current student info...")
    const response = await request<StudentResponse>("students_page/getStudent", "GET", undefined)

    if (response && response.status === "OK" && response.data) {
      console.log("[students] Current student fetched:", { id: response.data.id, name: response.data.name })
      return response.data
    }

    throw new Error("Invalid response format for current student")
  } catch (error) {
    console.error("[students] Error fetching current student:", error)
    throw error
  }
}

/**
 * Create a new student
 * @param studentData Student data
 * @returns Promise with newly created student
 */
export const createStudent = async (studentData: CreateStudentData): Promise<Student> => {
  const response: StudentResponse = await query("students", "POST", studentData)
  return response.data
}

/**
 * Update an existing student
 * @param id Student ID
 * @param studentData Updated student data
 * @returns Promise with updated student
 */
export const updateStudent = async (id: number, studentData: UpdateStudentData): Promise<Student> => {
  const response: StudentResponse = await query(`students/${id}`, "PUT", studentData)
  return response.data
}

/**
 * Delete a student
 * @param id Student ID
 * @returns Promise with deletion result
 */
export const deleteStudent = async (id: number): Promise<boolean> => {
  await query(`students/${id}`, "DELETE")
  return true
}

/**
 * Get orders for the current logged-in student
 * @returns Promise<Order[]> Array of orders for the student
 */
export async function getStudentOrders(): Promise<Order[]> {
  try {
    console.log("[students] Fetching orders for current student...")
    const response = await request<OrdersResponse>(`students_page/getOrders`)

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} orders for current student`)
      return response.data
    }

    console.warn("[students] Invalid response format for student orders")
    return []
  } catch (error) {
    console.error("[students] Error fetching orders for current student:", error)
    return []
  }
}

/**
 * Get subscribed courses for students
 * @returns Promise<Course[]> Array of subscribed courses
 */
export async function getSubscribedCourses(): Promise<Course[]> {
  try {
    console.log("[students] Fetching subscribed courses...")
    const response = await request<CoursesResponse>("students_page/getCourses")

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} subscribed courses`)
      return response.data
    }

    console.warn("[students] Invalid response format for subscribed courses")
    return []
  } catch (error) {
    console.error("[students] Error fetching subscribed courses:", error)
    return []
  }
}

/**
 * Get upcoming sessions for the student
 * @returns Promise<ClassSession[]> Array of upcoming class sessions
 */
export async function getUpcomingSessions(): Promise<ClassSession[]> {
  try {
    console.log("[students] Fetching upcoming sessions...")
    const response = await request<ClassSessionsResponse>("students_page/getUpcomingSessions")

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} upcoming sessions`)
      // Sort sessions by scheduled_at date (upcoming first)
      const sortedSessions = [...response.data].sort(
        (a, b) => new Date(a.scheduled_at).getTime() - new Date(b.scheduled_at).getTime(),
      )
      return sortedSessions
    }

    console.warn("[students] Invalid response format for upcoming sessions")
    return []
  } catch (error) {
    console.error("[students] Error fetching upcoming sessions:", error)
    return []
  }
}

/**
 * Get all sessions for the student
 * @returns Promise<ClassSession[]> Array of upcoming class sessions
 */
export async function getAllSessions(): Promise<ClassSession[]> {
  try {
    console.log("[students] Fetching upcoming sessions...")
    const response = await request<ClassSessionsResponse>("students_page/getAllSessions")

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} upcoming sessions`)
      // Sort sessions by scheduled_at date (upcoming first)
      const sortedSessions = [...response.data].sort(
        (a, b) => new Date(a.scheduled_at).getTime() - new Date(b.scheduled_at).getTime(),
      )
      return sortedSessions
    }

    console.warn("[students] Invalid response format for upcoming sessions")
    return []
  } catch (error) {
    console.error("[students] Error fetching upcoming sessions:", error)
    return []
  }
}

/**
 * Get all subscribed sessions for the student
 * @returns Promise<ClassSession[]> Array of all class sessions the student is subscribed to
 */
export async function getAllSubscribedSessions(): Promise<ClassSession[]> {
  try {
    console.log("[students] Fetching all subscribed sessions...")
    const response = await request<ClassSessionsResponse>("students_page/getClassSessions")

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} subscribed sessions`)
      return response.data
    }

    console.warn("[students] Invalid response format for subscribed sessions")
    return []
  } catch (error) {
    console.error("[students] Error fetching subscribed sessions:", error)
    return []
  }
}

/**
 * Get class attendances for the current student
 * @returns Promise<ClassAttendance[]> Array of class attendances for the student
 */
export async function getClassAttendances(): Promise<ClassAttendance[]> {
  try {
    console.log("[students] Fetching class attendances...")
    const response = await request<ClassAttendancesResponse>("students_page/getClassAttendances")

    if (response && response.status === "OK" && Array.isArray(response.data)) {
      console.log(`[students] Fetched ${response.data.length} class attendances`)
      return response.data
    }

    console.warn("[students] Invalid response format for class attendances")
    return []
  } catch (error) {
    console.error("[students] Error fetching class attendances:", error)
    return []
  }
}


/**
 * Fetches all class sessions for calendar page
 * @returns Promise with class sessions data
 */
export async function getAllClassSessions(): Promise<{
  status: string
  class_sessions: ClassSession[]
}> {
  try {
    const response = await queryFull("student_page/getAllClassSessions", "GET")

    if (response.status === "OK" && response.class_sessions) {
      return {
        status: response.status,
        class_sessions: response.class_sessions,
      }
    }

    throw new Error("Invalid response format or class sessions not found")
  } catch (error) {
    console.error("Error fetching class sessions:", error)
    throw error
  }
}

/**
 * Students data object for direct access
 * Contains methods for CRUD operations on students
 */
export const students = {
  getAll: getStudents,
  getById: getStudentById, // Now returns StudentResponse instead of Student
  getByUserId: getStudentByUserId,
  getCurrent: getCurrentStudent,
  create: createStudent,
  update: updateStudent,
  delete: deleteStudent,
  getOrders: getStudentOrders,
  getSubscribedCourses: getSubscribedCourses,
  getAllSessions: getAllSessions,
  getUpcomingSessions: getUpcomingSessions,
  getAllSubscribedSessions: getAllSubscribedSessions,
  getClassAttendances: getClassAttendances,
}
