import { create } from 'zustand';
import AsyncStorage from '@react-native-async-storage/async-storage';
import type { User } from '../types/auth';
import { authService } from '../services/auth';
import { setTokens, setOnRefreshFailed } from '../services/api';

const STORAGE_KEYS = {
  ACCESS_TOKEN: '@fitcrm/access_token',
  REFRESH_TOKEN: '@fitcrm/refresh_token',
  USER: '@fitcrm/user',
};

interface AuthState {
  user: User | null;
  accessToken: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  isLoading: boolean;
  error: string | null;
  login: (phone: string, password: string) => Promise<void>;
  logout: () => void;
  setTokensPair: (access: string, refresh: string) => void;
  restoreSession: () => Promise<void>;
  clearError: () => void;
}

export const useAuthStore = create<AuthState>((set, get) => {
  setOnRefreshFailed(() => {
    get().logout();
  });

  return {
    user: null,
    accessToken: null,
    refreshToken: null,
    isAuthenticated: false,
    isLoading: false,
    error: null,

    login: async (phone: string, password: string) => {
      set({ isLoading: true, error: null });
      try {
        const response = await authService.login(phone, password);

        setTokens(response.accessToken, response.refreshToken);

        await AsyncStorage.multiSet([
          [STORAGE_KEYS.ACCESS_TOKEN, response.accessToken],
          [STORAGE_KEYS.REFRESH_TOKEN, response.refreshToken],
          [STORAGE_KEYS.USER, JSON.stringify(response.user)],
        ]);

        set({
          user: response.user,
          accessToken: response.accessToken,
          refreshToken: response.refreshToken,
          isAuthenticated: true,
          isLoading: false,
        });
      } catch (err) {
        const message =
          err instanceof Error ? err.message : 'Ошибка входа';
        set({ error: message, isLoading: false });
        throw err;
      }
    },

    logout: () => {
      setTokens(null, null);
      AsyncStorage.multiRemove([
        STORAGE_KEYS.ACCESS_TOKEN,
        STORAGE_KEYS.REFRESH_TOKEN,
        STORAGE_KEYS.USER,
      ]);
      set({
        user: null,
        accessToken: null,
        refreshToken: null,
        isAuthenticated: false,
        error: null,
      });
    },

    setTokensPair: (access: string, refresh: string) => {
      setTokens(access, refresh);
      set({ accessToken: access, refreshToken: refresh });
    },

    restoreSession: async () => {
      set({ isLoading: true });
      try {
        const values = await AsyncStorage.multiGet([
          STORAGE_KEYS.ACCESS_TOKEN,
          STORAGE_KEYS.REFRESH_TOKEN,
          STORAGE_KEYS.USER,
        ]);

        const storedAccessToken = values[0][1];
        const storedRefreshToken = values[1][1];
        const storedUser = values[2][1];

        if (storedAccessToken && storedRefreshToken && storedUser) {
          const user: User = JSON.parse(storedUser);
          setTokens(storedAccessToken, storedRefreshToken);

          set({
            user,
            accessToken: storedAccessToken,
            refreshToken: storedRefreshToken,
            isAuthenticated: true,
            isLoading: false,
          });
        } else {
          set({ isLoading: false });
        }
      } catch {
        set({ isLoading: false });
      }
    },

    clearError: () => {
      set({ error: null });
    },
  };
});
