import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { getConfigValue } from '@brojs/cli'

import { keycloak } from '../kc'
import {
  AccessCode,
  BaseResponse,
  Course,
  Lesson,
  PopulatedCourse,
  User,
  UserData,
} from '../model'

export const api = createApi({
  reducerPath: 'auth',
  baseQuery: fetchBaseQuery({
    baseUrl: getConfigValue('journal.back.url'),
    fetchFn: async (
      input: RequestInfo | URL,
      init?: RequestInit | undefined,
    ) => {
      const response = await fetch(input, init)

      if (response.status === 403) keycloak.login()

      return response
    },
    headers: {
      'Content-Type': 'application/json;charset=utf-8',
    },
    prepareHeaders: (headers) => {
      headers.set('Authorization', `Bearer ${keycloak.token}`)
    },
  }),
  tagTypes: ['LessonList', 'CourseList', 'Course'],
  endpoints: (builder) => ({
    coursesList: builder.query<BaseResponse<Course[]>, void>({
      query: () => '/course/list',
      providesTags: ['CourseList'],
    }),
    createUpdateCourse: builder.mutation<
      BaseResponse<Course>,
      Partial<Course> & Pick<Course, 'name'>
    >({
      query: (course) => ({
        url: '/course',
        method: 'POST',
        body: course,
      }),
      invalidatesTags: ['CourseList'],
    }),
    courseAllStudents: builder.query<BaseResponse<User[]>, string>({
      query: (courseId) => `/course/students/${courseId}`,
    }),
    manualAddStudent: builder.mutation<
      BaseResponse<void>,
      { lessonId: string; user: User }
    >({
      query: ({ lessonId, user }) => ({
        url: `/lesson/add-student/${lessonId}`,
        method: 'POST',
        body: user,
      }),
    }),

    lessonList: builder.query<BaseResponse<Lesson[]>, string>({
      query: (courseId) => `/lesson/list/${courseId}`,
      providesTags: ['LessonList'],
    }),
    createLesson: builder.mutation<
      BaseResponse<Lesson>,
      Partial<Lesson> & Pick<Lesson, 'name' | 'date'> & { courseId: string }
    >({
      query: (data) => ({
        url: '/lesson',
        method: 'POST',
        body: data,
      }),
      invalidatesTags: ['LessonList'],
    }),
    updateLesson: builder.mutation<BaseResponse<Lesson>, Partial<Lesson> & Pick<Lesson, 'id'>>({
      query: (data) => ({
        method: 'PUT',
        url: '/lesson',
        body: data,
      }),
      invalidatesTags: ['LessonList'],
    }),
    deleteLesson: builder.mutation<null, string>({
      query: (lessonId) => ({
        url: `/lesson/${lessonId}`,
        method: 'DELETE',
      }),
      invalidatesTags: ['LessonList'],
    }),
    lessonById: builder.query<BaseResponse<Lesson>, string>({
      query: (lessonId: string) => `/lesson/${lessonId}`,
    }),

    createAccessCode: builder.query<
      BaseResponse<AccessCode>,
      { lessonId: string }
    >({
      query: ({ lessonId }) => ({
        url: '/lesson/access-code',
        method: 'POST',
        body: { lessonId },
      }),
    }),
    getAccess: builder.query<
      BaseResponse<{ user: UserData; accessCode: AccessCode }>,
      { accessCode: string }
    >({
      query: ({ accessCode }) => ({
        url: `/lesson/access-code/${accessCode}`,
        method: 'GET',
      }),
    }),
    getCourseById: builder.query<PopulatedCourse, string>({
      query: (courseId) => `/course/${courseId}`,
      transformResponse: (response: BaseResponse<PopulatedCourse>) => response.body,
      providesTags: ['Course'],
    }),
    toggleExamWithJury: builder.mutation<void, string>({
      query: (courseId) => ({
        url: `/course/toggle-exam-with-jury/${courseId}`,
        method: 'POST',
        body: {},
      }),
      invalidatesTags: ['Course']
    })
  }),
})