// SonicForge Studio API Service
window.API_BASE_URL = (window.API_BASE_URL || window.location.origin).replace(/\/+$/, '');

(function() {
    function getAuthToken() {
        return localStorage.getItem('sonic_token') || '';
    }

    function getAuthHeaders() {
        const token = getAuthToken();
        return {
            'Content-Type': 'application/json',
            ...(token ? { 'Authorization': `Bearer ${token}` } : {})
        };
    }

    async function apiRequest(endpoint, options = {}) {
        const url = `${window.API_BASE_URL}${endpoint}`;
        const headers = { ...getAuthHeaders(), ...options.headers };
        // FormData: browser tự đặt Content-Type kèm boundary — không được ép JSON
        if (options.body instanceof FormData) delete headers['Content-Type'];
        const response = await fetch(url, { ...options, headers });
        
        if (response.status === 401) {
            localStorage.removeItem('sonic_token');
            localStorage.removeItem('sonic_user');
        }
        
        const data = await response.json().catch(() => ({}));
        if (!response.ok) {
            throw new Error(data.detail || data.message || 'Lỗi kết nối API Server');
        }
        return data;
    }

    window.SonicAPI = {
        login: (username, password) => apiRequest('/api/v1/auth/login', { method: 'POST', body: JSON.stringify({ username, password }) }),
        register: (username, email, password) => apiRequest('/api/v1/auth/register', { method: 'POST', body: JSON.stringify({ username, email, password }) }),
        changePassword: (old_password, new_password) => apiRequest('/api/v1/auth/change-password', { method: 'POST', body: JSON.stringify({ old_password, new_password }) }),
        getProfile: () => apiRequest('/api/v1/auth/profile', { method: 'GET' }),
        
        listUsers: () => apiRequest('/api/v1/admin/users', { method: 'GET' }),
        updateUserQuota: (userId, storageLimitMb, maxTracks = 16) => apiRequest(`/api/v1/admin/quotas/${userId}`, { method: 'PUT', body: JSON.stringify({ storage_limit_mb: storageLimitMb, max_tracks: maxTracks }) }),
        updateUserRole: (userId, role, isActive = true) => apiRequest(`/api/v1/admin/users/${userId}/role`, { method: 'PUT', body: JSON.stringify({ role, is_active: isActive }) }),
        deleteUser: (userId) => apiRequest(`/api/v1/admin/users/${userId}`, { method: 'DELETE' }),
        createUser: (username, email, password, role = 'standard') => apiRequest('/api/v1/admin/users', { method: 'POST', body: JSON.stringify({ username, email, password, role }) }),

        saveTempProject: (dataJson, clientId) => apiRequest('/api/v1/projects/temp', { method: 'POST', body: JSON.stringify({ data_json: dataJson, client_id: clientId || '' }) }),
        getTempProject: () => apiRequest('/api/v1/projects/temp', { method: 'GET' }),
        getTempRevision: () => apiRequest('/api/v1/projects/temp/revision', { method: 'GET' }),
        saveCloudProject: (name, dataJson) => apiRequest('/api/v1/projects/cloud', { method: 'POST', body: JSON.stringify({ name, data_json: dataJson }) }),
        listCloudProjects: () => apiRequest('/api/v1/projects/cloud', { method: 'GET' }),
        getCloudProject: (projectId) => apiRequest(`/api/v1/projects/cloud/${projectId}`, { method: 'GET' }),
        deleteCloudProject: (projectId) => apiRequest(`/api/v1/projects/cloud/${projectId}`, { method: 'DELETE' }),
        updateCloudProject: (projectId, name, dataJson) => apiRequest(`/api/v1/projects/cloud/${projectId}`, { method: 'PUT', body: JSON.stringify({ name, data_json: dataJson }) }),
        listMyFiles: (activeFileIds) => apiRequest('/api/v1/audio/my-files', { method: 'POST', body: JSON.stringify({ active_file_ids: activeFileIds }) }),
        deleteMyFile: (fileId) => apiRequest(`/api/v1/audio/my-files/${fileId}`, { method: 'DELETE' }),

        aiScan: (trackId, fileId, minLoopDuration = 2.0, maxLoopDuration = 6.0) => apiRequest('/api/v1/audio/ai-scan', { method: 'POST', body: JSON.stringify({ track_id: trackId, file_id: fileId, min_loop_duration: minLoopDuration, max_loop_duration: maxLoopDuration }) }),
        aiCut: (sourceTrackId, fileId, selectionStart, selectionEnd) => apiRequest('/api/v1/audio/ai-cut', { method: 'POST', body: JSON.stringify({ source_track_id: sourceTrackId, file_id: fileId, selection_start: selectionStart, selection_end: selectionEnd }) }),
        runPythonTool: (toolType, trackId, fileId, timePos = 0.0, freq = 440.0, duration = 2.0, waveType = "sine") => apiRequest('/api/v1/audio/python-tool', { method: 'POST', body: JSON.stringify({ tool_type: toolType, track_id: trackId, file_id: fileId, time_pos: timePos, freq: freq, duration: duration, wave_type: waveType }) }),

        getAIConfigs: () => apiRequest('/api/v1/user/config/ai', { method: 'GET' }),
        saveAIConfigs: (providers) => apiRequest('/api/v1/user/config/ai', { method: 'POST', body: JSON.stringify({ providers }) }),

        getPreferences: () => apiRequest('/api/v1/user/preferences', { method: 'GET' }),
        savePreferences: (prefs) => apiRequest('/api/v1/user/preferences', { method: 'POST', body: JSON.stringify({ preferences: prefs }) }),

        listPlugins: () => apiRequest('/api/v1/plugins/available', { method: 'GET' }),
        getPluginDirs: () => apiRequest('/api/v1/plugins/dirs', { method: 'GET' }),
        savePluginDirs: (dirs) => apiRequest('/api/v1/plugins/dirs', { method: 'POST', body: JSON.stringify(dirs) }),
        scanPluginDirs: () => apiRequest('/api/v1/plugins/scan', { method: 'POST' }),
        // Runtime capabilities — frontend gọi lúc boot để biết môi trường
        // (desktop Windows / docker headless) và bật/tắt tính năng
        getCapabilities: () => apiRequest('/api/v1/system/capabilities', { method: 'GET' }),
        // Định vị Carla.exe (bản portable zip không cài đặt/PATH) — lưu config
        setCarlaPath: (path) => apiRequest('/api/v1/system/carla-path', { method: 'POST', body: JSON.stringify({ carla_path: path }) }),
        // Mở native GUI VSTi trong Carla (chỉ khi runtime=desktop + có Carla local)
        openInCarla: (pluginName, pluginPath) => apiRequest('/api/v1/plugins/open-in-carla', { method: 'POST', body: JSON.stringify({ plugin_name: pluginName, plugin_path: pluginPath }) }),
        // Unload Carla bridge: tắt mọi note đang ngân + terminate tiến trình Carla
        // do app spawn (gọi khi track chuyển từ VSTi sang instrument soundfont)
        stopCarla: () => apiRequest('/api/v1/plugins/carla-stop', { method: 'POST', body: JSON.stringify({}) }),
        // Kiểm tra Carla còn sống không (app-spawn) + cổng OSC — quyết định
        // route MIDI item exclusive qua Carla hay fallback FluidSynth
        carlaStatus: () => apiRequest('/api/v1/plugins/carla-status', { method: 'GET' }),
        // Gửi MIDI note (track ARM → Carla OSC) để preview VSTi realtime
        carlaMidi: (payload) => apiRequest('/api/v1/plugins/carla-midi', { method: 'POST', body: JSON.stringify(payload) }),
        // Quick-render preview VSTi (âm thật = âm export, cùng code path)
        previewInstrument: (payload) => apiRequest('/api/v1/plugins/preview', { method: 'POST', body: JSON.stringify(payload) }),
        // Render MIDI notes → WAV bằng VSTi (pedalboard, âm thật) — trả file_id
        // để UI preview / gán clip vào track / download
        midiRender: (payload) => apiRequest('/api/v1/plugins/midi-render', { method: 'POST', body: JSON.stringify(payload) }),
        soundfontRender: (payload) => apiRequest('/api/v1/plugins/soundfont-render', { method: 'POST', body: JSON.stringify(payload) }),
        // Phát dãy MIDI notes realtime qua Carla bridge (OSC) — preview khi
        // pedalboard không render được plugin (VD VST2)
        carlaPlayNotes: (payload) => apiRequest('/api/v1/plugins/carla-play-notes', { method: 'POST', body: JSON.stringify(payload) }),
        // Thư viện preset VST3 (.vstpreset) — cầu nối Carla → pedalboard
        listPresets: () => apiRequest('/api/v1/presets', { method: 'GET' }),
        uploadPreset: (file, pluginHint) => {
            const fd = new FormData();
            fd.append('file', file);
            if (pluginHint) fd.append('plugin_hint', pluginHint);
            return apiRequest('/api/v1/presets/upload', { method: 'POST', body: fd });
        },
        deletePreset: (presetId) => apiRequest(`/api/v1/presets/${presetId}`, { method: 'DELETE' }),
        // Native folder picker (Explorer qua Tauri bridge / PowerShell) —
        // user yêu cầu dùng window explorer, không nhập tay
        pickPluginDir: () => apiRequest('/api/v1/plugins/pick-dir', { method: 'POST' }),
        // Folder picker cho Plugin Manager: duyet thu muc qua backend (media)
        // — hoat dong moi OS, khong can window.__TAURI__ (UI chay tren localhost:8000)
        browseComputer: () => apiRequest('/api/v1/media/computer', { method: 'GET' }),
        browseDir: (path) => apiRequest(`/api/v1/media/browse?path=${encodeURIComponent(path)}`, { method: 'GET' }),
        getSoundfontCatalog: () => apiRequest('/api/v1/plugins/soundfonts/catalog', { method: 'GET' }),
        listDefaultSoundfonts: () => apiRequest('/api/v1/plugins/default-soundfonts', { method: 'GET' }),
        listSoundfontInstruments: (sfId) => apiRequest(`/api/v1/plugins/soundfont-instruments/${sfId}`, { method: 'GET' }),
        // Native Host Bridge (daw_vst_bridge C++): trạng thái + load asset +
        // tail bridge.log (E1/E2/E5).
        bridgeStatus: () => apiRequest('/api/v1/plugins/bridge/status', { method: 'GET' }),
        bridgeLoad: (payload) => apiRequest('/api/v1/plugins/bridge/load', { method: 'POST', body: JSON.stringify(payload) }),
        bridgeLog: (lines = 100) => apiRequest(`/api/v1/plugins/bridge/log?lines=${lines}`, { method: 'GET' }),
        getAIPresets: () => apiRequest('/api/v1/ai/presets', { method: 'GET' }),
        saveAIPreset: (preset) => apiRequest('/api/v1/ai/presets', { method: 'POST', body: JSON.stringify(preset) }),
        deleteAIPreset: (presetId) => apiRequest(`/api/v1/ai/presets/${presetId}`, { method: 'DELETE' }),

        createBackup: (projectId) => apiRequest(`/api/v1/projects/cloud/${projectId}/backup`, { method: 'POST' }),
        listBackups: (projectId) => apiRequest(`/api/v1/projects/cloud/${projectId}/backups`, { method: 'GET' }),
        deleteBackup: (backupId) => apiRequest(`/api/v1/projects/cloud/backups/${backupId}`, { method: 'DELETE' }),
        cleanupBackups: (keep) => apiRequest('/api/v1/projects/cloud/backups/cleanup', { method: 'POST', body: JSON.stringify({ keep }) }),

        renderProject: (projectJson, outputFilename) => apiRequest('/api/v1/plugins/render', { method: 'POST', body: JSON.stringify({ project_json: projectJson, output_filename: outputFilename }) }),
        // Ctrl-S desktop: lưu project ra THƯ MỤC CỦA HỆ ĐIỀU HÀNH
        // (Documents/SonicForgeDAW/Projects — Windows; ~/SonicForgeDAW/Projects — Linux)
        saveProjectToDisk: (name, dataJson) => apiRequest('/api/v1/projects/save-to-disk', { method: 'POST', body: JSON.stringify({ name, data_json: dataJson }) }),
        deleteSoundFont: (sfId) => apiRequest(`/api/v1/plugins/soundfont/${sfId}`, { method: 'DELETE' }),
        uploadSoundFont: async (file) => {
            const formData = new FormData();
            formData.append('file', file);
            const token = localStorage.getItem('sonic_token') || '';
            const resp = await fetch(`${window.API_BASE_URL}/api/v1/plugins/upload-soundfont`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token}` },
                body: formData
            });
            if (!resp.ok) {
                const err = await resp.json().catch(() => ({}));
                throw new Error(err.detail || 'Upload failed');
            }
            return resp.json();
        }
    };
})();
