import {
  articlesStore,
  Language,
  authInstance,
  languageInstance,
  mediaStore,
  selectedCityStore,
} from "@shared";
import { makeAutoObservable, runInAction } from "mobx";

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

type SightLanguageInfo = {
  name: string;
  short_name: string;
  address: string;
  left: {
    heading: string;
    body: string;
    media: MediaItem[];
  };
  right: { id: number; heading: string; body: string; media: MediaItem[] }[];
};

type SightCommonInfo = {
  city_id: number;
  city: string;
  latitude: number;
  longitude: number;
  is_default_icon: boolean;
  thumbnail: string | null;
  icon: string | null;
  alt_icon: string | null;
  watermark_lu: string | null;
  watermark_rd: string | null;
  left_article: number;
  preview_media: string | null;
  video_preview: string | null;
  preview_font_size?: number;
};

type SightBaseInfo = SightCommonInfo & {
  [key in Language]: SightLanguageInfo;
};

const initialSightState: SightBaseInfo = {
  city_id: 0,
  city: "",
  latitude: 0,
  longitude: 0,
  is_default_icon: false,
  thumbnail: null,
  icon: null,
  alt_icon: null,
  watermark_lu: null,
  watermark_rd: null,
  left_article: 0,
  preview_media: null,
  video_preview: null,
  ru: {
    name: "",
    short_name: "",
    address: "",
    left: { heading: "", body: "", media: [] },
    right: [],
  },
  en: {
    name: "",
    short_name: "",
    address: "",
    left: { heading: "", body: "", media: [] },
    right: [],
  },
  zh: {
    name: "",
    short_name: "",
    address: "",
    left: { heading: "", body: "", media: [] },
    right: [],
  },
};

class CreateSightStore {
  sight: SightBaseInfo = JSON.parse(JSON.stringify(initialSightState));

  uploadMediaOpen = false;
  setUploadMediaOpen = (open: boolean) => {
    this.uploadMediaOpen = open;
  };
  fileToUpload: File | null = null;
  setFileToUpload = (file: File | null) => {
    this.fileToUpload = file;
  };

  constructor() {
    makeAutoObservable(this);
  }

  createNewRightArticle = async () => {
    const articleRuData = {
      heading: "Новый заголовок (RU)",
      body: "Новый текст (RU)",
    };
    const articleEnData = {
      heading: "New Heading (EN)",
      body: "New Text (EN)",
    };
    const articleZhData = {
      heading: "Новый заголовок (ZH)",
      body: "Новый текст (ZH)",
    };

    try {
      this.needLeaveAgree = true;
      const articleRes = await authInstance.post("/article", {
        translations: {
          heading: {
            ru: articleRuData.heading,
            en: articleEnData.heading,
            zh: articleZhData.heading,
          },
          body: {
            ru: articleRuData.body,
            en: articleEnData.body,
            zh: articleZhData.body,
          },
        },
        ...(selectedCityStore.selectedCityId ? { city_id: selectedCityStore.selectedCityId } : {}),
      });
      const { id } = articleRes.data;

      runInAction(() => {
        const newArticleEntry = { id, media: [] };
        this.sight.ru.right.push({ ...newArticleEntry, ...articleRuData });
        this.sight.en.right.push({ ...newArticleEntry, ...articleEnData });
        this.sight.zh.right.push({ ...newArticleEntry, ...articleZhData });
      });
      return id;
    } catch (error) {
      console.error("Error creating new right article:", error);
      throw error;
    }
  };

