import { makeRequest } from "@frontend/kitui";
import { defaultQuizConfig } from "@model/quizSettings";

import { parseAxiosError } from "@utils/parse-error";

import type { RawQuiz } from "model/quiz/quiz";
import type { CopyQuizRequest, CopyQuizResponse } from "model/quiz/copy";
import type { CreateQuizRequest } from "model/quiz/create";
import type { DeleteQuizRequest, DeleteQuizResponse } from "model/quiz/delete";
import type { EditQuizRequest, EditQuizResponse } from "model/quiz/edit";
import type { GetQuizRequest, GetQuizResponse } from "model/quiz/get";
import { transliterate } from 'transliteration';
import type {
  GetQuizListRequest,
  GetQuizListResponse,
} from "model/quiz/getList";

type AddedQuizImagesResponse = {
  [key: string]: string;
};

const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
const IMAGES_URL = `${process.env.REACT_APP_DOMAIN}/squizstorer/v1.0.0`;

export const createQuiz = async (
  body?: Partial<CreateQuizRequest>,
): Promise<[RawQuiz | null, string?]> => {
  try {
    const createdQuiz = await makeRequest<CreateQuizRequest, RawQuiz>({
      method: "POST",
      url: `${API_URL}/quiz/create`,
      body: { ...defaultCreateQuizBody, ...body },
    });

    return [createdQuiz];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось создать квиз. ${error}`];
  }
};

export const getQuizList = async (
  body?: Partial<CreateQuizRequest>,
): Promise<[RawQuiz[] | null, string?]> => {
  try {
    const { items } = await makeRequest<
      GetQuizListRequest,
      GetQuizListResponse
    >({
      method: "POST",
      url: `${API_URL}/quiz/getList`,
      body: { ...defaultGetQuizListBody, ...body },
    });

    return [items];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось получить список квизов. ${error}`];
  }
};

export const getQuiz = async (
  body?: Partial<GetQuizRequest>,
): Promise<[GetQuizResponse | null, string?]> => {
  try {
    const quiz = await makeRequest<GetQuizRequest, GetQuizResponse>({
      method: "GET",
      url: `${API_URL}/quiz/get`,
      body: { ...defaultGetQuizBody, ...body },
    });

    return [quiz];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось получить квиз. ${error}`];
  }
};

export const editQuiz = async (
  body: EditQuizRequest,
  signal?: AbortSignal,
): Promise<[EditQuizResponse | null, string?]> => {
  try {
    const editedQuiz = await makeRequest<EditQuizRequest, EditQuizResponse>({
      method: "PATCH",
      url: `${API_URL}/quiz/edit`,
      body,
      signal,
    });

    return [editedQuiz];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось изменить квиз. ${error}`];
  }
};

export const copyQuiz = async (
  id: number,
): Promise<[EditQuizResponse | null, string?]> => {
  try {
    const copiedQuiz = await makeRequest<CopyQuizRequest, CopyQuizResponse>({
      method: "POST",
      url: `${API_URL}/quiz/copy`,
      body: { id },
    });

    return [copiedQuiz];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось скопировать квиз. ${error}`];
  }
};

export const deleteQuiz = async (
  id: number,
): Promise<[DeleteQuizResponse | null, string?]> => {
  try {
    const deletedQuiz = await makeRequest<
      DeleteQuizRequest,
      DeleteQuizResponse
    >({
      method: "DELETE",
      url: `${API_URL}/quiz/delete`,
      body: { id },
    });

    return [deletedQuiz];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось удалить квиз. ${error}`];
  }
};

export const addQuizImages = async (
  quizId: number,
  image: Blob,
): Promise<[AddedQuizImagesResponse | null, string?]> => {
  try {
    const formData = new FormData();

    const name = image?.name ? transliterate(image?.name.replace(/\s/g, '_')) : "blob"

    //Замена всех побелов на _
    const renamedImage = new File([image], name)


    formData.append("quiz", quizId.toString());
    formData.append("image", renamedImage);

    const addedQuizImages = await makeRequest<
      FormData,
      AddedQuizImagesResponse
    >({
      url: `${IMAGES_URL}/quiz/putImages`,
      body: formData,
      method: "PUT",
    });

    return [addedQuizImages];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось добавить изображение. ${error}`];
  }
};

export const copyQuizTemplate = async (
  qid: string,
): Promise<[number | null, string?]> => {
  try {
    const { id } = await makeRequest<{ Qid: string }, { id: number }>({
      method: "POST",
      url: `${API_URL}/quiz/template`,
      body: { Qid: qid },
    });

    if (!id) {
      return [null, `Не удалось скопировать шаблон квиза.`];
    }

    return [id];
  } catch (nativeError) {
    const [error] = parseAxiosError(nativeError);

    return [null, `Не удалось скопировать шаблон квиза. ${error}`];
  }
};

export const quizApi = {
  create: createQuiz,
  getList: getQuizList,
  get: getQuiz,
  edit: editQuiz,
  copy: copyQuiz,
  delete: deleteQuiz,
  addImages: addQuizImages,
  copyTemplate: copyQuizTemplate,
};

const defaultCreateQuizBody: CreateQuizRequest = {
  fingerprinting: true,
  repeatable: true,
  note_prevented: true,
  mail_notifications: false,
  unique_answers: true,
  name: "",
  description: "",
  config: JSON.stringify(defaultQuizConfig),
  status: "stop",
  limit: 0,
  due_to: 0,
  time_of_passing: 0,
  pausable: false,
  super: false,
  group_id: 0,
};

const defaultGetQuizBody: GetQuizRequest = {
  quiz_id: "string",
  limit: 0,
  page: 0,
  need_config: true,
};

const defaultGetQuizListBody: GetQuizListRequest = {
  limit: 100,
  offset: 0,
};
