import {
  authInstance,
  editSightStore,
  Language,
  languageStore,
  languageInstance,
} from "@shared";
import { computed, makeAutoObservable, runInAction } from "mobx";

export type Article = {
  id: number;
  heading: string;
  body: string;
  service_name: string;
  city_id?: number | null;
  ru?: {
    heading: string;
    body: string;
  };
  en?: {
    heading: string;
    body: string;
  };
  zh?: {
    heading: string;
    body: string;
  };
};

type Media = {
  id: string;
  filename: string;
  media_name: string;
  media_type: number;
};

type ArticleListCashed = {
  ru: {
    data: Article[];
    loaded: boolean;
  };
  en: {
    data: Article[];
    loaded: boolean;
  };
  zh: {
    data: Article[];
    loaded: boolean;
  };
};

type PreviewCashed = {
  ru: Article;
  en: Article;
  zh: Article;
};

type ArticlePreviewCashed = Record<string, PreviewCashed>;

class ArticlesStore {
  constructor() {
    makeAutoObservable(this);
  }

  articles: { [key in Language]: Article[] } = {
    ru: [],
    en: [],
    zh: [],
  };
  articleList: ArticleListCashed = {
    ru: {
      data: [],
      loaded: false,
    },
    en: {
      data: [],
      loaded: false,
    },
    zh: {
      data: [],
      loaded: false,
    },
  };
  articlePreview: ArticlePreviewCashed = {};
  articleData: Article | null = null;
  articleMedia: Media | null = null;
  articleLoading: boolean = false;

  getArticleList = async () => {
    const { language } = languageStore;
    if (this.articleList[language].loaded) {
      return;
    }
    const response = await authInstance.get("/article");

    runInAction(() => {
      this.articleList[language].data = response.data;
      this.articleList[language].loaded = true;
    });
  };

  getArticlePreview = async (id: number) => {
    const { language } = languageStore;
    if (this.articlePreview[id][language]) {
      return;
    }
    const response = await authInstance.get(`/article/${id}/preview`);
    this.articlePreview[id][language] = response.data;
  };

  getArticles = async (language: Language) => {
    this.articleLoading = true;

    const response = await languageInstance(language).get("/article");

    runInAction(() => {
      this.articles[language] = response.data;
    });
    this.articleLoading = false;
  };

  getArticle = async (id: number, language?: Language) => {
    this.articleLoading = true;
    let response: any;
    if (language) {
      response = await languageInstance(language).get(`/article/${id}`);
      runInAction(() => {
        if (!this.articleData) {
          this.articleData = { id, heading: "", body: "", service_name: "" };
        }
        this.articleData[language] = {
          heading: response.data.heading,
          body: response.data.body,
        };
      });
    } else {
      response = await authInstance.get(`/article/${id}`);
      runInAction(() => {
        this.articleData = response.data;
      });
    }
    return response;
    this.articleLoading = false;
  };

  getSightArticles = async (id: number) => {
    const response = await authInstance.get(`/sight/${id}/article`);

    runInAction(() => {
      editSightStore.sight[languageStore.language].right = response.data;
    });
  };

  getArticleMedia = async (id: number) => {
    const response = await authInstance.get(`/article/${id}/media`);

    runInAction(() => {
      this.articleMedia = response.data[0];
    });
  };

  getArticleByArticleId = computed(() => {
    if (editSightStore.sight.common.left_article) {
      const language = languageStore.language;
      const foundArticle = this.articles[language].find(
        (a) => a.id == editSightStore.sight.common.left_article
      );
      editSightStore.sight[language].left.heading = foundArticle?.heading ?? "";
      editSightStore.sight[language].left.body = foundArticle?.body ?? "";
      return foundArticle;
    }
    return null;
  });

  deleteArticles = async (ids: number[]) => {
    for (const id of ids) {
      await authInstance.delete(`/article/${id}`);
    }

    for (const id of ["ru", "en", "zh"] as Language[]) {
      runInAction(() => {
        this.articleList[id].data = this.articleList[id].data.filter(
          (article) => !ids.includes(article.id)
        );
      });
    }
  };
}

export const articlesStore = new ArticlesStore();
