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


// services/api.ts
import type { Document, DocumentData, Cell } from '../types';

// БАЗОВЫЙ КЛЮЧ (без привязки к пользователю - только для текущего документа)
const CURRENT_DOC_KEY = 'spreadsheet_current_doc';

// ФУНКЦИЯ ДЛЯ ПОЛУЧЕНИЯ КЛЮЧА С ПРЕФИКСОМ ПОЛЬЗОВАТЕЛЯ
const getUserKey = (baseKey: string, userId: string): string => {
    return `user_${userId}_${baseKey}`;
};

// ПОЛУЧИТЬ ТЕКУЩЕГО ПОЛЬЗОВАТЕЛЯ ИЗ STORE (вспомогательная функция)
const getCurrentUserId = (): string | null => {
    try {
        const authState = localStorage.getItem('redux_state_auth');
        if (authState) {
            const parsed = JSON.parse(authState);
            return parsed.user?.id || null;
        }
    } catch (e) {
        console.error('Failed to get user id:', e);
    }
    return null;
};

// ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ ДЛЯ РАБОТЫ С LOCALSTORAGE (с учётом пользователя)
const getStoredDocuments = (userId: string): Map<string, DocumentData> => {
    const key = getUserKey('spreadsheet_documents', userId);
    const stored = localStorage.getItem(key);
    if (!stored) {
        return new Map();
    }
    const obj = JSON.parse(stored);
    return new Map(Object.entries(obj));
};

const setStoredDocuments = (userId: string, docs: Map<string, DocumentData>) => {
    const key = getUserKey('spreadsheet_documents', userId);
    const obj = Object.fromEntries(docs);
    localStorage.setItem(key, JSON.stringify(obj));
};

