import { create } from 'zustand';
import { login as apiLogin, register as apiRegister, verifyToken, type AuthUser } from '../services/auth';

const APP_STORAGE_PREFIXES = ['hipograf_', 'hipograf.'] as const;

const removePrefixedStorageItems = (storage: Storage) => {
    const keys = Object.keys(storage);

    keys.forEach((key) => {
        if (APP_STORAGE_PREFIXES.some((prefix) => key.startsWith(prefix))) {
            storage.removeItem(key);
        }
    });
};

export const clearBrowserSessionState = () => {
    if (typeof window === 'undefined') return;

    removePrefixedStorageItems(window.localStorage);
    removePrefixedStorageItems(window.sessionStorage);
};

interface AuthState {
    token: string | null;
    user: AuthUser | null;
    isAuthenticated: boolean;
    isLoading: boolean;
    error: string | null;

    login: (identifier: string, password: string) => Promise<void>;
    register: (data: { username: string; email: string; password: string; dispName: string; role: string }) => Promise<void>;
    logout: () => void;
    loadFromStorage: () => Promise<void>;
    updateUser: (updates: Partial<AuthUser>) => void;
}

export const useAuthStore = create<AuthState>((set, _) => ({
    token: null,
    user: null,
    isAuthenticated: false,
    isLoading: true, // Start as loading so we check storage first
    error: null,

    login: async (identifier: string, password: string) => {
        set({ error: null });
        try {
            const res = await apiLogin(identifier, password);
            localStorage.setItem('hipograf_token', res.accessToken);
            localStorage.setItem('hipograf_user', JSON.stringify(res.user));
            set({
                token: res.accessToken,
                user: res.user,
                isAuthenticated: true,
                error: null,
            });
        } catch (err: unknown) {
            const msg = err instanceof Error ? err.message : 'Login failed';
            set({ error: msg });
            throw err;
        }
    },

    register: async (data) => {
        set({ error: null });
        try {
            const res = await apiRegister(data);
            localStorage.setItem('hipograf_token', res.accessToken);
            localStorage.setItem('hipograf_user', JSON.stringify(res.user));
            set({
                token: res.accessToken,
                user: res.user,
                isAuthenticated: true,
                error: null,
            });
        } catch (err: unknown) {
            const msg = err instanceof Error ? err.message : 'Registration failed';
            set({ error: msg });
            throw err;
        }
    },

    logout: () => {
        clearBrowserSessionState();
        set({
            token: null,
            user: null,
            isAuthenticated: false,
            isLoading: false,
            error: null,
        });
        window.history.replaceState({}, '', '/');
    },

    updateUser: (updates: Partial<AuthUser>) => {
        set((state) => {
            if (!state.user) return state;
            const updatedUser = { ...state.user, ...updates };
            localStorage.setItem('hipograf_user', JSON.stringify(updatedUser));
            return { user: updatedUser };
        });
    },

    loadFromStorage: async () => {
        const token = localStorage.getItem('hipograf_token');
        const userStr = localStorage.getItem('hipograf_user');

        if (!token || !userStr) {
            set({ isLoading: false });
            return;
        }

        try {
            await verifyToken();
            const user = JSON.parse(userStr) as AuthUser;
            set({
                token,
                user,
                isAuthenticated: true,
                isLoading: false,
            });
        } catch {
            // Token expired or invalid
            clearBrowserSessionState();
            set({ isLoading: false });
        }
    },
}));

