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

export type Country = {
  code: string;
  name: string;
};

export type CashedCountries = {
  ru: {
    data: Country[];
    loaded: boolean;
  };
  en: {
    data: Country[];
    loaded: boolean;
  };
  zh: {
    data: Country[];
    loaded: boolean;
  };
};

export type CashedCountry = {
  ru: Country | null;
  en: Country | null;
  zh: Country | null;
};

class CountryStore {
  countries: CashedCountries = {
    ru: {
      data: [],
      loaded: false,
    },
    en: {
      data: [],
      loaded: false,
    },
    zh: {
      data: [],
      loaded: false,
    },
  };

  country: Record<string, CashedCountry> = {};

  constructor() {
    makeAutoObservable(this);
  }

  getCountries = async (language: keyof CashedCountries) => {
    if (this.countries[language].loaded) {
      return;
    }

    const response = await languageInstance(language).get(`/country`);

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

  getCountry = async (code: string, language: keyof CashedCountries) => {
    const response = await languageInstance(language).get(`/country/${code}`);

    runInAction(() => {
      if (!this.country[code]) {
        this.country[code] = {
          ru: null,
          en: null,
          zh: null,
        };
      }
      this.country[code][language] = response.data;
    });

    return response.data;
  };

  deleteCountry = async (code: string) => {
    await authInstance.delete(`/country/${code}`);

    runInAction(() => {
      for (const lang of ["ru", "en", "zh"]) {
        this.countries[lang as keyof CashedCountries].data = this.countries[
          lang as keyof CashedCountries
        ].data.filter((country) => country.code !== code);
      }

      this.country[code] = {
        ru: null,
        en: null,
        zh: null,
      };
    });
  };

  createCountryData = {
    code: "",
    ru: {
      name: "",
    },
    en: {
      name: "",
    },
    zh: {
      name: "",
    },
  };
  setCountryData = (
    code: string,
    name: string,
    language: keyof CashedCountries
  ) => {
    this.createCountryData = {
      ...this.createCountryData,
      code: code,
      [language]: {
        name: name,
      },
    };
  };

  createCountry = async () => {
    const { code } = this.createCountryData;
    const { language } = languageStore;
    const { name } = this.createCountryData[language as keyof CashedCountries];

    if (code && this.createCountryData[language].name) {
      await languageInstance(language as Language).post("/country", {
        code: code,
        name: name.trim(),
      });

      runInAction(() => {
        this.countries[language as keyof CashedCountries].data = [
          ...this.countries[language as keyof CashedCountries].data,
          { code: code, name: name },
        ];
      });

      for (const secondaryLanguage of ["ru", "en", "zh"].filter(
        (l) => l !== language
      )) {
        const { name } =
          this.createCountryData[secondaryLanguage as keyof CashedCountries];

        if (name) {
          await languageInstance(secondaryLanguage as Language).patch(
            `/country/${code}`,
            {
              name: name.trim(),
            }
          );
        }
        runInAction(() => {
          this.countries[secondaryLanguage as keyof CashedCountries].data = [
            ...this.countries[secondaryLanguage as keyof CashedCountries].data,
            { code: code, name: name },
          ];
        });
      }
    }

    runInAction(() => {
      this.createCountryData = {
        code: "",
        ru: {
          name: "",
        },
        en: {
          name: "",
        },
        zh: {
          name: "",
        },
      };
    });
  };

  editCountryData = {
    ru: {
      name: "",
    },
    en: {
      name: "",
    },
    zh: {
      name: "",
    },
  };

  setEditCountryData = (name: string, language: keyof CashedCountries) => {
    this.editCountryData = {
      ...this.editCountryData,
      [language]: {
        name: name,
      },
    };
  };

  editCountry = async (code: string) => {
    for (const language of ["ru", "en", "zh"]) {
      const { name } = this.editCountryData[language as keyof CashedCountries];

      if (name) {
        await languageInstance(language as Language).patch(`/country/${code}`, {
          name: name.trim(),
        });

        runInAction(() => {
          if (this.country[code]) {
            this.country[code][language as keyof CashedCountries] = {
              code,
              name,
            };
          }
          if (this.countries[language as keyof CashedCountries]) {
            this.countries[language as keyof CashedCountries].data =
              this.countries[language as keyof CashedCountries].data.map(
                (country) => (country.code === code ? { code, name } : country)
              );
          }
        });
      }
    }
  };
}

export const countryStore = new CountryStore();
