import { GetQuizDataResponse, parseQuizData } from "@model/api/getQuizData";
import axios from "axios";
import MobileDetect from "mobile-detect";
import device from "current-device";

import type { AxiosError } from "axios";
import { replaceSpacesToEmptyLines } from "../components/ViewPublicationPage/tools/replaceSpacesToEmptyLines";
import { QuizSettings } from "@model/settingsData";
import * as Bowser from "bowser";
import { domain } from "../utils/defineDomain";
import { statusOfQuiz } from "@/utils/hooks/useQuestionFlowControl";
let SESSIONS = "";

const md = new MobileDetect(window.navigator.userAgent);
const userAgent = navigator.userAgent;
//операционная система
let OSDevice: string | undefined;
if (userAgent.toLowerCase().includes("linux")) {
  OSDevice = "Linux";
}
if (userAgent.toLowerCase().includes("windows")) {
  OSDevice = "Windows";
}
if (/iPad|iPhone|iPod/.test(userAgent)) {
  OSDevice = "IOS";
}
if (userAgent.toLowerCase().includes("macintosh")) {
  OSDevice = "Mac OS";
}
if (OSDevice === undefined) {
  OSDevice = userAgent;
}

//браузер
let browserUser: string;
if (Bowser.name === "Chrome") {
  browserUser = "Chrome";
} else if (Bowser.name === "Firefox") {
  browserUser = "Firefox";
} else if (Bowser.name === "Safari") {
  browserUser = "Safari";
} else if (Bowser.name === "Yandex Browser") {
  browserUser = "Yandex Browser";
} else {
  browserUser = userAgent;
}

const DeviceType = device.type;

let Device = md.mobile();
if (Device === null) {
  Device = userAgent;
}

type PublicationMakeRequestParams = {
  url: string;
  body: FormData;
  method: "POST";
};

const urlParams = new URLSearchParams(window.location.search);
const paudParam = urlParams.get("_paud");

export const publicationMakeRequest = ({ url, body }: PublicationMakeRequestParams) => {
  return axios(url, {
    data: body,
    headers: {
      "X-Sessionkey": SESSIONS,
      "Content-Type": "multipart/form-data",
      DeviceType: DeviceType,
      Device: Device,
      OS: OSDevice,
      Browser: browserUser,
    },
    method: "POST",
  });
};

// Глобальные переменные для хранения состояния между вызовами
let globalStatus: string | null = null;
let isFirstRequest = true;

/*
если запросить 0 вопросов - придёт items: null
если не запрашивать конфиг - поле конфига вообще не придёт
*/

interface GetDataProps {
  quizId: string;
  limit: number;
  page: number;
  needConfig: boolean;
}

export async function getData({ quizId, limit, page, needConfig }: GetDataProps): Promise<{
  data: GetQuizDataResponse | null;
  isRecentlyCompleted: boolean;
  error?: AxiosError;
}> {
  const body = {
    quiz_id: quizId,
    limit,
    page,
    need_config: needConfig,
  } as any;
  if (paudParam) body.auditory = Number(paudParam);

  try {
    const { data, headers } = await axios<GetQuizDataResponse>(
      domain + `/answer/v1.0.0/settings${window.location.search}`,
      {
        method: "POST",
        headers: {
          "X-Sessionkey": SESSIONS,
          "Content-Type": "application/json",
          DeviceType: DeviceType,
          Device: Device,
          OS: OSDevice,
          Browser: userAgent,
        },
        data: body,
      }
    );
    const sessions = JSON.parse(localStorage.getItem("sessions") || "{}");

    //Тут ещё проверка на антифрод без парса конфига. Нам не интересно время если не нужно запрещать проходить чаще чем в сутки
    if (
      needConfig &&
      data?.settings !== undefined &&
      typeof sessions[quizId] === "number" &&
      data.settings.cfg.includes('antifraud":true')
    ) {
      // unix время. Если меньше суток прошло - выводить ошибку, иначе пустить дальше
      if (Date.now() - sessions[quizId] < 86400000) {
        return { data, isRecentlyCompleted: true };
      }
    }

    SESSIONS = headers["x-sessionkey"] ? headers["x-sessionkey"] : SESSIONS;

    return { data, isRecentlyCompleted: false };
  } catch (nativeError) {
    const error = nativeError as AxiosError;

    return { data: null, isRecentlyCompleted: false, error: error };
  }
}

