import { useState, useCallback } from 'react' export function useSession() { const [sessionId, setSessionId] = useState(null) const [stems, setStems] = useState([]) const [detection, setDetection] = useState(null) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const clearError = useCallback(() => { setError(null) }, []) // Upload files and automatically run detection const upload = useCallback(async (formData) => { setLoading(true) setError(null) try { // Step 1: Upload files (formData already prepared by FileUpload component) const uploadResponse = await fetch('/api/upload', { method: 'POST', body: formData }) if (!uploadResponse.ok) { const data = await uploadResponse.json().catch(() => ({})) throw new Error(data.detail || `Upload failed: ${uploadResponse.status}`) } const uploadData = await uploadResponse.json() console.log('Upload response:', uploadData) setSessionId(uploadData.session_id) setStems(uploadData.stems) // Step 2: Automatically run detection with the session_id we just got const detectResponse = await fetch(`/api/detect/${uploadData.session_id}`, { method: 'POST' }) if (!detectResponse.ok) { const data = await detectResponse.json().catch(() => ({})) throw new Error(data.detail || `Detection failed: ${detectResponse.status}`) } const detectData = await detectResponse.json() console.log('Detection response:', detectData) setDetection(detectData) return { upload: uploadData, detection: detectData } } catch (err) { console.error('Error:', err) setError(err.message) return null } finally { setLoading(false) } }, []) // Manual detect (if needed separately) const detect = useCallback(async (sid = null) => { const id = sid || sessionId if (!id) { setError('No session to detect') return null } setLoading(true) setError(null) try { const response = await fetch(`/api/detect/${id}`, { method: 'POST' }) if (!response.ok) { const data = await response.json().catch(() => ({})) throw new Error(data.detail || `Detection failed: ${response.status}`) } const data = await response.json() setDetection(data) return data } catch (err) { setError(err.message) return null } finally { setLoading(false) } }, [sessionId]) const process = useCallback(async (semitones, targetBpm = null, regionStart = null, regionEnd = null) => { if (!sessionId) { setError('No session to process') return null } setLoading(true) setError(null) try { const body = { semitones, target_bpm: targetBpm } if (regionStart !== null && regionEnd !== null) { body.region_start = regionStart body.region_end = regionEnd } const response = await fetch(`/api/process/${sessionId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) if (!response.ok) { const data = await response.json().catch(() => ({})) throw new Error(data.detail || `Processing failed: ${response.status}`) } const data = await response.json() return data } catch (err) { setError(err.message) return null } finally { setLoading(false) } }, [sessionId]) const getStems = useCallback(async () => { if (!sessionId) return null try { const response = await fetch(`/api/stems/${sessionId}`) if (!response.ok) { throw new Error('Failed to get stems') } const data = await response.json() return data } catch (err) { setError(err.message) return null } }, [sessionId]) const loadPreset = useCallback(async (presetName) => { setLoading(true) setError(null) try { const uploadResponse = await fetch(`/api/preset/${presetName}`, { method: 'POST' }) if (!uploadResponse.ok) { const data = await uploadResponse.json().catch(() => ({})) throw new Error(data.detail || `Failed to load preset: ${uploadResponse.status}`) } const uploadData = await uploadResponse.json() setSessionId(uploadData.session_id) setStems(uploadData.stems) const detectResponse = await fetch(`/api/detect/${uploadData.session_id}`, { method: 'POST' }) if (!detectResponse.ok) { const data = await detectResponse.json().catch(() => ({})) throw new Error(data.detail || `Detection failed: ${detectResponse.status}`) } const detectData = await detectResponse.json() setDetection(detectData) return { upload: uploadData, detection: detectData } } catch (err) { setError(err.message) return null } finally { setLoading(false) } }, []) const generate = useCallback(async (regionStart, regionEnd, duration = 15.0, prompt = null) => { if (!sessionId) { setError('No session to generate') return null } setLoading(true) setError(null) try { const body = { region_start: regionStart, region_end: regionEnd, duration } if (prompt) { body.prompt = prompt } const response = await fetch(`/api/generate/${sessionId}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }) if (!response.ok) { const data = await response.json().catch(() => ({})) throw new Error(data.detail || `Generation failed: ${response.status}`) } const data = await response.json() return data } catch (err) { setError(err.message) return null } finally { setLoading(false) } }, [sessionId]) return { sessionId, stems, detection, loading, error, upload, detect, process, generate, getStems, loadPreset, clearError } }