import { State } from "./../index";
import { ActionContext, Module } from "vuex";
import { CalendarLight } from "../../../../types";
import { fetchCalendarLocalForUser } from "../../../Calendar/api";
import { EventInput } from "@fullcalendar/core";
import { localsToFullCalendarEvent } from "../../../Calendar/store/utils";
import { TransportExceptionInterface } from "../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
import { COLORS } from "../../../Calendar/const";

export interface CalendarLocalsState {
  locals: EventInput[];
  localsLoaded: { start: number; end: number }[];
  localsIndex: Set<string>;
  key: number;
}

type Context = ActionContext<CalendarLocalsState, State>;

export default {
  namespaced: true,
  state: (): CalendarLocalsState => ({
    locals: [],
    localsLoaded: [],
    localsIndex: new Set<string>(),
    key: 0,
  }),
  getters: {
    isLocalsLoaded:
      (state: CalendarLocalsState) =>
      ({ start, end }: { start: Date; end: Date }): boolean => {
        for (const range of state.localsLoaded) {
          if (start.getTime() === range.start && end.getTime() === range.end) {
            return true;
          }
        }

        return false;
      },
  },
  mutations: {
    addLocals(state: CalendarLocalsState, ranges: CalendarLight[]) {
      console.log("addLocals", ranges);

      const toAdd = ranges
        .map((cr) => localsToFullCalendarEvent(cr))
        .filter((r) => !state.localsIndex.has(r.id));

      toAdd.forEach((r) => {
        state.localsIndex.add(r.id);
        state.locals.push(r);
      });
      state.key = state.key + toAdd.length;
    },
    addLoaded(state: CalendarLocalsState, payload: { start: Date; end: Date }) {
      state.localsLoaded.push({
        start: payload.start.getTime(),
        end: payload.end.getTime(),
      });
    },
  },
  actions: {
    fetchLocals(
      ctx: Context,
      payload: { start: Date; end: Date },
    ): Promise<null> {
      const start = payload.start;
      const end = payload.end;

      if (ctx.rootGetters["me/getMe"] === null) {
        return Promise.resolve(null);
      }

      if (ctx.getters.isLocalsLoaded({ start, end })) {
        return Promise.resolve(ctx.getters.getRangeSource);
      }

      ctx.commit("addLoaded", {
        start: start,
        end: end,
      });

      return fetchCalendarLocalForUser(ctx.rootGetters["me/getMe"], start, end)
        .then((remotes: CalendarLight[]) => {
          // to be add when reactivity problem will be solve ?
          //ctx.commit('addRemotes', remotes);
          const inputs = remotes
            .map((cr) => localsToFullCalendarEvent(cr))
            .map((cr) => ({
              ...cr,
              backgroundColor: COLORS[0],
              textColor: "black",
              editable: false,
            }));
          ctx.commit("calendarRanges/addExternals", inputs, {
            root: true,
          });
          return Promise.resolve(null);
        })
        .catch((e: TransportExceptionInterface) => {
          console.error(e);

          return Promise.resolve(null);
        });
    },
  },
} as Module<CalendarLocalsState, State>;