  linkExistingRightArticle = async (articleId: number) => {
    try {
      const ruData = await languageInstance("ru").get(`/article/${articleId}`);
      const enData = await languageInstance("en").get(`/article/${articleId}`);
      const zhData = await languageInstance("zh").get(`/article/${articleId}`);
      const mediaRes = await authInstance.get(`/article/${articleId}/media`);
      const mediaData: MediaItem[] = mediaRes.data || [];

      runInAction(() => {
        this.sight.ru.right.push({
          id: articleId,
          heading: ruData.data.heading,
          body: ruData.data.body,
          media: mediaData,
        });
        this.sight.en.right.push({
          id: articleId,
          heading: enData.data.heading,
          body: enData.data.body,
          media: mediaData,
        });
        this.sight.zh.right.push({
          id: articleId,
          heading: zhData.data.heading,
          body: zhData.data.body,
          media: mediaData,
        });
      });

      return articleId;
    } catch (error) {
      console.error("Error linking existing right article:", error);
      throw error;
    }
  };

  updateRightArticleInfo = (
    index: number,
    language: Language,
    heading: string,
    body: string,
  ) => {
    if (this.sight[language].right[index]) {
      this.sight[language].right[index].heading = heading;
      this.sight[language].right[index].body = body;
    }
  };

  unlinkRightAritcle = (articleId: number) => {
    runInAction(() => {
      this.sight.ru.right = this.sight.ru.right.filter(
        (article) => article.id !== articleId,
      );
      this.sight.en.right = this.sight.en.right.filter(
        (article) => article.id !== articleId,
      );
      this.sight.zh.right = this.sight.zh.right.filter(
        (article) => article.id !== articleId,
      );
    });
  };

  deleteRightArticle = async (articleId: number) => {
    try {
      await authInstance.delete(`/article/${articleId}`);
      runInAction(() => {
        this.sight.ru.right = this.sight.ru.right.filter(
          (article) => article.id !== articleId,
        );
        this.sight.en.right = this.sight.en.right.filter(
          (article) => article.id !== articleId,
        );
        this.sight.zh.right = this.sight.zh.right.filter(
          (article) => article.id !== articleId,
        );
      });
    } catch (error) {
      console.error("Error deleting right article:", error);
      throw error;
    }
  };

  createLinkWithRightArticle = async (media: MediaItem, articleId: number) => {
    try {
      await authInstance.post(`/article/${articleId}/media`, {
        media_id: media.id,
        media_order: 1,
      });
      runInAction(() => {
        (["ru", "en", "zh"] as Language[]).forEach((lang) => {
          const article = this.sight[lang].right.find(
            (a) => a.id === articleId,
          );
          if (article) {
            if (!article.media) article.media = [];
            article.media.unshift(media);
          }
        });
      });
    } catch (error) {
      console.error("Error linking media to right article:", error);
      throw error;
    }
  };

  deleteRightArticleMedia = async (articleId: number, mediaId: string) => {
    try {
      await authInstance.delete(`/article/${articleId}/media`, {
        data: { media_id: mediaId },
      });
      runInAction(() => {
        (["ru", "en", "zh"] as Language[]).forEach((lang) => {
          const article = this.sight[lang].right.find(
            (a) => a.id === articleId,
          );
          if (article && article.media) {
            article.media = article.media.filter((m) => m.id !== mediaId);
          }
        });
      });
    } catch (error) {
      console.error("Error deleting media from right article:", error);
      throw error;
    }
  };

  updateLeftInfo = (language: Language, heading: string, body: string) => {
    this.sight[language].left.heading = heading;
    this.sight[language].left.body = body;
  };

  unlinkLeftArticle = () => {
    /* ... your existing logic ... */
    this.sight.left_article = 0;
    this.sight.ru.left = { heading: "", body: "", media: [] };
    this.sight.en.left = { heading: "", body: "", media: [] };
    this.sight.zh.left = { heading: "", body: "", media: [] };
  };

