import axios, { AxiosError } from 'axios';
import Cookies from 'js-cookie';
import {
    Course,
    CreateCourseRequest,
    CreateCourseResponse,
    CreateLessonRequest,
    CreateLessonResponse,
    CreateStepRequest,
    CreateVideoStepRequest, getCourseByIdForWatchingResponse,
    LessonItem, ReorderDataRequest,
    StepItem,
    TrainerCoursesResponse,
    UpdateCourseRequest,
    UpdateCourseResponse,
    UpdateLessonRequest,
    UpdatePublishStatusResponse,
    UpdateStepRequest, UpdateVideoStepRequest
} from "@/lib/types/courses";
import { GetTrainerProfileResponse } from "@/lib/types/profile";
import { signOut } from "next-auth/react";
import { axiosInstance } from "@/lib/api/services/apiClient";


export const TrainerCourseService = {
    async getAllCourses(): Promise<Course[]> {
        const response = await axiosInstance.get('/courses/findAll');
        return response.data;
    },

    async trainerCourses(): Promise<TrainerCoursesResponse> {
        const response = await axiosInstance.get('/trainer/courses/with-content');
        return response.data;
    },

    async getCourseByIdForWatching({ courseId }: { courseId: number }): Promise<getCourseByIdForWatchingResponse> {
        const response = await axiosInstance.get(`/trainer/courses/${courseId}/with-content`);
        return response.data;
    },

    async createCourse(courseData: CreateCourseRequest & { courseImage?: File | string, courseVideo?: File | string }): Promise<CreateCourseResponse | null> {
        const formData = new FormData();
        Object.entries(courseData).forEach(([key, value]) => {
            if (value !== undefined && value !== null) {
                formData.append(key, value as any);
            }
        });
        const response = await axiosInstance.post('/courses/create', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        });
        return response.data;
    },

    async deleteCourse({ courseID }: { courseID: number }): Promise<{ message: string } | null> {
        const response = await axiosInstance.delete(`/courses/${courseID}`);
        return response.data;
    },

    async updateCourse(courseData: UpdateCourseRequest & { courseImage?: File | string, courseVideo?: File | string }): Promise<UpdateCourseResponse | null> {
        const { id, ...dataWithoutId } = courseData;
        const formData = new FormData();
        Object.entries(dataWithoutId).forEach(([key, value]) => {
            if (value !== undefined && value !== null) {
                formData.append(key, value as any);
            }
        });
        const response = await axiosInstance.put(`/courses/${id}`, formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
        });
        return response.data;
    },

    async updatePublishStatus(id: number, isPublished: boolean): Promise<UpdatePublishStatusResponse> {
        const response = await axiosInstance.patch(`/courses/${id}/publish`, { isPublished });
        return response.data;
    },

    async createLesson(lessonData: CreateLessonRequest): Promise<CreateLessonResponse | null> {
        const { course_id, ...dataWithoutCourseId } = lessonData;
        const response = await axiosInstance.post(`/courses/${course_id}/lessons/create`, dataWithoutCourseId);
        return response.data;
    },

    async updateLesson(lessonData: UpdateLessonRequest): Promise<CreateLessonResponse | null> {
        const { course_id, lesson_id, ...dataWithoutIds } = lessonData;
        const response = await axiosInstance.put(`/courses/${course_id}/lessons/${lesson_id}`, dataWithoutIds);
        return response.data;
    },

    async deleteLesson({ courseID, lessonId }: { courseID: number, lessonId: number }): Promise<{
        message: string
    } | null> {
        const response = await axiosInstance.delete(`/courses/${courseID}/lessons/${lessonId}`);
        return response.data;
    },

    async findAllLessons(courseId: number): Promise<LessonItem[]> {
        const response = await axiosInstance.get(`/courses/${courseId}/lessons/findAll`);
        return response.data || [];
    },

    async createStep(stepData: CreateStepRequest): Promise<StepItem | null> {
        const { lesson_id, ...stepPayload } = stepData;
        const response = await axiosInstance.post(`/lessons/${lesson_id}/steps`, stepPayload);
        return response.data;
    },

    async createVideoStep(stepData: CreateVideoStepRequest): Promise<StepItem | null> {
        const { lesson_id, title, file, type, teleprompterText } = stepData;
        const formData = new FormData();
        formData.append("title", title);
        formData.append("file", file);
        if (type) formData.append("type", type);
        if (teleprompterText) formData.append("teleprompterText", teleprompterText);
        try {
            const response = await axiosInstance.post(`/lessons/${lesson_id}/steps/video`, formData, {
                headers: {
                    "Content-Type": "multipart/form-data",
                },
            });
            return response.data;
        } catch (error: unknown) {
            if (error instanceof AxiosError) {
                throw new Error(error.response?.data?.message || "Failed to create video step.");
            }
            throw new Error("An unexpected error occurred while creating video step.");
        }
    },

    async updateVideoStep(stepData: UpdateVideoStepRequest): Promise<StepItem | null> {
        const { lesson_id, step_id, title, file, type, teleprompterText } = stepData;
        const formData = new FormData();
        formData.append("title", title);
        if (file) {
            formData.append("file", file);
        }
        if (type) formData.append("type", type);
        if (teleprompterText) formData.append("teleprompterText", teleprompterText);
        try {
            const response = await axiosInstance.put(`/lessons/${lesson_id}/steps/${step_id}/video`, formData, {
                headers: {
                    "Content-Type": "multipart/form-data",
                },
            });
            return response.data;
        } catch (error: unknown) {
            if (error instanceof AxiosError) {
                throw new Error(error.response?.data?.message || "Failed to update video step.");
            }
            throw new Error("An unexpected error occurred while updating video step.");
        }
    },

    async updateStep(stepData: UpdateStepRequest): Promise<StepItem | null> {
        const { lesson_id, step_id, ...stepPayload } = stepData;
        const response = await axiosInstance.put(`/lessons/${lesson_id}/steps/${step_id}`, stepPayload);
        return response.data;
    },

    async deleteStep({ lesson_id, step_id }: { lesson_id: number, step_id: number }): Promise<{
        message: string
    } | null> {
        const response = await axiosInstance.delete(`/lessons/${lesson_id}/steps/${step_id}`);
        return response.data;
    },

    async reorderSteps(reorderData: ReorderDataRequest): Promise<void> {
        const { lesson_id, order } = reorderData
        await axiosInstance.patch(`/lessons/${lesson_id}/steps/reorder`, { order });
    },

    async getTrainerProfile({ trainerId }: { trainerId: number }): Promise<GetTrainerProfileResponse> {
        const response = await axiosInstance.get(`/courses/getTrainerProfile/${trainerId}`);
        return response.data;
    },
};
