import { queryOptions } from '@tanstack/react-query'
import { api } from '@/lib/api-client'
import type {
  Instructor,
  InstructorBlockedDate,
  LessonType,
  ScheduleSlot,
  Enrollment,
  LessonSession,
  GradingScale,
  LessonPlan,
  LessonPlanItem,
  LessonPlanItemGradeHistory,
  LessonPlanTemplate,
  StoreClosure,
  SessionPlanItem,
} from '@/types/lesson'
import type { PaginatedResponse, PaginationInput } from '@lunarfront/shared/schemas'

// --- Instructors ---

export const instructorKeys = {
  all: ['instructors'] as const,
  list: (params: PaginationInput) => [...instructorKeys.all, 'list', params] as const,
  detail: (id: string) => [...instructorKeys.all, 'detail', id] as const,
  blockedDates: (id: string) => [...instructorKeys.all, id, 'blocked-dates'] as const,
}

export function instructorListOptions(params: PaginationInput) {
  return queryOptions({
    queryKey: instructorKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<Instructor>>('/v1/instructors', params),
  })
}

export function instructorDetailOptions(id: string) {
  return queryOptions({
    queryKey: instructorKeys.detail(id),
    queryFn: () => api.get<Instructor>(`/v1/instructors/${id}`),
    enabled: !!id,
  })
}

export function instructorBlockedDatesOptions(instructorId: string) {
  return queryOptions({
    queryKey: instructorKeys.blockedDates(instructorId),
    queryFn: () => api.get<InstructorBlockedDate[]>(`/v1/instructors/${instructorId}/blocked-dates`),
    enabled: !!instructorId,
  })
}

export const instructorMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<Instructor>('/v1/instructors', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<Instructor>(`/v1/instructors/${id}`, data),
  delete: (id: string) =>
    api.del<Instructor>(`/v1/instructors/${id}`),
  addBlockedDate: (instructorId: string, data: Record<string, unknown>) =>
    api.post<InstructorBlockedDate>(`/v1/instructors/${instructorId}/blocked-dates`, data),
  deleteBlockedDate: (instructorId: string, id: string) =>
    api.del<InstructorBlockedDate>(`/v1/instructors/${instructorId}/blocked-dates/${id}`),
}

// --- Lesson Types ---

export const lessonTypeKeys = {
  all: ['lesson-types'] as const,
  list: (params: PaginationInput) => [...lessonTypeKeys.all, 'list', params] as const,
  detail: (id: string) => [...lessonTypeKeys.all, 'detail', id] as const,
}

export function lessonTypeListOptions(params: PaginationInput) {
  return queryOptions({
    queryKey: lessonTypeKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<LessonType>>('/v1/lesson-types', params),
  })
}

export const lessonTypeMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<LessonType>('/v1/lesson-types', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<LessonType>(`/v1/lesson-types/${id}`, data),
  delete: (id: string) =>
    api.del<LessonType>(`/v1/lesson-types/${id}`),
}

// --- Schedule Slots ---

export const scheduleSlotKeys = {
  all: ['schedule-slots'] as const,
  list: (params: PaginationInput) => [...scheduleSlotKeys.all, 'list', params] as const,
  byInstructor: (instructorId: string, params: PaginationInput) =>
    [...scheduleSlotKeys.all, 'instructor', instructorId, params] as const,
  detail: (id: string) => [...scheduleSlotKeys.all, 'detail', id] as const,
}

export function scheduleSlotListOptions(params: PaginationInput, filters?: { instructorId?: string; dayOfWeek?: number }) {
  const query = { ...params, ...filters }
  return queryOptions({
    queryKey: filters?.instructorId
      ? scheduleSlotKeys.byInstructor(filters.instructorId, params)
      : scheduleSlotKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<ScheduleSlot>>('/v1/schedule-slots', query),
  })
}

export const scheduleSlotMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<ScheduleSlot>('/v1/schedule-slots', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<ScheduleSlot>(`/v1/schedule-slots/${id}`, data),
  delete: (id: string) =>
    api.del<ScheduleSlot>(`/v1/schedule-slots/${id}`),
}

