import { QuestionVariant } from "@model/questionTypes/shared";
import { QuizStep } from "@model/settingsData";
import type { Moment } from "moment";
import { nanoid } from "nanoid";
import { createContext, useContext } from "react";
import { createStore, useStore } from "zustand";
import { immer } from "zustand/middleware/immer";
import { devtools } from "zustand/middleware";

export type Answer = string | string[] | Moment;

export type QuestionAnswer = {
  questionId: string;
  answer: Answer;
};

export type OwnVariant = {
  id: string;
  variant: QuestionVariant;
};

interface QuizViewStore {
  answers: QuestionAnswer[];
  ownVariants: OwnVariant[];
  pointsSum: number;
  points: Record<string, number>;
  currentQuizStep: QuizStep;
}

interface QuizViewActions {
  updateAnswer: (questionId: string, answer: string | string[] | Moment, points: number) => void;
  deleteAnswer: (questionId: string) => void;
  updateOwnVariant: (
    id: string, //
    answer: string | null, //
    extendedText?: string, //
    originalImageUrl?: string, //
    localImageUrl?: string //
  ) => void;
  deleteOwnVariant: (id: string) => void;
  setCurrentQuizStep: (step: QuizStep) => void;
}

export const QuizViewContext = createContext<ReturnType<typeof createQuizViewStore> | null>(null);

export function useQuizViewStore<U>(selector: (state: QuizViewStore & QuizViewActions) => U): U {
  const store = useContext(QuizViewContext);
  if (!store) throw new Error("QuizViewStore context is null");

  return useStore(store, selector);
}

export const createQuizViewStore = () =>
  createStore<QuizViewStore & QuizViewActions>()(
    immer(
      devtools(
        (set, get) => ({
          answers: [], //Массив вообще всех ответов. Объекты хранят инфо о id вопроса и списке выбранных ответов
          ownVariants: [], //Подробное описание ответов для особенных. Здесь подробно расписана вся кастомизация ответов в own вариантах
          points: {},
          pointsSum: 0,
          currentQuizStep: "startpage",
          updateAnswer(questionId, answer, points) {
            set(
              (state) => {
                const index = state.answers.findIndex((answer) => questionId === answer.questionId);

                if (index < 0) {
                  state.answers.push({ questionId, answer });
                } else {
                  state.answers[index] = { questionId, answer };
                }

                state.points = { ...state.points, ...{ [questionId]: points } };

                state.pointsSum = Object.values(state.points).reduce((sum, value) => sum + value);
              },
              false,
              {
                type: "updateAnswer",
                questionId,
                answer,
                points,
              }
            );
          },
          deleteAnswer(questionId) {
            set(
              (state) => {
                state.answers = state.answers.filter((answer) => questionId !== answer.questionId);
              },
              false,
              {
                type: "deleteAnswer",
                questionId,
              }
            );
          },
          updateOwnVariant(id, answer, extendedText, originalImageUrl, localImageUrl) {
            set(
              (state) => {
                const index = state.ownVariants.findIndex((variant) => variant.id === id);

                if (index < 0) {
                  state.ownVariants.push({
                    id,
                    variant: {
                      id: id,
                      answer: answer || "",
                      extendedText: extendedText || "",
                      hints: "",
                      originalImageUrl: originalImageUrl || "",
                      localImageUrl: localImageUrl || "",
                    },
                  });
                } else {
                  if (answer !== null) state.ownVariants[index].variant.answer = answer;
                  if (extendedText !== undefined) {
                    state.ownVariants[index].variant.extendedText = extendedText;
                  }
                  if (originalImageUrl !== undefined) {
                    state.ownVariants[index].variant.originalImageUrl = originalImageUrl;
                  }
                  if (localImageUrl !== undefined) {
                    state.ownVariants[index].variant.localImageUrl = localImageUrl;
                  }
                }
              },
              false,
              {
                type: "updateOwnVariant",
                id,
                answer,
              }
            );
          },
          deleteOwnVariant(id) {
            set(
              (state) => {
                state.ownVariants = state.ownVariants.filter((variant) => variant.id !== id);
              },
              false,
              {
                type: "deleteOwnVariant",
                id,
              }
            );
          },
          setCurrentQuizStep(step) {
            set({ currentQuizStep: step }, false, {
              type: "setCurrentQuizStep",
              step,
            });
          },
        }),
        {
          name: "QuizViewStore-" + nanoid(4),
          enabled: import.meta.env.DEV,
          trace: import.meta.env.DEV,
        }
      )
    )
  );
