import { Exam, ExerciseOnlyExam, PartExam } from "@/interfaces/exam";
import defaultModuleSettings, { defaultSectionSettings, defaultSettings, sectionLabels } from "../defaults";
import ExamEditorStore, { SectionState } from "../types";
import { MODULE_ACTIONS, ModuleActions, moduleReducer } from "./moduleReducer";
import { SECTION_ACTIONS, SectionActions, sectionReducer } from "./sectionReducer";
import { Module } from "@/interfaces";
import { updateExamWithUserSolutions } from "@/stores/exam/utils";
import { defaultExamUserSolutions } from "@/utils/exams";
import { access } from "fs";

type RootActions = { type: 'FULL_RESET' } |
{ type: 'INIT_EXAM_EDIT', payload: { exam: Exam; examModule: Module; id: string } } |
{ type: 'UPDATE_ROOT'; payload: { updates: Partial<ExamEditorStore> } } |
{ type: 'RESET_MODULE'; payload: { module: Module } };

export type Action = ModuleActions | SectionActions | RootActions;

export const rootReducer = (
    state: ExamEditorStore,
    action: Action
): Partial<ExamEditorStore> => {
    if (MODULE_ACTIONS.includes(action.type as any)) {
        if (action.type === "REORDER_EXERCISES") {
            const updatedState = sectionReducer(state, action as SectionActions);
            if (!updatedState.modules) return state;

            return moduleReducer({
                ...state,
                modules: updatedState.modules
            }, { type: "REORDER_EXERCISES" });
        }

        return moduleReducer(state, action as ModuleActions);
    }

    if (SECTION_ACTIONS.includes(action.type as any)) {
        if (action.type === "UPDATE_SECTION_STATE") {
            const updatedState = sectionReducer(state, action as SectionActions);
            if (!updatedState.modules) return state;

            return moduleReducer({
                ...state,
                modules: updatedState.modules
            }, { type: "REORDER_EXERCISES" });
        }
        return sectionReducer(state, action as SectionActions);
    }

    switch (action.type) {
        case 'UPDATE_ROOT':
            const { updates } = action.payload;
            return {
                ...state,
                ...updates
            };
        case 'RESET_MODULE':
            const { module } = action.payload;
            const timer = ["reading", "writing", "level"].includes(module) ?
                60 : (module === "speaking" ? 14 : 30);
            return {
                modules: {
                    ...state.modules,
                    [module]: defaultModuleSettings(module, timer, true),
                },
            };
        case 'FULL_RESET':
            return {
                title: "",
                currentModule: "reading",
                speakingAvatars: [],
                modules: {
                    reading: defaultModuleSettings("reading", 60),
                    writing: defaultModuleSettings("writing", 60),
                    speaking: defaultModuleSettings("speaking", 14),
                    listening: defaultModuleSettings("listening", 30),
                    level: defaultModuleSettings("level", 60)
                },
            };
        case 'INIT_EXAM_EDIT': {
            const { exam, id, examModule } = action.payload;
            let typedExam;
            let examState;


            if (["reading", "listening", "level"].includes(examModule)) {
                typedExam = updateExamWithUserSolutions(exam, defaultExamUserSolutions(exam)) as PartExam;
                examState = typedExam.parts.map((part, index) => {
                    return {
                        ...defaultSectionSettings(examModule, index + 1, part),
                        sectionId: index + 1,
                        settings: {
                            ...defaultSettings(examModule),
                            category: part.category,
                            introOption: { label: 'Custom', value: 'Custom' },
                            currentIntro: part.intro
                        },
                    }
                })

            } else {
                typedExam = updateExamWithUserSolutions(exam, defaultExamUserSolutions(exam)) as ExerciseOnlyExam;
                examState = typedExam.exercises.map((exercise, index) => {
                    return {
                        ...defaultSectionSettings(examModule, index + 1),
                        sectionId: index + 1,
                        settings: {
                            ...defaultSettings(examModule),
                            category: exercise.category,
                            introOption: { label: 'Custom', value: 'Custom' },
                            currentIntro: exercise.intro
                        },
                        state: exercise,
                    }
                })
            }

            return {
                title: id,
                modules: {
                    ...state.modules,
                    [examModule]: {
                        ...defaultModuleSettings(examModule, exam.minTimer),
                        examLabel: exam.label,
                        difficulty: exam.difficulty,
                        access: exam.access,
                        sections: examState,
                        importModule: false,
                        sectionLabels:
                            exam.module === "level" ?
                                sectionLabels(examModule, exam.parts.length) :
                                sectionLabels(examModule)
                    }
                }
            }
        }
        default:
            return {};
    }
};