/**
 * Pipeline Builder - Client Side Logic
 * Gestion de la construction interactive de pipelines modulaires
 */

// État global du builder
const state = {
    pipeline: {
        name: '',
        description: '',
        pipeline: [],
        metadata: {
            author: 'user',
            created: new Date().toISOString(),
            version: '1.0',
            tags: []
        }
    },
    modules: [],
    templates: [],
    llmProviders: [],
    personalities: [],  // ✅ NOUVEAU: Liste des personnalités disponibles
    nextStepNumber: 1
};

// ====================
// INITIALIZATION
// ====================

window.onload = async function() {
    await loadModules();
    await loadTemplates();
    await loadLLMProviders();
    await loadPersonalities();  // ✅ NOUVEAU: Charger personnalités
    updatePreview();
};

// Load available modules from API
async function loadModules() {
    try {
        const response = await fetch('/api/pipeline/modules');
        const data = await response.json();

        if (data.success) {
            state.modules = data.modules;
            renderModulesPalette();
        }
    } catch (error) {
        showStatus(`Erreur chargement modules: ${error.message}`, 'error');
    }
}

// Load templates from API
async function loadTemplates() {
    try {
        const response = await fetch('/api/pipeline/templates');
        const data = await response.json();

        if (data.success) {
            state.templates = data.templates;
            renderTemplates();
        }
    } catch (error) {
        showStatus(`Erreur chargement templates: ${error.message}`, 'error');
    }
}

// Load LLM providers from API
async function loadLLMProviders() {
    try {
        const response = await fetch('/api/pipeline/modules');
        const data = await response.json();

        if (data.success && data.llmProviders) {
            state.llmProviders = data.llmProviders;
        }
    } catch (error) {
        console.error('Erreur chargement LLM providers:', error);
        // Fallback providers si l'API échoue (synchronisé avec LLMManager)
        state.llmProviders = [
            { id: 'claude-sonnet-4-5', name: 'Claude Sonnet 4.5', default: true },
            { id: 'gpt-4o-mini', name: 'GPT-4o Mini' },
            { id: 'gemini-pro', name: 'Google Gemini Pro' },
            { id: 'deepseek-chat', name: 'Deepseek Chat' },
            { id: 'moonshot-v1-32k', name: 'Moonshot v1 32K' },
            { id: 'mistral-small', name: 'Mistral Small' }
        ];
    }
}

// ✅ NOUVEAU: Load personalities from API
async function loadPersonalities() {
    try {
        const response = await fetch('/api/personalities');
        const data = await response.json();

        if (data.success && data.personalities) {
            state.personalities = data.personalities;
            console.log(`✅ ${state.personalities.length} personnalités chargées`);
        }
    } catch (error) {
        console.error('Erreur chargement personnalités:', error);
        state.personalities = [];
    }
}

// ====================
// RENDERING
// ====================

function renderModulesPalette() {
    const container = document.getElementById('modulesContainer');
    container.innerHTML = '';

    const categories = {
        core: ['generation'],
        enhancement: ['selective', 'smarttouch'],  // ✅ AJOUTÉ: smarttouch
        protection: ['adversarial', 'human', 'pattern']
    };

    const categoryLabels = {
        core: '🎯 Génération',
        enhancement: '✨ Enhancement',
        protection: '🛡️ Protection'
    };

    Object.entries(categories).forEach(([catKey, moduleIds]) => {
        const catDiv = document.createElement('div');
        catDiv.className = 'module-category';

        const catTitle = document.createElement('h3');
        catTitle.textContent = categoryLabels[catKey];
        catDiv.appendChild(catTitle);

        moduleIds.forEach(moduleId => {
            const module = state.modules.find(m => m.id === moduleId);
            if (!module) return;

            const moduleDiv = document.createElement('div');
            moduleDiv.className = 'module-item';
            moduleDiv.draggable = true;
            moduleDiv.dataset.moduleId = module.id;

            moduleDiv.innerHTML = `
                <div class="module-name">${module.name}</div>
                <div class="module-desc">${module.description}</div>
            `;

            // Drag events
            moduleDiv.addEventListener('dragstart', handleDragStart);
            moduleDiv.addEventListener('dragend', handleDragEnd);

            // Click to add
            moduleDiv.addEventListener('click', () => {
                addStep(module.id, module.modes[0]);
            });

            catDiv.appendChild(moduleDiv);
        });

        container.appendChild(catDiv);
    });
}

