import axios from 'axios';
import { supabase } from '../supabaseClient';
import {
  Class,
  ClassWithRole,
  ClassWithRelations,
  ClassFilters,
  Timetable,
  TimetableWithRelations,
  TimetableLesson,
  Lesson,
  LessonWithRelations,
  EnrollmentRequest,
  EnrollmentRequestWithProfile,
} from '../types/timetable.types';

// API base URL
const API_BASE = import.meta.env.VITE_API_URL || 'http://localhost:8000';

// ============================================================================
// Helper: Get auth headers
// ============================================================================

async function getAuthHeaders(): Promise<Record<string, string>> {
  const { data: { session } } = await supabase.auth.getSession();
  if (!session?.access_token) {
    throw new Error('No authentication token available');
  }
  return {
    Authorization: `Bearer ${session.access_token}`,
  };
}

// ============================================================================
// Class Service
// ============================================================================

export const classService = {
  async listClasses(filters?: ClassFilters): Promise<{ classes: Class[]; total: number }> {
    const headers = await getAuthHeaders();
    const params = new URLSearchParams();
    
    if (filters?.subject) params.append('subject', filters.subject);
    if (filters?.school_year) params.append('school_year', filters.school_year);
    if (filters?.academic_term) params.append('academic_term', filters.academic_term);
    if (filters?.search) params.append('search', filters.search);
    if (filters?.skip !== undefined) params.append('skip', filters.skip.toString());
    if (filters?.limit !== undefined) params.append('limit', filters.limit.toString());

    const response = await axios.get(`${API_BASE}/database/timetable/classes?${params}`, { headers });
    return response.data;
  },

  async getClass(classId: string): Promise<ClassWithRelations> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/classes/${classId}`, { headers });
    return response.data;
  },

  async createClass(data: {
    name: string;
    subject: string;
    school_year: string;
    academic_term: string;
    description?: string;
  }): Promise<Class> {
    const headers = await getAuthHeaders();
    const response = await axios.post(`${API_BASE}/database/timetable/classes`, data, { headers });
    return response.data;
  },

  async updateClass(classId: string, data: Partial<Class>): Promise<Class> {
    const headers = await getAuthHeaders();
    const response = await axios.patch(`${API_BASE}/database/timetable/classes/${classId}`, data, { headers });
    return response.data;
  },

  async deleteClass(classId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/classes/${classId}`, { headers });
  },

  async getMyClasses(): Promise<ClassWithRole[]> {
    const headers = await getAuthHeaders();
    const [teacherRes, studentRes] = await Promise.allSettled([
      axios.get(`${API_BASE}/database/timetable/classes/me/teacher`, { headers }),
      axios.get(`${API_BASE}/database/timetable/classes/me/student`, { headers }),
    ]);
    const teacherClasses: ClassWithRole[] = teacherRes.status === 'fulfilled'
      ? (teacherRes.value.data.classes || []).map((c: Class) => ({
          ...c,
          class_id: c.id,
          role: 'teacher' as const,
          status: 'active',
        }))
      : [];
    const studentClasses: ClassWithRole[] = studentRes.status === 'fulfilled'
      ? (studentRes.value.data.classes || []).map((c: Class) => ({
          ...c,
          class_id: c.id,
          role: 'student' as const,
          status: 'active',
        }))
      : [];
    const seen = new Set(teacherClasses.map(c => c.id));
    return [...teacherClasses, ...studentClasses.filter(c => !seen.has(c.id))];
  },

  async getMyTeachingClasses(): Promise<Class[]> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/classes/me/teacher`, { headers });
    return response.data.classes;
  },

  // Teacher management
  async addTeacher(classId: string, teacherId: string, isPrimary: boolean = false): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/classes/${classId}/teachers`,
      { teacher_id: teacherId, is_primary: isPrimary },
      { headers }
    );
  },

  async removeTeacher(classId: string, teacherId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/classes/${classId}/teachers/${teacherId}`, { headers });
  },

  // Student management
  async addStudent(classId: string, studentId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/classes/${classId}/students`,
      { student_id: studentId },
      { headers }
    );
  },

  async removeStudent(classId: string, studentId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/classes/${classId}/students/${studentId}`, { headers });
  },

  async leaveClass(classId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(`${API_BASE}/database/timetable/classes/${classId}/leave`, {}, { headers });
  },
};

// ============================================================================
// Timetable Service
// ============================================================================

export const timetableOnlyService = {
  async listTimetables(filters?: {
    class_id?: string;
    type?: 'ad-hoc' | 'recurring';
    active?: boolean;
  }): Promise<Timetable[]> {
    const headers = await getAuthHeaders();
    const params = new URLSearchParams();
    
    if (filters?.class_id) params.append('class_id', filters.class_id);
    if (filters?.type) params.append('type', filters.type);
    if (filters?.active !== undefined) params.append('active', filters.active.toString());

    const response = await axios.get(`${API_BASE}/database/timetable/timetables?${params}`, { headers });
    return response.data.timetables;
  },

  async getTimetable(timetableId: string): Promise<TimetableWithRelations> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/timetables/${timetableId}`, { headers });
    return response.data;
  },

  async createTimetable(data: {
    class_id: string;
    name: string;
    type: 'ad-hoc' | 'recurring';
    start_date: string;
    end_date?: string;
    recurrence_pattern?: Record<string, unknown>;
    recurrence_rule?: string;
    whiteboard_type?: 'single' | 'multiple';
  }): Promise<Timetable> {
    const headers = await getAuthHeaders();
    const response = await axios.post(`${API_BASE}/database/timetable/timetables`, data, { headers });
    return response.data;
  },

  async updateTimetable(timetableId: string, data: Partial<Timetable>): Promise<Timetable> {
    const headers = await getAuthHeaders();
    const response = await axios.patch(`${API_BASE}/database/timetable/timetables/${timetableId}`, data, { headers });
    return response.data;
  },

  async deleteTimetable(timetableId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/timetables/${timetableId}`, { headers });
  },

  async generateLessons(timetableId: string, startDate: string, endDate: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/timetables/${timetableId}/generate-lessons`,
      { start_date: startDate, end_date: endDate },
      { headers }
    );
  },

  // Timetable Teachers
  async addTimetableTeacher(timetableId: string, teacherId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/timetables/${timetableId}/teachers`,
      { teacher_id: teacherId },
      { headers }
    );
  },

  async removeTimetableTeacher(timetableId: string, teacherId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/timetables/${timetableId}/teachers/${teacherId}`, { headers });
  },

  // Lessons from timetable
  async getTimetableLessons(timetableId: string): Promise<TimetableLesson[]> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/timetables/${timetableId}/lessons`, { headers });
    return response.data.lessons;
  },
};

// ============================================================================
// Lesson Service
// ============================================================================

export const lessonService = {
  async listLessons(filters?: {
    timetable_id?: string;
    start_date?: string;
    end_date?: string;
    status?: 'scheduled' | 'in-progress' | 'completed' | 'cancelled';
  }): Promise<Lesson[]> {
    const headers = await getAuthHeaders();
    const params = new URLSearchParams();
    
    if (filters?.timetable_id) params.append('timetable_id', filters.timetable_id);
    if (filters?.start_date) params.append('start_date', filters.start_date);
    if (filters?.end_date) params.append('end_date', filters.end_date);
    if (filters?.status) params.append('status', filters.status);

    const response = await axios.get(`${API_BASE}/database/timetable/lessons?${params}`, { headers });
    return response.data.lessons;
  },

  async getLesson(lessonId: string): Promise<LessonWithRelations> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/lessons/${lessonId}`, { headers });
    return response.data;
  },

  async createLesson(data: {
    timetable_id: string;
    scheduled_start: string;
    scheduled_end: string;
    teacher_id?: string;
    title?: string;
    description?: string;
  }): Promise<Lesson> {
    const headers = await getAuthHeaders();
    const response = await axios.post(`${API_BASE}/database/timetable/lessons`, data, { headers });
    return response.data;
  },

  async updateLesson(lessonId: string, data: Partial<Lesson>): Promise<Lesson> {
    const headers = await getAuthHeaders();
    const response = await axios.patch(`${API_BASE}/database/timetable/lessons/${lessonId}`, data, { headers });
    return response.data;
  },

  async deleteLesson(lessonId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.delete(`${API_BASE}/database/timetable/lessons/${lessonId}`, { headers });
  },

  async startLesson(lessonId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(`${API_BASE}/database/timetable/lessons/${lessonId}/start`, {}, { headers });
  },

  async endLesson(lessonId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(`${API_BASE}/database/timetable/lessons/${lessonId}/end`, {}, { headers });
  },

  async cancelLesson(lessonId: string, reason?: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/lessons/${lessonId}/cancel`,
      { reason },
      { headers }
    );
  },
};

// ============================================================================
// Enrollment Request Service
// ============================================================================

export const enrollmentService = {
  async requestEnrollment(classId: string, message?: string): Promise<EnrollmentRequest> {
    const headers = await getAuthHeaders();
    const response = await axios.post(
      `${API_BASE}/database/timetable/classes/${classId}/enroll`,
      { message },
      { headers }
    );
    return response.data;
  },

  async listEnrollmentRequests(classId: string): Promise<EnrollmentRequestWithProfile[]> {
    const headers = await getAuthHeaders();
    const response = await axios.get(`${API_BASE}/database/timetable/classes/${classId}/enrollment-requests`, { headers });
    return response.data.requests;
  },

  async respondToEnrollment(requestId: string, status: 'approved' | 'rejected'): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(
      `${API_BASE}/database/timetable/enrollment-requests/${requestId}/respond`,
      { status },
      { headers }
    );
  },

  async cancelEnrollmentRequest(requestId: string): Promise<void> {
    const headers = await getAuthHeaders();
    await axios.post(`${API_BASE}/database/timetable/enrollment-requests/${requestId}/cancel`, {}, { headers });
  },
};

// ============================================================================
// Combined Export
// ============================================================================

export const timetableService = {
  ...classService,
  ...lessonService,
  ...enrollmentService,
  
  // Aliases for store compatibility
  getClasses: classService.listClasses,
  getClass: classService.getClass,
  createClass: classService.createClass,
  updateClass: classService.updateClass,
  deleteClass: classService.deleteClass,
  getMyClasses: classService.getMyClasses,
  getMyTeachingClasses: classService.getMyTeachingClasses,
  addTeacherToClass: classService.addTeacher,
  removeTeacherFromClass: classService.removeTeacher,
  addStudentToClass: classService.addStudent,
  removeStudentFromClass: classService.removeStudent,
  
  // Timetable aliases
  getTimetables: timetableOnlyService.listTimetables,
  getTimetable: timetableOnlyService.getTimetable,
  createTimetable: timetableOnlyService.createTimetable,
  updateTimetable: timetableOnlyService.updateTimetable,
  deleteTimetable: timetableOnlyService.deleteTimetable,
  getMyTimetables: timetableOnlyService.getMyTimetables,
  getMyTeachingTimetables: timetableOnlyService.getMyTeachingTimetables,
  addTeacherToTimetable: timetableOnlyService.addTeacher,
  removeTeacherFromTimetable: timetableOnlyService.removeTeacher,
  addTimetableLesson: timetableOnlyService.addLesson,
  updateTimetableLesson: timetableOnlyService.updateLesson,
  removeTimetableLesson: timetableOnlyService.removeLesson,
  
  // Lesson aliases
  getLessons: lessonService.listLessons,
  getLesson: lessonService.getLesson,
  generateLessons: lessonService.generateLessons,
  cancelLesson: lessonService.cancelLesson,
  getMyLessons: lessonService.getMyLessons,
  getMyTeachingLessons: lessonService.getMyTeachingLessons,
  saveWhiteboard: lessonService.saveWhiteboard,
  getWhiteboard: lessonService.getWhiteboard,
  exportWhiteboard: lessonService.exportWhiteboard,
  
  // Enrollment aliases
  getEnrollmentRequests: enrollmentService.listEnrollmentRequests,
  requestEnrollment: enrollmentService.requestEnrollment,
  respondToEnrollmentRequest: enrollmentService.respondToEnrollment,
  cancelEnrollmentRequest: enrollmentService.cancelEnrollmentRequest,
};

export default timetableOnlyService;
