'use client';

import { useMemo, useEffect, useCallback } from 'react';
import { useSetState } from 'src/hooks/use-set-state';
import axios, { endpoints } from 'src/utils/axios';
import { STORAGE_KEY, REFRESH_STORAGE_KEY } from './constant';
import { AuthContext } from '../auth-context';
import { setSession, isValidToken } from './utils';
import { refreshAccessToken } from './action';

export function AuthProvider({ children }) {
  const { state, setState } = useSetState({
    user: null,
    loading: true,
  });

  const checkUserSession = useCallback(async () => {
    try {
      let accessToken = localStorage.getItem(STORAGE_KEY);

      if (accessToken && isValidToken(accessToken)) {
        setSession(accessToken);
      } else {
        // Пробуем обновить через refresh token
        try {
          accessToken = await refreshAccessToken();
        } catch {
          setState({ user: null, loading: false });
          return;
        }
      }

      const res = await axios.get(endpoints.auth.me);
      const userData = res.data?.data || res.data;

      if (!userData || typeof userData !== 'object' || Array.isArray(userData)) {
        throw new Error('Invalid user data format');
      }

      setState({ user: { ...userData, accessToken }, loading: false });
    } catch (error) {
      console.error('[Auth Debug]:', error);
      setState({ user: null, loading: false });
    }
  }, [setState]);

  useEffect(() => {
    checkUserSession();
  }, [checkUserSession]);

  const checkAuthenticated = state.user ? 'authenticated' : 'unauthenticated';
  const status = state.loading ? 'loading' : checkAuthenticated;

  const memoizedValue = useMemo(
    () => ({
      user: state.user
        ? {
            ...state.user,
            role: state.user?.role ?? 'client',
          }
        : null,
      checkUserSession,
      loading: status === 'loading',
      authenticated: status === 'authenticated',
      unauthenticated: status === 'unauthenticated',
    }),
    [checkUserSession, state.user, status]
  );

  return <AuthContext.Provider value={memoizedValue}>{children}</AuthContext.Provider>;
}