  updateLeftArticle = async (articleId: number) => {
    /* ... your existing logic ... */
    this.sight.left_article = articleId;
    if (articleId) {
      const [ruArticleData, enArticleData, zhArticleData, mediaData] =
        await Promise.all([
          languageInstance("ru").get(`/article/${articleId}`),
          languageInstance("en").get(`/article/${articleId}`),
          languageInstance("zh").get(`/article/${articleId}`),
          authInstance.get(`/article/${articleId}/media`),
        ]);
      runInAction(() => {
        this.sight.ru.left = {
          heading: ruArticleData.data.heading,
          body: ruArticleData.data.body,
          media: mediaData.data || [],
        };
        this.sight.en.left = {
          heading: enArticleData.data.heading,
          body: enArticleData.data.body,
          media: mediaData.data || [],
        };
        this.sight.zh.left = {
          heading: zhArticleData.data.heading,
          body: zhArticleData.data.body,
          media: mediaData.data || [],
        };
      });
    } else {
      this.unlinkLeftArticle();
    }
  };

  deleteLeftArticle = async (articleId: number) => {
    /* ... your existing logic ... */
    await authInstance.delete(`/article/${articleId}`);

    runInAction(() => {
      articlesStore.articles.ru = articlesStore.articles.ru.filter(
        (article) => article.id !== articleId,
      );
      articlesStore.articles.en = articlesStore.articles.en.filter(
        (article) => article.id !== articleId,
      );
      articlesStore.articles.zh = articlesStore.articles.zh.filter(
        (article) => article.id !== articleId,
      );
    });
    this.unlinkLeftArticle();
  };

  createLeftArticle = async () => {
    /* ... your existing logic to create a new left article (placeholder or DB) ... */
    const ruName = (this.sight.ru.name || "").trim();
    const enName = (this.sight.en.name || "").trim();
    const zhName = (this.sight.zh.name || "").trim();

    const hasAnyName = !!(ruName || enName || zhName);

    const response = await languageInstance("ru").post("/article", {
      heading: hasAnyName ? ruName : "",
      body: "",
      ...(selectedCityStore.selectedCityId ? { city_id: selectedCityStore.selectedCityId } : {}),
    });
    const newLeftArticleId = response.data.id;

    await languageInstance("en").patch(`/article/${newLeftArticleId}`, {
      heading: hasAnyName ? enName : "",
      body: "",
    });
    await languageInstance("zh").patch(`/article/${newLeftArticleId}`, {
      heading: hasAnyName ? zhName : "",
      body: "",
    });

    runInAction(() => {
      this.sight.left_article = newLeftArticleId;
      this.sight.ru.left = {
        heading: hasAnyName ? ruName : "",
        body: "",
        media: [],
      };
      this.sight.en.left = {
        heading: hasAnyName ? enName : "",
        body: "",
        media: [],
      };
      this.sight.zh.left = {
        heading: hasAnyName ? zhName : "",
        body: "",
        media: [],
      };

      articlesStore.articles.ru.push({
        id: newLeftArticleId,
        heading: hasAnyName ? ruName : "",
        body: "",
        service_name: hasAnyName ? ruName : "",
      });
      articlesStore.articles.en.push({
        id: newLeftArticleId,
        heading: hasAnyName ? enName : "",
        body: "",
        service_name: hasAnyName ? enName : "",
      });
      articlesStore.articles.zh.push({
        id: newLeftArticleId,
        heading: hasAnyName ? zhName : "",
        body: "",
        service_name: hasAnyName ? zhName : "",
      });
    });
    return newLeftArticleId;
  };

  setNewLeftArticlePlaceholder = () => {
    this.sight.left_article = 10000000;
    this.sight.ru.left = {
      heading: "Новая левая статья",
      body: "Заполните контентом",
      media: [],
    };
    this.sight.en.left = {
      heading: "New Left Article",
      body: "Fill with content",
      media: [],
    };
    this.sight.zh.left = {
      heading: "新的左侧文章",
      body: "填写内容",
      media: [],
    };
  };

  linkPreviewMedia = (mediaId: string) => {
    this.sight.preview_media = mediaId;
  };

  unlinkPreviewMedia = () => {
    this.sight.preview_media = null;
  };