// --- Enrollments ---

export const enrollmentKeys = {
  all: ['enrollments'] as const,
  list: (params: Record<string, unknown>) => [...enrollmentKeys.all, 'list', params] as const,
  detail: (id: string) => [...enrollmentKeys.all, 'detail', id] as const,
}

export function enrollmentListOptions(params: Record<string, unknown>) {
  return queryOptions({
    queryKey: enrollmentKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<Enrollment>>('/v1/enrollments', params),
  })
}

export function enrollmentDetailOptions(id: string) {
  return queryOptions({
    queryKey: enrollmentKeys.detail(id),
    queryFn: () => api.get<Enrollment>(`/v1/enrollments/${id}`),
    enabled: !!id,
  })
}

export const enrollmentMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<Enrollment>('/v1/enrollments', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<Enrollment>(`/v1/enrollments/${id}`, data),
  updateStatus: (id: string, status: string) =>
    api.post<Enrollment>(`/v1/enrollments/${id}/status`, { status }),
  generateSessions: (id: string, weeks?: number) =>
    api.post<{ generated: number; sessions: LessonSession[] }>(
      `/v1/enrollments/${id}/generate-sessions${weeks ? `?weeks=${weeks}` : ''}`,
      {},
    ),
}

// --- Lesson Sessions ---

export const sessionKeys = {
  all: ['lesson-sessions'] as const,
  list: (params: Record<string, unknown>) => [...sessionKeys.all, 'list', params] as const,
  detail: (id: string) => [...sessionKeys.all, 'detail', id] as const,
  planItems: (id: string) => [...sessionKeys.all, id, 'plan-items'] as const,
}

export function sessionListOptions(params: Record<string, unknown>) {
  return queryOptions({
    queryKey: sessionKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<LessonSession>>('/v1/lesson-sessions', params),
  })
}

export function sessionDetailOptions(id: string) {
  return queryOptions({
    queryKey: sessionKeys.detail(id),
    queryFn: () => api.get<LessonSession>(`/v1/lesson-sessions/${id}`),
    enabled: !!id,
  })
}

export function sessionPlanItemsOptions(sessionId: string) {
  return queryOptions({
    queryKey: sessionKeys.planItems(sessionId),
    queryFn: () => api.get<SessionPlanItem[]>(`/v1/lesson-sessions/${sessionId}/plan-items`),
    enabled: !!sessionId,
  })
}

export const sessionMutations = {
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<LessonSession>(`/v1/lesson-sessions/${id}`, data),
  updateStatus: (id: string, status: string) =>
    api.post<LessonSession>(`/v1/lesson-sessions/${id}/status`, { status }),
  updateNotes: (id: string, data: Record<string, unknown>) =>
    api.post<LessonSession>(`/v1/lesson-sessions/${id}/notes`, data),
  linkPlanItems: (id: string, lessonPlanItemIds: string[]) =>
    api.post<{ linked: number; items: SessionPlanItem[] }>(`/v1/lesson-sessions/${id}/plan-items`, { lessonPlanItemIds }),
}

// --- Grading Scales ---

export const gradingScaleKeys = {
  all: ['grading-scales'] as const,
  list: (params: PaginationInput) => [...gradingScaleKeys.all, 'list', params] as const,
  allScales: [...['grading-scales'], 'all'] as const,
  detail: (id: string) => [...gradingScaleKeys.all, 'detail', id] as const,
}

export function gradingScaleListOptions(params: PaginationInput) {
  return queryOptions({
    queryKey: gradingScaleKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<GradingScale>>('/v1/grading-scales', params),
  })
}

export function gradingScaleAllOptions() {
  return queryOptions({
    queryKey: gradingScaleKeys.allScales,
    queryFn: () => api.get<GradingScale[]>('/v1/grading-scales/all'),
  })
}

export function gradingScaleDetailOptions(id: string) {
  return queryOptions({
    queryKey: gradingScaleKeys.detail(id),
    queryFn: () => api.get<GradingScale>(`/v1/grading-scales/${id}`),
    enabled: !!id,
  })
}

