import { itGetCached } from "@/fetchHelpers";
import { LearningPath } from "@/services/learningPath";
import { useCompletionStore } from "@/stores/completion";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import { useUserStore } from "@/stores/user";
import type { CourseCompletion } from "@/types";
import eventBus from "@/utils/eventBus";
import cloneDeep from "lodash/cloneDeep";
import log from "loglevel";
import { defineStore } from "pinia";
import { computed, reactive } from "vue";

export type LearningPathStoreState = {
  learningPaths: Map<string, LearningPath>;
  page: "INDEX" | "OVERVIEW";
};

type LearningPathKey = string;

function getLearningPathKey(
  slug: string,
  userId: string | number | undefined
): LearningPathKey {
  return `${slug}-${userId}`;
}

export const useLearningPathStore = defineStore("learningPath", () => {
  const state: LearningPathStoreState = reactive({
    learningPaths: new Map<LearningPathKey, LearningPath>(),
    page: "INDEX",
  });

  const learningPathForUser = computed(() => {
    return (courseSlug: string, userId: string | number | undefined) => {
      if (state.learningPaths.size > 0) {
        const learningPathKey = getLearningPathKey(`${courseSlug}-lp`, userId);
        return state.learningPaths.get(learningPathKey);
      }

      return undefined;
    };
  });

  async function loadCourseSessionCompletionData(
    courseSlug: string,
    userId: number | undefined = undefined
  ) {
    // FIXME: should not be here anymore with VBV-305
    const completionStore = useCompletionStore();

    let completionData: CourseCompletion[] = [];
    if (userId) {
      const courseSessionsStore = useCourseSessionsStore();
      const courseSession = courseSessionsStore.courseSessionForCourse(courseSlug);
      if (courseSession) {
        completionData = await completionStore.loadCourseSessionCompletionData(
          courseSession.id,
          userId
        );
        return completionData;
      }
    }

    return [];
  }

  async function loadLearningPath(
    slug: string,
    userId: number | undefined = undefined,
    reload = false,
    fail = true
  ) {
    if (!userId) {
      const userStore = useUserStore();
      userId = userStore.id;
    }

    const key = getLearningPathKey(slug, userId);

    if (state.learningPaths.has(key) && !reload) {
      return state.learningPaths.get(key);
    }

    const learningPathData = await itGetCached(`/api/course/page/${slug}/`);
    if (!learningPathData && fail) {
      throw `No learning path found with: ${slug}`;
    }

    const completionData = await loadCourseSessionCompletionData(
      learningPathData.course.slug,
      userId
    );

    const learningPath = LearningPath.fromJson(
      cloneDeep(learningPathData),
      completionData,
      userId
    );
    state.learningPaths.set(key, learningPath);
    return learningPath;
  }

  eventBus.on("switchedCourseSession", (courseSession) => {
    log.debug("handle switchedCourseSession", courseSession);
    // FIXME: clean up with VBV-305
    // Die Completion Daten werden nur für die aktuelle Durchführung geladen.
    // Deshalb müssen die hier neu geladen werden...
    state.learningPaths.forEach((lp) => {
      if (lp.userId) {
        lp.reloadCompletionData();
      }
    });
  });

  return {
    state,
    learningPathForUser,
    loadCourseSessionCompletionData,
    loadLearningPath,
  };
});