// API ДЛЯ РАБОТЫ С ДОКУМЕНТАМИ (с учётом пользователя)
export const api = {
    // ПОЛУЧИТЬ ВСЕ ДОКУМЕНТЫ ПОЛЬЗОВАТЕЛЯ
    async getDocuments(userId?: string): Promise<Document[]> {
        await new Promise(resolve => setTimeout(resolve, 100));
        
        const uid = userId || getCurrentUserId();
        if (!uid) return [];
        
        const docs = getStoredDocuments(uid);
        const documents: Document[] = [];
        
        for (const [id, docData] of docs) {
            const previewData = docData.data.slice(0, 3).map(row => row.slice(0, 3));
            
            documents.push({
                id,
                name: docData.name,
                createdAt: docData.createdAt,
                updatedAt: docData.updatedAt,
                rows: docData.rows,
                cols: docData.cols,
                previewData
            });
        }
        
        return documents.sort((a, b) => 
            new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
        );
    },

    // ПОЛУЧИТЬ ОДИН ДОКУМЕНТ ПО ID
    async getDocument(id: string, userId?: string): Promise<DocumentData | null> {
        await new Promise(resolve => setTimeout(resolve, 100));
        
        const uid = userId || getCurrentUserId();
        if (!uid) return null;
        
        const docs = getStoredDocuments(uid);
        return docs.get(id) || null;
    },

    // СОЗДАТЬ НОВЫЙ ДОКУМЕНТ
    async createDocument(name: string, rows: number, cols: number, userId?: string): Promise<DocumentData> {
        await new Promise(resolve => setTimeout(resolve, 200));
        
        const uid = userId || getCurrentUserId();
        if (!uid) throw new Error('No user logged in');
        
        const id = `${uid}_${Date.now()}`;
        const now = new Date().toISOString();
        
        const data: Cell[][] = [];
        for (let i = 0; i < rows; i++) {
            const row: Cell[] = [];
            for (let j = 0; j < cols; j++) {
                row.push({
                    value: '',
                    displayValue: '',
                    type: 'string'
                });
            }
            data.push(row);
        }
        
        const newDoc: DocumentData = {
            id,
            name,
            data,
            rows,
            cols,
            createdAt: now,
            updatedAt: now
        };
        
        const docs = getStoredDocuments(uid);
        docs.set(id, newDoc);
        setStoredDocuments(uid, docs);
        
        return newDoc;
    },

    // ОБНОВИТЬ ДОКУМЕНТ
    async updateDocument(id: string, data: Cell[][], rows: number, cols: number, userId?: string): Promise<DocumentData> {
        await new Promise(resolve => setTimeout(resolve, 300));
        
        const uid = userId || getCurrentUserId();
        if (!uid) throw new Error('No user logged in');
        
        const docs = getStoredDocuments(uid);
        const existingDoc = docs.get(id);
        
        if (!existingDoc) {
            throw new Error('Document not found');
        }
        
        const updatedDoc: DocumentData = {
            ...existingDoc,
            data: JSON.parse(JSON.stringify(data)),
            rows,
            cols,
            updatedAt: new Date().toISOString()
        };
        
        docs.set(id, updatedDoc);
        setStoredDocuments(uid, docs);
        
        return updatedDoc;
    },

    // ПЕРЕИМЕНОВАТЬ ДОКУМЕНТ
    async renameDocument(id: string, newName: string, userId?: string): Promise<DocumentData> {
        await new Promise(resolve => setTimeout(resolve, 100));
        
        const uid = userId || getCurrentUserId();
        if (!uid) throw new Error('No user logged in');
        
        const docs = getStoredDocuments(uid);
        const existingDoc = docs.get(id);
        
        if (!existingDoc) {
            throw new Error('Document not found');
        }
        
        const renamedDoc: DocumentData = {
            ...existingDoc,
            name: newName,
            updatedAt: new Date().toISOString()
        };
        
        docs.set(id, renamedDoc);
        setStoredDocuments(uid, docs);
        
        return renamedDoc;
    },

    // УДАЛИТЬ ДОКУМЕНТ
    async deleteDocument(id: string, userId?: string): Promise<void> {
        await new Promise(resolve => setTimeout(resolve, 100));
        
        const uid = userId || getCurrentUserId();
        if (!uid) throw new Error('No user logged in');
        
        const docs = getStoredDocuments(uid);
        docs.delete(id);
        setStoredDocuments(uid, docs);
    },

    // ДУБЛИРОВАТЬ ДОКУМЕНТ
    async duplicateDocument(id: string, userId?: string): Promise<DocumentData> {
        await new Promise(resolve => setTimeout(resolve, 200));
        
        const uid = userId || getCurrentUserId();
        if (!uid) throw new Error('No user logged in');
        
        const docs = getStoredDocuments(uid);
        const existingDoc = docs.get(id);
        
        if (!existingDoc) {
            throw new Error('Document not found');
        }
        
        const newId = `${uid}_${Date.now()}`;
        const now = new Date().toISOString();
        
        const duplicatedDoc: DocumentData = {
            ...existingDoc,
            id: newId,
            name: `${existingDoc.name} (копия)`,
            createdAt: now,
            updatedAt: now
        };
        
        docs.set(newId, duplicatedDoc);
        setStoredDocuments(uid, docs);
        
        return duplicatedDoc;
    },

    // СОХРАНИТЬ ТЕКУЩИЙ ДОКУМЕНТ В localStorage ДЛЯ ВОССТАНОВЛЕНИЯ
    setCurrentDocumentId(id: string | null, userId?: string) {
        const uid = userId || getCurrentUserId();
        if (id && uid) {
            const key = getUserKey(CURRENT_DOC_KEY, uid);
            localStorage.setItem(key, id);
        } else if (uid) {
            const key = getUserKey(CURRENT_DOC_KEY, uid);
            localStorage.removeItem(key);
        }
    },

    getCurrentDocumentId(userId?: string): string | null {
        const uid = userId || getCurrentUserId();
        if (!uid) return null;
        const key = getUserKey(CURRENT_DOC_KEY, uid);
        return localStorage.getItem(key);
    }
};