import { lens } from '@dhmk/zustand-lens';
import { SetStateAction } from 'react';
import { BusinessInfo, UserFavorite, UserInfo } from './types';
import { StorageKeys } from '@/shared/constants/local-storage';

export interface UserInfoState {
  userInfo: UserInfo;
  setUserInfo: (update: SetStateAction<Partial<UserInfo>>) => void;
  resetUserInfo: () => void;
  businessInfo: BusinessInfo;
  setBusinessInfo: (update: SetStateAction<Partial<BusinessInfo>>) => void;

  userFavorite: Array<UserFavorite>;
  setUserFavorite: (update: SetStateAction<Array<UserFavorite>>) => void;
  userMids: Array<string>;
  userEmails: Array<string>;
  setUserMids: (update: SetStateAction<Array<string>>) => void;
  setUserEmails: (update: SetStateAction<Array<string>>) => void;
  selectOptionsMids: Array<Record<string, string>>;
  selectOptionsMidsWithoutGids: Array<Record<string, string>>;
  setSelectOptionsMids: (update: SetStateAction<Array<Record<string, string>>>) => void;
  setSelectOptionsMidsWithoutGids: (update: SetStateAction<Array<Record<string, string>>>) => void;
  selectOptionsEmails: Array<Record<string, string>>;
  setSelectOptionsEmails: (update: SetStateAction<Array<Record<string, string>>>) => void;
  mid: string;
  setMid: (update: SetStateAction<string>) => void;
  email: string;
  setEmail: (update: SetStateAction<string>) => void;
  firstAccess: boolean;
  setFirstAccess: (update: SetStateAction<boolean>) => void;
};

const initialUserInfoState = {
  userInfo: {} as UserInfo,
  businessInfo: {} as BusinessInfo,
  userFavorite: [] as Array<UserFavorite>,
  userMids: [] as Array<string>,
  userEmails: [] as Array<string>,
  selectOptionsMids: [] as Array<Record<string, string>>,
  selectOptionsMidsWithoutGids: [] as Array<Record<string, string>>,
  selectOptionsEmails: [] as Array<Record<string, string>>,
  mid: '' as string,
  email: '' as string,
  firstAccess: true as boolean,
} as UserInfoState;

export const createUserInfoStore = lens<UserInfoState>((set, get) => ({
  ...initialUserInfoState,
  setUserInfo: (update) => {
    set((state: UserInfoState) => {
      const newUserInfo = (typeof update === 'function')
        ? update(state.userInfo): update;
      return {
        ...state,
        userInfo: {
          ...state.userInfo,
          ...newUserInfo
        },
      };
    });
  },
  setBusinessInfo: (update) => {
    set((state: UserInfoState) => {
      const newBusinessInfo = (typeof update === 'function')
        ? update(state.businessInfo): update;
      return {
        ...state,
        businessInfo: {
          ...state.businessInfo,
          ...newBusinessInfo
        },
      };
    });
  },
  resetUserInfo: () => {
    window.localStorage.removeItem(StorageKeys.TokenType);
    window.localStorage.removeItem(StorageKeys.AccessToken);
    window.localStorage.removeItem(StorageKeys.RefreshToken);
    window.localStorage.removeItem(StorageKeys.AccessTokenExpiresIn);
    window.localStorage.removeItem(StorageKeys.RefreshTokenExpiresIn);
    window.localStorage.removeItem(StorageKeys.MenuGrants);
    window.localStorage.removeItem(StorageKeys.Usrid);
    window.localStorage.removeItem(StorageKeys.ClientAddressIP);
    window.localStorage.removeItem(StorageKeys.Requires2FA);
    set(initialUserInfoState);
  },
  setUserFavorite: (update) => {
    set((state: UserInfoState) => {
      const newUserFavorite = (typeof update === 'function')
        ? update(state.userFavorite): update;
      return {
        ...state,
        userFavorite: [
          ...newUserFavorite
        ],
      };
    });
  },
  setUserMids: (update) => {
    set((state: UserInfoState) => {
      const newUserMids = (typeof update === 'function')
        ? update(state.userMids): update;
      return {
        ...state,
        userMids: [
          ...state.userMids,
          ...newUserMids
        ],
      };
    });
  },
  setUserEmails: (update) => {
    set((state: UserInfoState) => {
      const newUserEmails = (typeof update === 'function')
        ? update(state.userEmails): update;
      return {
        ...state,
        userEmails: [
          ...state.userEmails,
          ...newUserEmails
        ],
      };
    });
  },
  setSelectOptionsMids: (update) => {
    set((state: UserInfoState) => {
      const newSelectOptionsMids = (typeof update === 'function')
        ? update(state.selectOptionsMids): update;
      return {
        ...state,
        selectOptionsMids: [
          ...newSelectOptionsMids
        ],
      };
    });
  },
  setSelectOptionsMidsWithoutGids: (update) => {
    set((state: UserInfoState) => {
      const newSelectOptionsMidsWithoutGids = (typeof update === 'function')
        ? update(state.selectOptionsMidsWithoutGids): update;
      return {
        ...state,
        selectOptionsMidsWithoutGids: [
          ...newSelectOptionsMidsWithoutGids
        ],
      };
    });
  },
  setSelectOptionsEmails: (update) => {
    set((state: UserInfoState) => {
      const newSelectOptionsEmails = (typeof update === 'function')
        ? update(state.selectOptionsEmails): update;
      return {
        ...state,
        selectOptionsEmails: [
          ...newSelectOptionsEmails
        ],
      };
    });
  },
  setMid: (update) => {
    set((state: UserInfoState) => {
      const newMid = (typeof update === 'function')
        ? update(state.mid): update;
      return {
        ...state,
        mid: newMid
      }
    });
  },
  setEmail: (update) => {
    set((state: UserInfoState) => {
      const newEmail = (typeof update === 'function')
        ? update(state.email): update;
      return {
        ...state,
        email: newEmail
      }
    });
  },
  setFirstAccess: (update) => {
    set((state: UserInfoState) => {
      const newFirstAccess = (typeof update === 'function')
        ? update(state.firstAccess): update;
      return {
        ...state,
        firstAccess: newFirstAccess
      }
    });
  }
}));
