import { usePostSetSlowMutation } from '@api/countries';
import { usePostSetDareRegionMutation } from '@api/myDARE';
import { usePostSetNmRegionMutation } from '@api/myRegions';
import React, { createContext, useContext, useState, useCallback } from 'react';
import { DareRegion, NmRegion, SlowData } from 'src/screens/InAppScreens/TravelsScreen/utils/types';
import { StoreType, storage } from 'src/storage';

const RegionContext = createContext<any>(null);

export const useRegion = () => useContext(RegionContext);

export const RegionProvider = ({ children }: { children: React.ReactNode }) => {
  const [userData, setUserData] = useState({});
  const [nmRegions, setNmRegions] = useState<NmRegion[]>([]);
  const [dareRegions, setDareRegions] = useState<DareRegion[] | null>([]);
  const [slow, setSlow] = useState<SlowData[]>([]);
  const token = storage.get('token', StoreType.STRING) as string;
  const { mutate: updateNM } = usePostSetNmRegionMutation();
  const { mutate: updateDARE } = usePostSetDareRegionMutation();
  const { mutate: updateSlow } = usePostSetSlowMutation();

  const handleUpdateNM = useCallback(
    (region: number, first: number, last: number, visits: number, quality: number) => {
      const updatedNM = {
        ...userData,
        first_visit_year: first,
        last_visit_year: last,
        best_visit_quality: quality,
        no_of_visits: visits,
        visited: visits > 0 ? true : false
      };

      const updatedNMData = {
        token,
        region,
        first,
        last,
        visits,
        quality
      };

      updateNM(updatedNMData);
      updatedNM && setUserData(updatedNM);
    },
    [userData, token]
  );

  const handleUpdateDare = useCallback(
    (region: number, visits: 0 | 1) => {
      const updatedDARE = { ...userData, visited: visits > 0 ? true : false };

      const updatedDareData = {
        token,
        region,
        visits
      };

      updateDARE(updatedDareData);
      updatedDARE && setUserData(updatedDARE);
    },
    [userData, token]
  );

  const handleUpdateSlow = useCallback(
    (id: number, v: boolean, s11: boolean, s31: boolean, s101: boolean) => {
      const updatedSlow = {
        type: 'countries',
        visited: v,
        slow11: !v ? 0 : (Number(s11) as 0 | 1),
        slow31: !v ? 0 : (Number(s31) as 0 | 1),
        slow101: !v ? 0 : (Number(s101) as 0 | 1)
      };

      const updatedSlowData = {
        token,
        id,
        v,
        s11: !v ? false : s11,
        s31: !v ? false : s31,
        s101: !v ? false : s101
      };

      updateSlow(updatedSlowData);
      setUserData(updatedSlow);
    },
    [userData, token]
  );

  const handleUpdateNMList = useCallback(
    (id: number, first: number, last: number, visits: number, quality: number) => {
      const updatedNM = nmRegions.map((item) => {
        if (item.id === id) {
          return {
            ...item,
            year: first,
            last,
            quality,
            visits
          };
        }
        return item;
      });

      const updatedNMData = {
        token,
        region: id,
        first,
        last,
        visits,
        quality
      };

      updateNM(updatedNMData);
      updatedNM && setNmRegions(updatedNM);
    },
    [nmRegions]
  );

  const handleUpdateDareList = useCallback(
    (region: number, visits: 0 | 1) => {
      const updatedDARE = dareRegions?.map((item) => {
        if (item.id === region) {
          return {
            ...item,
            visited: String(visits)
          };
        }

        return item;
      });

      const updatedDareData = {
        token,
        region,
        visits
      };

      updateDARE(updatedDareData);
      updatedDARE && setDareRegions(updatedDARE);
    },
    [dareRegions]
  );

  const handleUpdateSlowList = useCallback(
    (id: number, v: boolean, s11: boolean, s31: boolean, s101: boolean) => {
      const updatedSlow = slow?.map((item) => {
        if (item.country_id === id) {
          return {
            ...item,
            visited: Number(v) as 0 | 1,
            slow11: !v ? 0 : (Number(s11) as 0 | 1),
            slow31: !v ? 0 : (Number(s31) as 0 | 1),
            slow101: !v ? 0 : (Number(s101) as 0 | 1)
          };
        }

        return item;
      });

      const updatedSlowData = {
        token,
        id,
        v,
        s11: !v ? false : s11,
        s31: !v ? false : s31,
        s101: !v ? false : s101
      };

      updateSlow(updatedSlowData);
      updatedSlow && setSlow(updatedSlow);
    },
    [slow]
  );

  return (
    <RegionContext.Provider
      value={{
        userData,
        setUserData,
        setNmRegions,
        nmRegions,
        setDareRegions,
        dareRegions,
        handleUpdateNM,
        handleUpdateDare,
        handleUpdateNMList,
        handleUpdateDareList,
        handleUpdateSlow,
        handleUpdateSlowList,
        slow,
        setSlow
      }}
    >
      {children}
    </RegionContext.Provider>
  );
};
