import { useCurrentCourseSession } from "@/composables";
import { itGetCached } from "@/fetchHelpers";
import { useCompletionStore } from "@/stores/completion";
import { useUserStore } from "@/stores/user";
import type {
  CircleLight,
  CompetencePage,
  CompetenceProfilePage,
  PerformanceCriteria,
} from "@/types";
import cloneDeep from "lodash/cloneDeep";
import groupBy from "lodash/groupBy";
import orderBy from "lodash/orderBy";
import { defineStore } from "pinia";

export type CompetenceStoreState = {
  competenceProfilePages: Map<number, CompetenceProfilePage>;

  selectedCircle: { id: string; name: string };
  availableCircles: { id: string; name: string }[];
};

export const useCompetenceStore = defineStore({
  id: "competence",
  state: () => {
    return {
      competenceProfilePages: new Map<number, CompetenceProfilePage>(),
      selectedCircle: { id: "all", name: "Circle: Alle" },
      availableCircles: [],
    } as CompetenceStoreState;
  },
  getters: {},
  actions: {
    calcStatusCount(criteria: PerformanceCriteria[]) {
      if (criteria) {
        const grouped = groupBy(criteria, "completion_status");
        return {
          fail: grouped?.fail?.length || 0,
          success: grouped?.success?.length || 0,
          unknown: grouped?.unknown?.length || 0,
        };
      }

      return {
        success: 0,
        fail: 0,
        unknown: 0,
      };
    },
    criteriaByCompetence(competence: CompetencePage) {
      return competence.children.filter((criteria) => {
        if (this.selectedCircle.id != "all") {
          return criteria.circle.translation_key === this.selectedCircle.id;
        }

        return competence.children;
      });
    },
    competenceProfilePage(userId: number | undefined = undefined) {
      if (!userId) {
        const userStore = useUserStore();
        userId = userStore.id;
      }

      return this.competenceProfilePages.get(userId);
    },
    flatPerformanceCriteria(
      userId: number | undefined = undefined,
      circleTranslationKeys: string[] | undefined = undefined
    ) {
      if (!userId) {
        const userStore = useUserStore();
        userId = userStore.id;
      }

      if (this.competenceProfilePages.get(userId)) {
        const competenceProfilePage = this.competenceProfilePages.get(userId);
        if (competenceProfilePage) {
          let criteria = orderBy(
            competenceProfilePage.children.flatMap((competence) => {
              return competence.children;
            }),
            ["competence_id"],
            ["asc"]
          );

          if (this.selectedCircle.id !== "all") {
            criteria = criteria.filter(
              (c) => c.circle.translation_key === this.selectedCircle.id
            );
          }

          if (circleTranslationKeys) {
            criteria = criteria.filter((c) =>
              circleTranslationKeys.includes(c.circle.translation_key)
            );
          }

          return criteria;
        }
      }

      return [];
    },
    competences(userId: number | undefined = undefined) {
      if (!userId) {
        const userStore = useUserStore();
        userId = userStore.id;
      }

      if (this.competenceProfilePages.get(userId)) {
        const competenceProfilePage = this.competenceProfilePages.get(userId);

        if (competenceProfilePage?.children.length) {
          return competenceProfilePage.children.filter((competence) => {
            let criteria = competence.children;
            if (this.selectedCircle.id != "all") {
              criteria = criteria.filter((criteria) => {
                return criteria.circle.translation_key === this.selectedCircle.id;
              });
            }
            return criteria.length > 0;
          });
        }
      }

      return [];
    },
    async loadCompetenceProfilePage(
      slug: string,
      userId: number | undefined = undefined,
      reload = false
    ) {
      if (!userId) {
        const userStore = useUserStore();
        userId = userStore.id;
      }

      if (this.competenceProfilePages.has(userId) && !reload) {
        const competenceProfilePage = this.competenceProfilePages.get(userId);
        await this.parseCompletionData(userId);
        return competenceProfilePage;
      }

      const competenceProfilePage = await itGetCached(`/api/course/page/${slug}/`, {
        reload: reload,
      });

      if (!competenceProfilePage) {
        throw `No competenceProfilePageData found with: ${slug}`;
      }

      this.competenceProfilePages.set(userId, cloneDeep(competenceProfilePage));

      const circles = competenceProfilePage.circles.map((c: CircleLight) => {
        return { id: c.translation_key, name: `Circle: ${c.title}` };
      });
      this.availableCircles = [{ id: "all", name: "Circle: Alle" }, ...circles];

      await this.parseCompletionData(userId);

      return this.competenceProfilePages.get(userId);
    },
    async parseCompletionData(userId: number) {
      const competenceProfilePage = this.competenceProfilePages.get(userId);
      if (competenceProfilePage) {
        const completionStore = useCompletionStore();

        const courseSession = useCurrentCourseSession();
        if (courseSession) {
          const completionData = await completionStore.loadCourseSessionCompletionData(
            courseSession.value.id,
            userId
          );

          if (completionData) {
            competenceProfilePage.children.forEach((competence) => {
              competence.children.forEach((performanceCriteria) => {
                const completion = completionData.find(
                  (c) => c.page_key === performanceCriteria.translation_key
                );
                if (completion) {
                  performanceCriteria.completion_status = completion.completion_status;
                  performanceCriteria.completion_status_updated_at =
                    completion.updated_at;
                } else {
                  performanceCriteria.completion_status = "unknown";
                  performanceCriteria.completion_status_updated_at = "";
                }
              });
            });

            this.competenceProfilePages.set(userId, competenceProfilePage);
          }
        }
      }
    },
  },
});