  clearCreateSight = () => {
    this.needLeaveAgree = false;
    this.sight = JSON.parse(JSON.stringify(initialSightState));
  };

  updateSightInfo = (
    content: Partial<SightLanguageInfo | SightCommonInfo>,
    language?: Language,
  ) => {
    this.needLeaveAgree = true;
    if (language) {
      this.sight[language] = { ...this.sight[language], ...content };
    } else {
      this.sight = { ...this.sight, ...(content as Partial<SightCommonInfo>) };
    }
  };

  createSight = async (primaryLanguage: Language) => {
    let finalLeftArticleId = this.sight.left_article;

    if (this.sight.left_article === 10000000) {
      const res = await languageInstance("ru").post("/article", {
        heading: this.sight.ru.left.heading,
        body: this.sight.ru.left.body,
        ...(selectedCityStore.selectedCityId ? { city_id: selectedCityStore.selectedCityId } : {}),
      });
      finalLeftArticleId = res.data.id;
      await languageInstance("en").patch(`/article/${finalLeftArticleId}`, {
        heading: this.sight.en.left.heading,
        body: this.sight.en.left.body,
      });
      await languageInstance("zh").patch(`/article/${finalLeftArticleId}`, {
        heading: this.sight.zh.left.heading,
        body: this.sight.zh.left.body,
      });
    } else if (
      this.sight.left_article !== 0 &&
      this.sight.left_article !== null
    ) {
      await languageInstance("ru").patch(
        `/article/${this.sight.left_article}`,
        { heading: this.sight.ru.left.heading, body: this.sight.ru.left.body },
      );
      await languageInstance("en").patch(
        `/article/${this.sight.left_article}`,
        { heading: this.sight.en.left.heading, body: this.sight.en.left.body },
      );
      await languageInstance("zh").patch(
        `/article/${this.sight.left_article}`,
        { heading: this.sight.zh.left.heading, body: this.sight.zh.left.body },
      );
    }

    for (const lang of ["ru", "en", "zh"] as Language[]) {
      for (const article of this.sight[lang].right) {
        if (article.id == 0 || article.id == null) {
          continue;
        }
        await languageInstance(lang).patch(`/article/${article.id}`, {
          heading: article.heading,
          body: article.body,
        });
      }
    }
    const rightArticleIdsForLink = this.sight[primaryLanguage].right.map(
      (a) => a.id,
    );

    const sightPayload = {
      city_id: this.sight.city_id,
      city: this.sight.city,
      latitude: this.sight.latitude,
      longitude: this.sight.longitude,
      is_default_icon: this.sight.is_default_icon,
      name: (this.sight[primaryLanguage].name || "").trim(),
      short_name: (this.sight[primaryLanguage].short_name || "").trim(),
      address: this.sight[primaryLanguage].address,
      thumbnail: this.sight.thumbnail,
      icon: this.sight.icon,
      alt_icon: this.sight.alt_icon,
      watermark_lu: this.sight.watermark_lu,
      watermark_rd: this.sight.watermark_rd,
      left_article: finalLeftArticleId === 0 ? null : finalLeftArticleId,
      preview_media: this.sight.preview_media,
      video_preview: this.sight.video_preview,
      preview_font_size: this.sight.preview_font_size,
    };

    const response = await languageInstance(primaryLanguage).post(
      "/sight",
      sightPayload,
    );
    const newSightId = response.data.id;

    const otherLanguages = (["ru", "en", "zh"] as Language[]).filter(
      (l) => l !== primaryLanguage,
    );
    for (const lang of otherLanguages) {
      await languageInstance(lang).patch(`/sight/${newSightId}`, {
        city_id: this.sight.city_id,
        city: this.sight.city,
        latitude: this.sight.latitude,
        longitude: this.sight.longitude,
        is_default_icon: this.sight.is_default_icon,
        name: (this.sight[lang].name || "").trim(),
        short_name: (this.sight[lang].short_name || "").trim(),
        address: this.sight[lang].address,
        thumbnail: this.sight.thumbnail,
        icon: this.sight.icon,
        alt_icon: this.sight.alt_icon,
        watermark_lu: this.sight.watermark_lu,
        watermark_rd: this.sight.watermark_rd,
        left_article: finalLeftArticleId === 0 ? null : finalLeftArticleId,
        preview_media: this.sight.preview_media,
        video_preview: this.sight.video_preview,
      });
    }

    for (let i = 0; i < rightArticleIdsForLink.length; i++) {
      await authInstance.post(`/sight/${newSightId}/article`, {
        article_id: rightArticleIdsForLink[i],
        page_num: i + 1,
      });
    }

    runInAction(() => {
      this.needLeaveAgree = false;
    });

    return newSightId;
  };