function renderTemplates() {
    const container = document.getElementById('templatesContainer');
    container.innerHTML = '';

    state.templates.forEach(template => {
        const templateDiv = document.createElement('div');
        templateDiv.className = 'template-item';

        templateDiv.innerHTML = `
            <div class="template-name">${template.name}</div>
            <div class="template-desc">${template.description.substring(0, 60)}...</div>
        `;

        templateDiv.addEventListener('click', () => loadTemplate(template.id));

        container.appendChild(templateDiv);
    });
}

function renderPipeline() {
    const container = document.getElementById('stepsContainer');
    const empty = document.getElementById('canvasEmpty');

    if (state.pipeline.pipeline.length === 0) {
        container.style.display = 'none';
        empty.style.display = 'flex';
        return;
    }

    empty.style.display = 'none';
    container.style.display = 'block';
    container.innerHTML = '';

    state.pipeline.pipeline.forEach((step, index) => {
        const stepDiv = createStepElement(step, index);
        container.appendChild(stepDiv);
    });

    updatePreview();
}

function createStepElement(step, index) {
    const module = state.modules.find(m => m.id === step.module);
    if (!module) return document.createElement('div');

    const stepDiv = document.createElement('div');
    stepDiv.className = 'pipeline-step';
    stepDiv.dataset.stepIndex = index;

    stepDiv.innerHTML = `
        <div class="step-header">
            <div class="step-number">${step.step}</div>
            <div class="step-title">${module.name} - ${step.mode}</div>
            <div class="step-actions">
                <button class="step-btn" onclick="moveStepUp(${index})" ${index === 0 ? 'disabled' : ''}>↑</button>
                <button class="step-btn" onclick="moveStepDown(${index})" ${index === state.pipeline.pipeline.length - 1 ? 'disabled' : ''}>↓</button>
                <button class="step-btn" onclick="duplicateStep(${index})">📋</button>
                <button class="step-btn" onclick="deleteStep(${index})">🗑️</button>
            </div>
        </div>
        <div class="step-config">
            <div class="config-row">
                <label>Mode:</label>
                <select onchange="updateStepMode(${index}, this.value)">
                    ${module.modes.map(mode =>
                        `<option value="${mode}" ${mode === step.mode ? 'selected' : ''}>${mode}</option>`
                    ).join('')}
                </select>
            </div>
            <div class="config-row">
                <label>Intensité:</label>
                <input type="number" step="0.1" min="0.1" max="2.0" value="${step.intensity || 1.0}"
                       onchange="updateStepIntensity(${index}, parseFloat(this.value))">
            </div>
            ${renderModuleParameters(step, index, module)}
        </div>
    `;

    return stepDiv;
}

function renderModuleParameters(step, index, module) {
    let html = '';

    // Toujours afficher le dropdown LLM Provider en premier
    const currentProvider = step.parameters?.llmProvider || module.defaultLLM || '';
    const defaultProvider = module.defaultLLM || 'claude';

    html += `
        <div class="config-row">
            <label>LLM:</label>
            <select onchange="updateStepParameter(${index}, 'llmProvider', this.value)">
                <option value="">Default (${defaultProvider})</option>
                ${state.llmProviders.map(provider =>
                    `<option value="${provider.id}" ${provider.id === currentProvider ? 'selected' : ''}>${provider.name}</option>`
                ).join('')}
            </select>
        </div>
    `;

    // ✅ NOUVEAU: Afficher dropdown personnalité pour SmartTouch
    if (step.module === 'smarttouch' && state.personalities.length > 0) {
        const currentPersonality = step.parameters?.personalityName || '';

        html += `
            <div class="config-row">
                <label>Personnalité:</label>
                <select onchange="updateStepParameter(${index}, 'personalityName', this.value)">
                    <option value="">Auto (from csvData)</option>
                    ${state.personalities.map(personality =>
                        `<option value="${personality.nom}" ${personality.nom === currentPersonality ? 'selected' : ''}>${personality.nom} (${personality.style})</option>`
                    ).join('')}
                </select>
            </div>
        `;
    }

    // Autres paramètres du module (sauf llmProvider et personalityName qui sont déjà affichés)
    if (module.parameters && Object.keys(module.parameters).length > 0) {
        Object.entries(module.parameters).forEach(([paramName, paramConfig]) => {
            // Skip llmProvider et personalityName car déjà affichés ci-dessus
            if (paramName === 'llmProvider' || paramName === 'personalityName') return;

            const value = step.parameters?.[paramName] || paramConfig.default || '';

            if (paramConfig.enum) {
                html += `
                    <div class="config-row">
                        <label>${paramName}:</label>
                        <select onchange="updateStepParameter(${index}, '${paramName}', this.value)">
                            ${paramConfig.enum.map(opt =>
                                `<option value="${opt}" ${opt === value ? 'selected' : ''}>${opt}</option>`
                            ).join('')}
                        </select>
                    </div>
                `;
            } else if (paramConfig.type === 'number') {
                html += `
                    <div class="config-row">
                        <label>${paramName}:</label>
                        <input type="number" step="${paramConfig.step || 0.1}"
                               min="${paramConfig.min || 0}" max="${paramConfig.max || 10}"
                               value="${value}"
                               onchange="updateStepParameter(${index}, '${paramName}', parseFloat(this.value))">
                    </div>
                `;
            }
        });
    }

    return html;
}

