import { defineStore } from "pinia";
import type { CreateNewsletterViewModel, SyncNewsletterViewModel } from "@/viewmodels/admin/club/newsletter/newsletter.models";
import { http } from "@/serverCom";
import type { AxiosResponse } from "axios";
import type { NewsletterViewModel } from "@/viewmodels/admin/club/newsletter/newsletter.models";
import cloneDeep from "lodash.clonedeep";
import isEqual from "lodash.isequal";
import difference from "lodash.difference";

export const useNewsletterStore = defineStore("newsletter", {
  state: () => {
    return {
      newsletters: [] as Array<NewsletterViewModel & { tab_pos: number }>,
      totalCount: 0 as number,
      loading: "loading" as "loading" | "fetched" | "failed",
      activeNewsletter: null as number | null,
      activeNewsletterObj: null as NewsletterViewModel | null,
      origin: null as NewsletterViewModel | null,
      loadingActive: "loading" as "loading" | "fetched" | "failed",
      syncingNewsletter: "synced" as "synced" | "syncing" | "detectedChanges" | "failed",
    };
  },
  getters: {
    detectedChangeNewsletter: (state) =>
      !isEqual(state.origin, state.activeNewsletterObj) && state.syncingNewsletter != "syncing",
  },
  actions: {
    setNewsletterSyncingState(state: "synced" | "syncing" | "detectedChanges" | "failed") {
      this.syncingNewsletter = state;
    },
    fetchNewsletters(offset = 0, count = 25, clear = false) {
      if (clear) this.newsletters = [];
      this.loading = "loading";
      http
        .get(`/admin/newsletter?offset=${offset}&count=${count}`)
        .then((result) => {
          this.totalCount = result.data.total;
          result.data.newsletters
            .filter((elem: NewsletterViewModel) => this.newsletters.findIndex((m) => m.id == elem.id) == -1)
            .map((elem: NewsletterViewModel, index: number): NewsletterViewModel & { tab_pos: number } => {
              return {
                ...elem,
                tab_pos: index + offset,
              };
            })
            .forEach((elem: NewsletterViewModel & { tab_pos: number }) => {
              this.newsletters.push(elem);
            });
          this.loading = "fetched";
        })
        .catch((err) => {
          this.loading = "failed";
        });
    },
    fetchNewsletterByActiveId() {
      this.loadingActive = "loading";
      http
        .get(`/admin/newsletter/${this.activeNewsletter}`)
        .then((res) => {
          this.origin = res.data;
          this.activeNewsletterObj = cloneDeep(this.origin);
          this.loadingActive = "fetched";
        })
        .catch((err) => {
          this.loadingActive = "failed";
        });
    },
    fetchNewsletterById(id: number) {
      return http.get(`/admin/newsletter/${id}`);
    },
    async createNewsletter(newsletter: CreateNewsletterViewModel): Promise<AxiosResponse<any, any>> {
      const result = await http.post(`/admin/newsletter`, {
        title: newsletter.title,
      });
      this.fetchNewsletters();
      return result;
    },
    async synchronizeActiveNewsletter(): Promise<void> {
      if (this.origin == null || this.activeNewsletterObj == null) return;

      this.syncingNewsletter = "syncing";
      await http
        .patch(`/admin/newsletter/${this.origin.id}/synchronize`, {
          title: this.activeNewsletterObj.title,
          description: this.activeNewsletterObj.description,
          newsletterTitle: this.activeNewsletterObj.newsletterTitle,
          newsletterText: this.activeNewsletterObj.newsletterText,
          newsletterSignatur: this.activeNewsletterObj.newsletterSignatur,
          recipientsByQueryId: this.activeNewsletterObj.recipientsByQueryId,
        })
        .then((res) => {
          this.syncingNewsletter = "synced";
        })
        .catch((err) => {
          this.syncingNewsletter = "failed";
        });
      this.fetchNewsletterById(this.origin.id)
        .then((res) => {
          this.origin = res.data;
          if (this.detectedChangeNewsletter) this.syncingNewsletter = "detectedChanges";
        })
        .catch((err) => {});
    },
  },
});