  uploadMedia = async (
    filename: string,
    type: number,
    file: File,
    media_name?: string,
  ): Promise<MediaItem> => {
    const formData = new FormData();
    formData.append("file", file);
    formData.append("filename", filename);
    if (media_name) formData.append("media_name", media_name);
    formData.append("type", type.toString());
    if (selectedCityStore.selectedCityId) {
      formData.append("city_id", selectedCityStore.selectedCityId.toString());
    }

    try {
      const response = await authInstance.post(`/media`, formData);
      runInAction(() => {
        this.fileToUpload = null;
        this.uploadMediaOpen = false;
      });
      mediaStore.getMedia();
      return {
        id: response.data.id,
        filename: filename,
        media_name: media_name,
        media_type: type,
      };
    } catch (error) {
      console.error("Error uploading media:", error);
      throw error;
    }
  };

  createLinkWithLeftArticle = async (media: MediaItem) => {
    if (!this.sight.left_article || this.sight.left_article === 10000000) {
      console.warn(
        "Left article not selected or is a placeholder. Cannot link media yet.",
      );

      return;
    }
    try {
      await authInstance.post(`/article/${this.sight.left_article}/media`, {
        media_id: media.id,
        media_order: (this.sight.ru.left.media?.length || 0) + 1,
      });
      runInAction(() => {
        (["ru", "en", "zh"] as Language[]).forEach((lang) => {
          if (!this.sight[lang].left.media) this.sight[lang].left.media = [];
          this.sight[lang].left.media.unshift(media);
        });
      });
    } catch (error) {
      console.error("Error linking media to left article:", error);
      throw error;
    }
  };

  deleteLeftArticleMedia = async (mediaId: string) => {
    if (!this.sight.left_article || this.sight.left_article === 10000000)
      return;
    try {
      await authInstance.delete(`/article/${this.sight.left_article}/media`, {
        data: { media_id: mediaId },
      });
      runInAction(() => {
        (["ru", "en", "zh"] as Language[]).forEach((lang) => {
          if (this.sight[lang].left.media) {
            this.sight[lang].left.media = this.sight[lang].left.media.filter(
              (m) => m.id !== mediaId,
            );
          }
        });
      });
    } catch (error) {
      console.error("Error deleting media from left article:", error);
      throw error;
    }
  };

  updateRightArticles = async (articles: any[]) => {
    const articlesIds = articles.map((article) => article.id);

    const sortArticles = (existing: any[]) => {
      const articleMap = new Map(
        existing.map((article) => [article.id, article]),
      );
      return articlesIds
        .map((id) => articleMap.get(id))
        .filter(
          (article): article is (typeof existing)[number] =>
            article !== undefined,
        );
    };

    this.sight.ru.right = sortArticles(this.sight.ru.right);
    this.sight.en.right = sortArticles(this.sight.en.right);
    this.sight.zh.right = sortArticles(this.sight.zh.right);

    this.needLeaveAgree = true;
  };

  needLeaveAgree = false;
  setNeedLeaveAgree = (need: boolean) => {
    this.needLeaveAgree = need;
  };
}

export const createSightStore = new CreateSightStore();