// ====================
// PIPELINE OPERATIONS
// ====================

function addStep(moduleId, mode = null) {
    const module = state.modules.find(m => m.id === moduleId);
    if (!module) return;

    const newStep = {
        step: state.nextStepNumber++,
        module: moduleId,
        mode: mode || module.modes[0],
        intensity: module.defaultIntensity || 1.0,
        parameters: {},
        enabled: true
    };

    state.pipeline.pipeline.push(newStep);
    reorderSteps();
    renderPipeline();
}

function deleteStep(index) {
    state.pipeline.pipeline.splice(index, 1);
    reorderSteps();
    renderPipeline();
}

function duplicateStep(index) {
    const step = state.pipeline.pipeline[index];
    const duplicated = JSON.parse(JSON.stringify(step));
    duplicated.step = state.nextStepNumber++;

    state.pipeline.pipeline.splice(index + 1, 0, duplicated);
    reorderSteps();
    renderPipeline();
}

function moveStepUp(index) {
    if (index === 0) return;

    const temp = state.pipeline.pipeline[index];
    state.pipeline.pipeline[index] = state.pipeline.pipeline[index - 1];
    state.pipeline.pipeline[index - 1] = temp;

    reorderSteps();
    renderPipeline();
}

function moveStepDown(index) {
    if (index === state.pipeline.pipeline.length - 1) return;

    const temp = state.pipeline.pipeline[index];
    state.pipeline.pipeline[index] = state.pipeline.pipeline[index + 1];
    state.pipeline.pipeline[index + 1] = temp;

    reorderSteps();
    renderPipeline();
}

function updateStepMode(index, mode) {
    state.pipeline.pipeline[index].mode = mode;
    updatePreview();
}

function updateStepIntensity(index, intensity) {
    state.pipeline.pipeline[index].intensity = intensity;
    updatePreview();
}

function updateStepParameter(index, paramName, value) {
    if (!state.pipeline.pipeline[index].parameters) {
        state.pipeline.pipeline[index].parameters = {};
    }

    // Si value est vide/null/undefined, supprimer la clé pour utiliser le default
    if (value === '' || value === null || value === undefined) {
        delete state.pipeline.pipeline[index].parameters[paramName];
    } else {
        state.pipeline.pipeline[index].parameters[paramName] = value;
    }

    updatePreview();
}

function reorderSteps() {
    state.pipeline.pipeline.forEach((step, index) => {
        step.step = index + 1;
    });
    state.nextStepNumber = state.pipeline.pipeline.length + 1;
}

function clearPipeline() {
    if (!confirm('Effacer tout le pipeline ?')) return;

    state.pipeline.pipeline = [];
    state.nextStepNumber = 1;
    document.getElementById('pipelineName').value = '';
    document.getElementById('pipelineDesc').value = '';

    renderPipeline();
}

// ====================
// DRAG & DROP
// ====================

let draggedElement = null;

function handleDragStart(e) {
    draggedElement = e.target;
    e.target.classList.add('dragging');
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('moduleId', e.target.dataset.moduleId);
}

function handleDragEnd(e) {
    e.target.classList.remove('dragging');
}