export const gradingScaleMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<GradingScale>('/v1/grading-scales', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<GradingScale>(`/v1/grading-scales/${id}`, data),
  delete: (id: string) =>
    api.del<GradingScale>(`/v1/grading-scales/${id}`),
}

// --- Lesson Plans ---

export const lessonPlanKeys = {
  all: ['lesson-plans'] as const,
  list: (params: Record<string, unknown>) => [...lessonPlanKeys.all, 'list', params] as const,
  detail: (id: string) => [...lessonPlanKeys.all, 'detail', id] as const,
}

export function lessonPlanListOptions(params: Record<string, unknown>) {
  return queryOptions({
    queryKey: lessonPlanKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<LessonPlan>>('/v1/lesson-plans', params),
  })
}

export function lessonPlanDetailOptions(id: string) {
  return queryOptions({
    queryKey: lessonPlanKeys.detail(id),
    queryFn: () => api.get<LessonPlan>(`/v1/lesson-plans/${id}`),
    enabled: !!id,
  })
}

export const lessonPlanMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<LessonPlan>('/v1/lesson-plans', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<LessonPlan>(`/v1/lesson-plans/${id}`, data),
}

// --- Lesson Plan Items ---

export const lessonPlanItemKeys = {
  gradeHistory: (itemId: string) => ['lesson-plan-items', itemId, 'grade-history'] as const,
}

export function lessonPlanItemGradeHistoryOptions(itemId: string) {
  return queryOptions({
    queryKey: lessonPlanItemKeys.gradeHistory(itemId),
    queryFn: () => api.get<LessonPlanItemGradeHistory[]>(`/v1/lesson-plan-items/${itemId}/grade-history`),
    enabled: !!itemId,
  })
}

export const lessonPlanItemMutations = {
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<LessonPlanItem>(`/v1/lesson-plan-items/${id}`, data),
  addGrade: (id: string, data: Record<string, unknown>) =>
    api.post<{ record: LessonPlanItemGradeHistory; item: LessonPlanItem }>(`/v1/lesson-plan-items/${id}/grades`, data),
}

// --- Lesson Plan Templates ---

export const lessonPlanTemplateKeys = {
  all: ['lesson-plan-templates'] as const,
  list: (params: PaginationInput) => [...lessonPlanTemplateKeys.all, 'list', params] as const,
  detail: (id: string) => [...lessonPlanTemplateKeys.all, 'detail', id] as const,
}

export function lessonPlanTemplateListOptions(params: PaginationInput) {
  return queryOptions({
    queryKey: lessonPlanTemplateKeys.list(params),
    queryFn: () => api.get<PaginatedResponse<LessonPlanTemplate>>('/v1/lesson-plan-templates', params),
  })
}

export function lessonPlanTemplateDetailOptions(id: string) {
  return queryOptions({
    queryKey: lessonPlanTemplateKeys.detail(id),
    queryFn: () => api.get<LessonPlanTemplate>(`/v1/lesson-plan-templates/${id}`),
    enabled: !!id,
  })
}

export const lessonPlanTemplateMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<LessonPlanTemplate>('/v1/lesson-plan-templates', data),
  update: (id: string, data: Record<string, unknown>) =>
    api.patch<LessonPlanTemplate>(`/v1/lesson-plan-templates/${id}`, data),
  delete: (id: string) =>
    api.del<LessonPlanTemplate>(`/v1/lesson-plan-templates/${id}`),
  createPlan: (templateId: string, data: Record<string, unknown>) =>
    api.post<LessonPlan>(`/v1/lesson-plan-templates/${templateId}/create-plan`, data),
}

// --- Store Closures ---

export const storeClosureKeys = {
  all: ['store-closures'] as const,
}

export function storeClosureListOptions() {
  return queryOptions({
    queryKey: storeClosureKeys.all,
    queryFn: () => api.get<StoreClosure[]>('/v1/store-closures'),
  })
}

export const storeClosureMutations = {
  create: (data: Record<string, unknown>) =>
    api.post<StoreClosure>('/v1/store-closures', data),
  delete: (id: string) =>
    api.del<StoreClosure>(`/v1/store-closures/${id}`),
}
