Загрузка данных


// services/authApi.ts
import type { User, AuthResponse, LoginCredentials, RegisterCredentials } from '../types';

// БАЗА ДАННЫХ ПОЛЬЗОВАТЕЛЕЙ (теперь с хранением в localStorage)
const USERS_KEY = 'spreadsheet_users';

// ЗАГРУЗКА ПОЛЬЗОВАТЕЛЕЙ ИЗ localStorage
const loadUsers = (): Map<string, { id: string; name: string; email: string; password: string }> => {
    const stored = localStorage.getItem(USERS_KEY);
    if (!stored) {
        // СОЗДАЁМ ТЕСТОВОГО ПОЛЬЗОВАТЕЛЯ ПРИ ПЕРВОМ ЗАПУСКЕ
        const defaultUsers = new Map();
        defaultUsers.set('test@example.com', {
            id: 'user_1',
            name: 'Тестовый Пользователь',
            email: 'test@example.com',
            password: 'password123'
        });
        return defaultUsers;
    }
    const obj = JSON.parse(stored);
    return new Map(Object.entries(obj));
};

// СОХРАНЕНИЕ ПОЛЬЗОВАТЕЛЕЙ
const saveUsers = (users: Map<string, any>) => {
    const obj = Object.fromEntries(users);
    localStorage.setItem(USERS_KEY, JSON.stringify(obj));
};

// ПОЛУЧАЕМ НАЧАЛЬНУЮ БАЗУ
let usersDB = loadUsers();

// ПЕРИОДИЧЕСКИ СОХРАНЯЕМ ИЗМЕНЕНИЯ
const persistUsers = () => {
    saveUsers(usersDB);
};

// ГЕНЕРАЦИЯ ТОКЕНОВ
const generateAccessToken = (userId: string): string => {
    const payload = { userId, exp: Date.now() + 15 * 60 * 1000 };
    return btoa(JSON.stringify(payload));
};

const generateRefreshToken = (userId: string): string => {
    const payload = { userId, exp: Date.now() + 7 * 24 * 60 * 60 * 1000 };
    return btoa(JSON.stringify(payload));
};

export const authApi = {
    async register(credentials: RegisterCredentials): Promise<AuthResponse> {
        await new Promise(resolve => setTimeout(resolve, 500));
        
        if (usersDB.has(credentials.email)) {
            throw new Error('Пользователь с таким email уже существует');
        }
        
        const newUser = {
            id: `user_${Date.now()}`,
            name: credentials.name,
            email: credentials.email,
            password: credentials.password
        };
        usersDB.set(credentials.email, newUser);
        persistUsers();
        
        const accessToken = generateAccessToken(newUser.id);
        const refreshToken = generateRefreshToken(newUser.id);
        
        localStorage.setItem('refreshToken', refreshToken);
        localStorage.setItem('currentUserId', newUser.id);
        
        return {
            user: { id: newUser.id, name: newUser.name, email: newUser.email },
            accessToken
        };
    },
    
    async login(credentials: LoginCredentials): Promise<AuthResponse> {
        await new Promise(resolve => setTimeout(resolve, 500));
        
        const user = usersDB.get(credentials.email);
        
        if (!user || user.password !== credentials.password) {
            throw new Error('Неверный email или пароль');
        }
        
        const accessToken = generateAccessToken(user.id);
        const refreshToken = generateRefreshToken(user.id);
        
        localStorage.setItem('refreshToken', refreshToken);
        localStorage.setItem('currentUserId', user.id);
        
        return {
            user: { id: user.id, name: user.name, email: user.email },
            accessToken
        };
    },
    
    async refreshAccessToken(): Promise<{ accessToken: string }> {
        await new Promise(resolve => setTimeout(resolve, 300));
        
        const refreshToken = localStorage.getItem('refreshToken');
        if (!refreshToken) {
            throw new Error('No refresh token');
        }
        
        try {
            const payload = JSON.parse(atob(refreshToken));
            if (payload.exp < Date.now()) {
                localStorage.removeItem('refreshToken');
                throw new Error('Refresh token expired');
            }
            const newAccessToken = generateAccessToken(payload.userId);
            return { accessToken: newAccessToken };
        } catch {
            throw new Error('Invalid refresh token');
        }
    },
    
    async logout(): Promise<void> {
        await new Promise(resolve => setTimeout(resolve, 200));
        localStorage.removeItem('refreshToken');
        localStorage.removeItem('currentUserId');
        // НЕ ОЧИЩАЕМ ДАННЫЕ ПОЛЬЗОВАТЕЛЯ - они остаются в хранилище
    },
    
    async getCurrentUser(): Promise<User | null> {
        const refreshToken = localStorage.getItem('refreshToken');
        const userId = localStorage.getItem('currentUserId');
        
        if (!refreshToken || !userId) return null;
        
        try {
            const payload = JSON.parse(atob(refreshToken));
            if (payload.exp < Date.now()) {
                localStorage.removeItem('refreshToken');
                return null;
            }
            
            // ИЩЕМ ПОЛЬЗОВАТЕЛЯ ПО ID
            for (const [_, user] of usersDB) {
                if (user.id === userId) {
                    return { id: user.id, name: user.name, email: user.email };
                }
            }
        } catch {
            return null;
        }
        
        return null;
    }
};