// Setup drop zone
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('pipelineCanvas');

    canvas.addEventListener('dragover', (e) => {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
    });

    canvas.addEventListener('drop', (e) => {
        e.preventDefault();
        const moduleId = e.dataTransfer.getData('moduleId');
        if (moduleId) {
            addStep(moduleId);
        }
    });

    // Add step button
    document.getElementById('addStepBtn').addEventListener('click', () => {
        const firstModule = state.modules[0];
        if (firstModule) {
            addStep(firstModule.id);
        }
    });
});

// ====================
// TEMPLATES
// ====================

async function loadTemplate(templateId) {
    try {
        const response = await fetch(`/api/pipeline/templates/${templateId}`);
        const data = await response.json();

        if (data.success) {
            state.pipeline = data.template;
            state.nextStepNumber = data.template.pipeline.length + 1;

            document.getElementById('pipelineName').value = data.template.name;
            document.getElementById('pipelineDesc').value = data.template.description || '';

            renderPipeline();
            showStatus(`Template "${data.template.name}" chargé`, 'success');
        }
    } catch (error) {
        showStatus(`Erreur chargement template: ${error.message}`, 'error');
    }
}

// ====================
// SAVE / VALIDATE / TEST
// ====================

async function savePipeline() {
    const name = document.getElementById('pipelineName').value.trim();
    const description = document.getElementById('pipelineDesc').value.trim();

    if (!name) {
        showStatus('Nom du pipeline requis', 'error');
        return;
    }

    if (state.pipeline.pipeline.length === 0) {
        showStatus('Pipeline vide, ajoutez au moins une étape', 'error');
        return;
    }

    state.pipeline.name = name;
    state.pipeline.description = description;
    state.pipeline.metadata.saved = new Date().toISOString();

    try {
        const response = await fetch('/api/pipeline/save', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ pipelineDefinition: state.pipeline })
        });

        const data = await response.json();

        if (data.success) {
            showStatus(`✅ Pipeline "${name}" sauvegardé`, 'success');
        } else {
            showStatus(`Erreur: ${data.error}`, 'error');
        }
    } catch (error) {
        showStatus(`Erreur sauvegarde: ${error.message}`, 'error');
    }
}

async function validatePipeline() {
    const name = document.getElementById('pipelineName').value.trim();
    if (!name) {
        state.pipeline.name = 'Unnamed Pipeline';
    } else {
        state.pipeline.name = name;
    }

    try {
        const response = await fetch('/api/pipeline/validate', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ pipelineDefinition: state.pipeline })
        });

        const data = await response.json();

        if (data.valid) {
            showStatus('✅ Pipeline valide', 'success');
        } else {
            showStatus(`❌ Erreurs: ${data.errors.join(', ')}`, 'error');
        }
    } catch (error) {
        showStatus(`Erreur validation: ${error.message}`, 'error');
    }
}

async function testPipeline() {
    const name = document.getElementById('pipelineName').value.trim();

    if (!name) {
        showStatus('Nom du pipeline requis pour le test', 'error');
        return;
    }

    state.pipeline.name = name;
    state.pipeline.description = document.getElementById('pipelineDesc').value.trim();

    const rowNumber = prompt('Numéro de ligne Google Sheets à tester ?', '2');
    if (!rowNumber) return;

    showStatus('🚀 Test en cours...', 'info');

    try {
        const response = await fetch('/api/pipeline/execute', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                pipelineConfig: state.pipeline,
                rowNumber: parseInt(rowNumber)
            })
        });

        const data = await response.json();

        if (data.success) {
            showStatus(`✅ Test réussi! Durée: ${data.result.stats.totalDuration}ms`, 'success');
            console.log('Test result:', data.result);
        } else {
            showStatus(`❌ Test échoué: ${data.error}`, 'error');
        }
    } catch (error) {
        showStatus(`Erreur test: ${error.message}`, 'error');
    }
}

// ====================
// PREVIEW & HELPERS
// ====================

function updatePreview() {
    const preview = document.getElementById('previewJson');
    preview.textContent = JSON.stringify(state.pipeline, null, 2);
}

function showStatus(message, type) {
    const status = document.getElementById('status');
    status.textContent = message;
    status.className = `status ${type}`;
    status.style.display = 'block';

    setTimeout(() => {
        status.style.display = 'none';
    }, 5000);
}
