import { create } from 'zustand';
import { TOKEN_AUTH_KEY, TOKEN_EXPIRY_DURATION, TOKEN_ISSUED_DATE_KEY, USER_DATA_KEY } from '../constants';
import { AuthState } from '../interfaces/auth';
import AuthService from '../services/AuthService';

export const useAuthStore = create<AuthState>(() => ({
    isAuthenticated: false,
    token: null,
    userData: null,
}));

const login = (token: string) => {
    const issuedDate = Date.now();
    localStorage.setItem(TOKEN_AUTH_KEY, token);
    localStorage.setItem(TOKEN_ISSUED_DATE_KEY, issuedDate.toString());
    useAuthStore.setState(() => ({ isAuthenticated: true, token: token }))
}

const logout = () => {
    localStorage.removeItem(TOKEN_AUTH_KEY);
    localStorage.removeItem(USER_DATA_KEY);
    localStorage.removeItem(TOKEN_ISSUED_DATE_KEY);
    useAuthStore.setState(() => ({ isAuthenticated: false, token: null, userData: null }));
}

const initAuth = async () => {
    const token = localStorage.getItem(TOKEN_AUTH_KEY);
    const issuedDate = parseInt(localStorage.getItem(TOKEN_ISSUED_DATE_KEY) || '0', 10);
    const currentTime = Date.now();

    if (token && issuedDate) {
        if (currentTime - issuedDate < TOKEN_EXPIRY_DURATION) {
            useAuthStore.setState(() => ({ isAuthenticated: true, token: token }))
        } else {
            try {
                await refreshToken();
            } catch (error) {
                console.error('Token refresh failed:', error);
                logout();
            }
        }
    } else {
        logout()
    }
}

const refreshToken = async () => {
    const token = useAuthStore.getState().token
    if (!token) throw new Error('No token to refresh');

    try {
        const response = await AuthService.refreshToken(token)
        const newToken = response.data.access_token;
        const newIssuedDate = Date.now();
        localStorage.setItem(TOKEN_AUTH_KEY, newToken);
        localStorage.setItem(TOKEN_ISSUED_DATE_KEY, newIssuedDate.toString());
        useAuthStore.setState(() => ({ token: newToken }))
    } catch (error) {
        console.error('Failed to refresh token:', error);
        logout();
    }
}

const getUserData = () => {
    const userData = localStorage.getItem(USER_DATA_KEY)
    return userData ? JSON.parse(userData) : {}
}

const setUserData = (userData: string) => {
    const parsedData = JSON.parse(userData)
    localStorage.setItem(USER_DATA_KEY, userData)
    useAuthStore.setState(() => ({ userData: parsedData }))
}

export {
    getUserData,
    setUserData,
    refreshToken,
    initAuth,
    login,
    logout,
}