// frontend/js/api.js

import { API_BASE_URL_WITH_PREFIX } from './config.js';

const API_BASE_URL = API_BASE_URL_WITH_PREFIX;

/**
 * Fetches the list of available speakers.
 * @returns {Promise<Array<Object>>} A promise that resolves to an array of speaker objects.
 * @throws {Error} If the network response is not ok.
 */
export async function getSpeakers() {
    const response = await fetch(`${API_BASE_URL}/speakers`);
    if (!response.ok) {
        const errorData = await response.json().catch(() => ({ message: response.statusText }));
        throw new Error(`Failed to fetch speakers: ${errorData.detail || errorData.message || response.statusText}`);
    }
    return response.json();
}

// We will add more functions here: addSpeaker, deleteSpeaker, generateDialog

// ... (keep API_BASE_URL and getSpeakers)

/**
 * Adds a new speaker.
 * @param {FormData} formData - The form data containing speaker name and audio file.
 *                               Example: formData.append('name', 'New Speaker');
 *                                        formData.append('audio_file', fileInput.files[0]);
 * @returns {Promise<Object>} A promise that resolves to the new speaker object.
 * @throws {Error} If the network response is not ok.
 */
export async function addSpeaker(formData) {
    const response = await fetch(`${API_BASE_URL}/speakers`, {
        method: 'POST',
        body: formData, // FormData sets Content-Type to multipart/form-data automatically
    });
    if (!response.ok) {
        console.log('API_JS_ADD_SPEAKER: Entered !response.ok block. Status:', response.status, 'StatusText:', response.statusText);
        let errorPayload = { detail: `Request failed with status ${response.status}` }; // Default payload
        try {
            console.log('API_JS_ADD_SPEAKER: Attempting to parse error response as JSON...');
            errorPayload = await response.json();
            console.log('API_JS_ADD_SPEAKER: Successfully parsed error JSON:', errorPayload);
        } catch (e) {
            console.warn('API_JS_ADD_SPEAKER: Failed to parse error response as JSON. Error:', e);
            // Use statusText if JSON parsing fails
            errorPayload = { detail: response.statusText || `Request failed with status ${response.status} and no JSON body.`, parseError: e.toString() };
        }
        
        console.error('--- BEGIN SERVER ERROR PAYLOAD (addSpeaker) ---');
        console.error('Status:', response.status);
        console.error('Status Text:', response.statusText);
        console.error('Parsed Payload:', errorPayload);
        console.error('--- END SERVER ERROR PAYLOAD (addSpeaker) ---');

        let detailedMessage = "Unknown error";
        if (errorPayload && errorPayload.detail) {
            if (typeof errorPayload.detail === 'string') {
                detailedMessage = errorPayload.detail;
            } else {
                // If detail is an array (FastAPI validation errors) or object, stringify it.
                detailedMessage = JSON.stringify(errorPayload.detail);
            }
        } else if (errorPayload && errorPayload.message) { 
            detailedMessage = errorPayload.message;
        } else if (response.statusText) {
            detailedMessage = response.statusText;
        } else {
            detailedMessage = `HTTP error ${response.status}`;
        }
        
        console.log(`API_JS_ADD_SPEAKER: Constructed detailedMessage: "${detailedMessage}"`);
        console.log(`API_JS_ADD_SPEAKER: Throwing error with message: "Failed to add speaker: ${detailedMessage}"`);
        throw new Error(`Failed to add speaker: ${detailedMessage}`);
    }
    return response.json();
}

// ... (keep API_BASE_URL, getSpeakers, addSpeaker)

/**
 * Deletes a speaker by their ID.
 * @param {string} speakerId - The ID of the speaker to delete.
 * @returns {Promise<Object>} A promise that resolves to the response data (e.g., success message).
 * @throws {Error} If the network response is not ok.
 */
export async function deleteSpeaker(speakerId) {
    const response = await fetch(`${API_BASE_URL}/speakers/${speakerId}`, {
        method: 'DELETE',
    });
    if (!response.ok) {
        const errorData = await response.json().catch(() => ({ message: response.statusText }));
        throw new Error(`Failed to delete speaker ${speakerId}: ${errorData.detail || errorData.message || response.statusText}`);
    }
    // Handle 204 No Content specifically, as .json() would fail
    if (response.status === 204) {
        return { message: `Speaker ${speakerId} deleted successfully.` };
    }
    return response.json();
}

// ... (keep API_BASE_URL, getSpeakers, addSpeaker, deleteSpeaker)

/**
 * Generates audio for a single dialog line (speech or silence).
 * @param {Object} line - The dialog line object (type: 'speech' or 'silence').
 * @returns {Promise<Object>} Resolves with { audio_url } on success.
 * @throws {Error} If the network response is not ok.
 */
export async function generateLine(line) {
    console.log('generateLine called with:', line);
    const response = await fetch(`${API_BASE_URL}/dialog/generate_line`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(line),
    });
    console.log('Response status:', response.status);
    console.log('Response headers:', [...response.headers.entries()]);
    
    if (!response.ok) {
        const errorData = await response.json().catch(() => ({ message: response.statusText }));
        throw new Error(`Failed to generate line audio: ${errorData.detail || errorData.message || response.statusText}`);
    }
    const data = await response.json();
    return data;
}

/**
 * Generates a dialog by sending a payload to the backend.
 * @param {Object} dialogPayload - The payload for dialog generation.
 *   Example:
 *   {
 *     output_base_name: "my_dialog",
 *     dialog_items: [
 *       { type: "speech", speaker_id: "speaker1", text: "Hello world.", exaggeration: 1.0, cfg_weight: 2.0, temperature: 0.7 },
 *       { type: "silence", duration: 0.5 },
 *       { type: "speech", speaker_id: "speaker2", text: "How are you?" }
 *     ]
 *   }
 * @returns {Promise<Object>} A promise that resolves to the dialog generation response (log, file URLs).
 * @throws {Error} If the network response is not ok.
 */
export async function generateDialog(dialogPayload) {
    const response = await fetch(`${API_BASE_URL}/dialog/generate`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(dialogPayload),
    });
    if (!response.ok) {
        const errorData = await response.json().catch(() => ({ message: response.statusText }));
        throw new Error(`Failed to generate dialog: ${errorData.detail || errorData.message || response.statusText}`);
    }
    return response.json();
}