export async function getAndParceData(props: GetDataProps) {
  if (!props.quizId) throw new Error("No quiz id");

  const response = await getData(props);
  const quizDataResponse = response.data;

  if (response.error) {
    const axiosError = response.error as AxiosError;
    if (axiosError.response?.data) {
      throw new Error(
        typeof axiosError.response.data === "string"
          ? axiosError.response.data
          : JSON.stringify(axiosError.response.data)
      );
    }
    throw axiosError;
  }
  if (!quizDataResponse) {
    throw new Error("Quiz not found");
  }

  //Парсим строки в строках
  const quizSettings = replaceSpacesToEmptyLines(parseQuizData(quizDataResponse));
  //Единоразово стрингифаим ВСЁ распаршенное и удаляем лишние пробелы
  const res = JSON.parse(
    JSON.stringify({ data: quizSettings })
      .replaceAll(/\\" \\"/g, '""')
      .replaceAll(/" "/g, '""')
  ).data as QuizSettings;
  res.recentlyCompleted = response.isRecentlyCompleted;
  return res;
}

type SendAnswerProps = {
  questionId: string;
  body: string | string[];
  qid: string;
  preview?: boolean;
};

export function sendAnswer({ questionId, body, qid, preview = false }: SendAnswerProps) {
  if (preview) return;
  const formData = new FormData();

  const answers = [
    {
      question_id: questionId,
      //Для АИ квизов нельзя слать пустые строки
      content: statusOfQuiz != "ai" ? body : body.length ? body : "-", //тут массив с ответом
    },
  ];
  formData.append("answers", JSON.stringify(answers));
  formData.append("qid", qid);

  return publicationMakeRequest({
    url: domain + `/answer/v1.0.0/answer`,
    body: formData,
    method: "POST",
  });
}

//body ={file, filename}
type SendFileParams = {
  questionId: string;
  body: {
    name: string;
    file: File;
    preview: boolean;
  };
  qid: string;
};

type Answer = {
  question_id: string;
  content: string;
};

export function sendFile({ questionId, body, qid }: SendFileParams) {
  if (body.preview) return;
  const formData = new FormData();

  const file = new File([body.file], body.file.name.replace(/\s/g, "_"));
  const nameImage = body.name.replace(/\s/g, "_");

  const answers: Answer[] = [
    {
      question_id: questionId,
      content: "file:" + nameImage,
    },
  ];

  formData.append("answers", JSON.stringify(answers));
  formData.append(nameImage, file);
  formData.append("qid", qid);

  return publicationMakeRequest({
    url: domain + `/answer/v1.0.0/answer`,
    body: formData,
    method: "POST",
  });
}

//форма контактов
export type SendFCParams = {
  questionId: string;
  body: {
    name?: string;
    email?: string;
    phone?: string;
    address?: string;
    customs?: Record<string, string>;
  };
  qid: string;
  preview: boolean;
};

export function sendFC({ questionId, body, qid, preview }: SendFCParams) {
  if (preview) return;
  const formData = new FormData();

  // const keysBody = Object.keys(body)
  // const content:any = {}
  // fields.forEach((key) => {
  //     if (keysBody.includes(key)) content[key] = body.key
  // })

  const answers = [
    {
      question_id: questionId,
      content: JSON.stringify(body),
      result: true,
      qid,
    },
  ];

  formData.append("answers", JSON.stringify(answers));
  formData.append("qid", qid);

  return publicationMakeRequest({
    url: domain + `/answer/v1.0.0/answer`,
    body: formData,
    method: "POST",
  });
}

//форма контактов
export type SendResultParams = {
  questionId: string;
  pointsSum: number;
  qid: string;
  preview: boolean;
};

export function sendResult({ questionId, pointsSum, qid, preview }: SendResultParams) {
  if (preview) return;
  const formData = new FormData();

  // const keysBody = Object.keys(body)
  // const content:any = {}
  // fields.forEach((key) => {
  //     if (keysBody.includes(key)) content[key] = body.key
  // })

  const answers = [
    {
      question_id: questionId,
      content: pointsSum.toString(),
      result: false,
      qid,
    },
  ];

  formData.append("answers", JSON.stringify(answers));
  formData.append("qid", qid);

  return publicationMakeRequest({
    url: domain + `/answer/v1.0.0/answer`,
    body: formData,
    method: "POST",
  });
}
