'use strict';

(function() {
  const zipInput = document.getElementById('zipInput');
  const integrateBtn = document.getElementById('integrateBtn');
  const downloadLink = document.getElementById('downloadLink');
  const statusContainer = document.getElementById('statusContainer');
  const statusBox = document.getElementById('statusBox');
  const statusText = document.getElementById('statusText');
  const progressBar = document.getElementById('progressBar');
  const progressMsg = document.getElementById('progressMsg');
  const logEl = document.getElementById('log');
  const dropZone = document.getElementById('dropZone');
  const fileName = document.getElementById('fileName');

  // Base path awareness so the app works both at domain root and under a subfolder.
  // We also guard against the case where the page is served as
  //   /lookangejss/appXapiIntegratorAgent/index.html
  // so that API calls still go to:
  //   /lookangejss/appXapiIntegratorAgent/api/...
  (function fixAppBase() {
    const rawPath = window.location.pathname || '/';
    // If the last segment looks like a file (has an extension), strip it.
    const withoutFile = rawPath.replace(/\/[^^/]*\.[^/]*$/, '/');
    // Remove a trailing slash (except when the path is just '/')
    const cleaned = withoutFile === '/' ? '/' : withoutFile.replace(/\/$/, '');
    window.__XAPI_APP_BASE__ = cleaned === '/' ? '' : cleaned;
  })();

  const APP_BASE = window.__XAPI_APP_BASE__ || '';
  const apiUrl = (path) => `${APP_BASE}${path}`;

  let selectedFile = null;
  let modelLoadSeq = 0;

  function log(msg) {
    console.log('[integrator]', msg);
    if (logEl) {
      logEl.textContent += (logEl.textContent ? '\n' : '') + msg;
      logEl.scrollTop = logEl.scrollHeight;
    }
  }

  function setStatus(msg, type = 'info') {
    statusContainer.style.display = 'block';
    statusBox.className = 'status-box ' + type;
    statusText.innerHTML = msg;
  }

  function showProgress(show = true) {
    progressBar.style.display = show ? 'block' : 'none';
  }

  function setProgress(msg) {
    progressMsg.textContent = msg;
  }

  function getSelectedMode() {
    const el = document.querySelector('input[name="mode"]:checked');
    return (el && el.value) || 'timeline';
  }

  function shouldKeepAnalytics() {
    const checkbox = document.getElementById('keepAnalytics');
    return checkbox ? checkbox.checked : false;
  }

  function shouldEnableAI() {
    const checkbox = document.getElementById('enableAi');
    return checkbox ? checkbox.checked : true;
  }

  function getCustomInstructions() {
    const textarea = document.getElementById('customInstructions');
    return (textarea && textarea.value.trim()) || '';
  }

  function getSelectedAIProvider() {
    const sel = document.getElementById('aiProvider');
    return (sel && sel.value) ? sel.value : 'openai';
  }

  function getSelectedAIModel() {
    const sel = document.getElementById('aiModel');
    return (sel && sel.value) ? sel.value : '';
  }

  function getOpenAIApiKey() {
    const input = document.getElementById('openaiApiKey');
    return (input && input.value.trim()) ? input.value.trim() : '';
  }

  function getGeminiApiKey() {
    const input = document.getElementById('geminiApiKey');
    return (input && input.value.trim()) ? input.value.trim() : '';
  }

  function getClaudeApiKey() {
    const input = document.getElementById('claudeApiKey');
    return (input && input.value.trim()) ? input.value.trim() : '';
  }

  function updateKeyStatus(id, hasServerKey, label) {
    const el = document.getElementById(id);
    if (!el) return;
    if (hasServerKey) {
      el.textContent = `${label} key configured on server (•••••)`;
      el.classList.remove('warning');
      el.classList.add('success');
    } else {
      el.textContent = `${label} key not configured on server`;
      el.classList.remove('success');
      el.classList.add('warning');
    }
  }

  function updateKeyPlaceholders(hasOpenAI, hasGemini) {
    const openaiInput = document.getElementById('openaiApiKey');
    const geminiInput = document.getElementById('geminiApiKey');
    const claudeInput = document.getElementById('claudeApiKey');

    if (openaiInput) {
      openaiInput.placeholder = hasOpenAI
        ? 'Optional: override server OpenAI key'
        : 'Paste your OpenAI API key (required if no server key)';
    }
    if (geminiInput) {
      geminiInput.placeholder = hasGemini
        ? 'Optional: override server Gemini key'
        : 'Paste your Gemini API key (required if no server key)';
    }
    if (claudeInput) {
      claudeInput.placeholder = 'Paste your Claude API key (optional)';
    }
  }

  function updateApiKeyVisibility(provider) {
    const rows = document.querySelectorAll('.api-key-row');
    if (!rows.length) return;
    rows.forEach(row => {
      const rowProvider = row.getAttribute('data-provider');
      row.style.display = (rowProvider === provider) ? 'grid' : 'none';
    });
  }

  async function loadAiStatus() {
    try {
      const r = await fetch(apiUrl('/api/status'));
      const data = await r.json();
      if (!r.ok) throw new Error(data?.message || 'Status unavailable');

      const hasOpenAI = !!data?.features?.openaiAgent;
      const hasGemini = !!data?.features?.aiAgent;

      updateKeyStatus('openaiKeyStatus', hasOpenAI, 'OpenAI');
      updateKeyStatus('geminiKeyStatus', hasGemini, 'Gemini');

      const claudeStatus = document.getElementById('claudeKeyStatus');
      if (claudeStatus) {
        claudeStatus.textContent = 'Claude provider not enabled (key optional)';
        claudeStatus.classList.remove('success');
        claudeStatus.classList.add('muted');
      }

      updateKeyPlaceholders(hasOpenAI, hasGemini);
    } catch (e) {
      updateKeyStatus('openaiKeyStatus', false, 'OpenAI');
      updateKeyStatus('geminiKeyStatus', false, 'Gemini');
      updateKeyPlaceholders(false, false);
    }
  }

  async function loadGeminiModels(loadId) {
    const sel = document.getElementById('aiModel');
    if (!sel) return;
    if (loadId !== modelLoadSeq) return;

    try {
      const r = await fetch(apiUrl('/api/ai-models'));
      const data = await r.json();

      if (loadId !== modelLoadSeq) return;
      if (!r.ok || !data.ok) {
        sel.innerHTML = '<option value="">(Models unavailable)</option>';
        return;
      }

      // Only models that can generateContent
      const models = (data.models || [])
        .filter(m => Array.isArray(m.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'));

      // Prefer showing only the specific models you care about.
      // Note: We only show models that actually exist in /api/ai-models for your key.
      const preferredAllowList = [
        // Gemini 2 Flash
        'models/gemini-2.0-flash',
        // Gemini 2.5 Flash
        'models/gemini-2.5-flash',
        // Gemini 3 Flash / Pro (if/when enabled on your account)
        'models/gemini-3-flash',
        'models/gemini-3-flash-preview',
        'models/gemini-3-pro',
        'models/gemini-3-pro-preview'
      ];

      const filteredPreferred = models.filter(m => preferredAllowList.includes(m.name));
      const finalModels = filteredPreferred.length > 0 ? filteredPreferred : models;

      // Prefer latest models first (newest → oldest)
      const preferredOrder = [
        'models/gemini-3-pro-preview',
        'models/gemini-3-pro',
        'models/gemini-3-flash-preview',
        'models/gemini-3-flash',
        'models/gemini-2.5-pro',
        'models/gemini-2.5-flash',
        'models/gemini-2.0-flash',
        'models/gemini-2.0-flash-lite',
      ];

      finalModels.sort((a, b) => {
        const ai = preferredOrder.indexOf(a.name);
        const bi = preferredOrder.indexOf(b.name);
        if (ai !== -1 || bi !== -1) return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
        return String(a.name).localeCompare(String(b.name));
      });

      const toSdkId = (apiName) => String(apiName || '').replace(/^models\//, '');

      if (loadId !== modelLoadSeq) return;
      sel.innerHTML = '';
      finalModels.forEach(m => {
        const opt = document.createElement('option');
        opt.value = toSdkId(m.name);
        opt.textContent = `${m.displayName || m.name} (${opt.value})`;
        sel.appendChild(opt);
      });

      // Preselect top option (latest model)
      if (sel.options.length > 0) {
        sel.selectedIndex = 0;
      }
    } catch (e) {
      if (loadId !== modelLoadSeq) return;
      sel.innerHTML = '<option value="">(Models unavailable)</option>';
    }
  }

  async function loadOpenAIModels(loadId) {
    const sel = document.getElementById('aiModel');
    if (!sel) return;
    if (loadId !== modelLoadSeq) return;

    try {
      const r = await fetch(apiUrl('/api/openai-models'));
      const data = await r.json();

      if (loadId !== modelLoadSeq) return;
      if (!r.ok || !data.ok) {
        sel.innerHTML = '<option value="">(Models unavailable)</option>';
        return;
      }

      const models = Array.isArray(data.models) ? data.models : [];
      // Backend now only returns chat-capable models (gpt-4o, gpt-4o-mini).
      const finalModels = models;
      if (loadId !== modelLoadSeq) return;
      sel.innerHTML = '';
      finalModels.forEach(m => {
        const opt = document.createElement('option');
        opt.value = m.id;
        opt.textContent = m.label || m.id;
        sel.appendChild(opt);
      });

      // Default to the latest small model (gpt-5-mini) if available
      const defaultId = 'gpt-5-mini';
      const match = Array.from(sel.options).find(o => o.value === defaultId);
      if (match) sel.value = defaultId;
    } catch (e) {
      if (loadId !== modelLoadSeq) return;
      sel.innerHTML = '<option value="">(Models unavailable)</option>';
    }
  }

  async function loadModelsForProvider(provider) {
    const sel = document.getElementById('aiModel');
    if (!sel) return;
    const loadId = ++modelLoadSeq;
    sel.innerHTML = '<option value="">Loading models...</option>';
    if (provider === 'openai') {
      await loadOpenAIModels(loadId);
    } else if (provider === 'claude') {
      if (loadId !== modelLoadSeq) return;
      const claudeModels = [
        { id: 'claude-opus-4.5', label: 'Opus 4.5' },
        { id: 'claude-sonnet-4.5', label: 'Sonnet 4.5' },
        { id: 'claude-haiku-4.5', label: 'Haiku 4.5' }
      ];
      sel.innerHTML = '';
      claudeModels.forEach(model => {
        const opt = document.createElement('option');
        opt.value = model.id;
        opt.textContent = `${model.label} (${model.id})`;
        sel.appendChild(opt);
      });
      sel.value = claudeModels[0]?.id || '';
    } else {
      await loadGeminiModels(loadId);
    }
  }

  // Drag and drop
  if (dropZone) {
    ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
      dropZone.addEventListener(eventName, (e) => {
        e.preventDefault();
        e.stopPropagation();
      }, false);
    });

    ['dragenter', 'dragover'].forEach(eventName => {
      dropZone.addEventListener(eventName, () => {
        dropZone.classList.add('drag-over');
      }, false);
    });

    ['dragleave', 'drop'].forEach(eventName => {
      dropZone.addEventListener(eventName, () => {
        dropZone.classList.remove('drag-over');
      }, false);
    });

    dropZone.addEventListener('drop', async (e) => {
      const files = e.dataTransfer.files;
      if (files.length > 0) {
        handleFile(files[0]);
      }
    }, false);

    dropZone.addEventListener('click', () => {
      zipInput.click();
    });
  }

  if (zipInput) {
    zipInput.addEventListener('change', (e) => {
      const file = e.target.files[0];
      if (file) {
        handleFile(file);
      }
    });
  }

  function handleFile(file) {
    if (file && (file.type === 'application/zip' || file.name.endsWith('.zip'))) {
      selectedFile = file;
      if (fileName) {
        fileName.textContent = `📦 ${file.name}`;
      }
      log(`File selected: ${file.name}`);
      integrateBtn.disabled = false;
      integrateBtn.textContent = '🔄 Integrate';
      
      // Analyze file
      analyzeFile(file);
    } else {
      setStatus('Please select a ZIP file.', 'error');
    }
  }

  async function analyzeFile(file) {
    log('📊 Analyzing content...');
    setProgress(true);
    setProgress('Analyzing...');
    
    try {
      // We'll do analysis on the server side
      log('✓ File ready for processing');
    } catch (error) {
      log('⚠️ Analysis error: ' + error.message);
    }
  }

  if (integrateBtn) {
    integrateBtn.addEventListener('click', async () => {
      if (!selectedFile) {
        setStatus('Please select a ZIP file first.', 'error');
        return;
      }

      await integrate();
    });
  }

  async function integrate() {
    const mode = getSelectedMode();
    const keepAnalytics = shouldKeepAnalytics();
    const customInstructions = getCustomInstructions();
    const enableAi = shouldEnableAI();
    const aiProvider = getSelectedAIProvider();
    const aiModel = getSelectedAIModel();
    const openaiApiKey = getOpenAIApiKey();
    const geminiApiKey = getGeminiApiKey();
    const claudeApiKey = getClaudeApiKey();

    log(`\n🚀 Starting integration...`);
    log(`Mode: ${mode.toUpperCase()}`);
    log(`Keep Analytics: ${keepAnalytics}`);
    log(`AI Augmentation: ${enableAi}`);
    log(`AI Provider: ${aiProvider}`);
    if (aiModel) log(`AI Model: ${aiModel}`);
    if (customInstructions) {
      log(`📋 Custom Instructions: ${customInstructions.substring(0, 60)}${customInstructions.length > 60 ? '...' : ''}`);
    }

    integrateBtn.disabled = true;
    integrateBtn.textContent = '⏳ Processing...';
    setStatus('Processing your ZIP file...', 'info');
    showProgress(true);
    setProgress('Uploading and analyzing...');

    try {
      const formData = new FormData();
      formData.append('file', selectedFile);
      formData.append('mode', mode);
      formData.append('keepAnalytics', keepAnalytics);
      formData.append('enableAi', enableAi);
      formData.append('aiProvider', aiProvider);
      if (aiModel) formData.append('aiModel', aiModel);
      if (customInstructions) {
        formData.append('customInstructions', customInstructions);
      }
      if (openaiApiKey) formData.append('openaiApiKey', openaiApiKey);
      if (geminiApiKey) formData.append('geminiApiKey', geminiApiKey);
      if (claudeApiKey) formData.append('claudeApiKey', claudeApiKey);

      const response = await fetch(apiUrl('/api/upload'), {
        method: 'POST',
        body: formData
      });

      const result = await response.json();

      if (!response.ok) {
        throw new Error(result.error || 'Integration failed');
      }

      // Log all steps
      if (result.log && Array.isArray(result.log)) {
        result.log.forEach(msg => log(msg));
      }

      // Show analysis results
      if (result.analysis) {
        const analysis = result.analysis;
        log(`\n📊 Analysis Results:`);
        log(`Recommended Mode: ${analysis.recommendedMode.toUpperCase()} (${analysis.confidence}% confidence)`);
        if (analysis.reasons.length > 0) {
          analysis.reasons.forEach(reason => log(`  • ${reason}`));
        }
      }

      // Show AI thinking if available
      if (result.aiThinking && result.aiThinking.chainOfThought) {
        log(`\n🤖 AI Agent Thinking Process:`);
        log(`\n--- CHAIN OF THOUGHT ---`);
        log(result.aiThinking.chainOfThought);
        
        if (result.aiThinking.trackingStrategy) {
          log(`\n--- TRACKING STRATEGY ---`);
          log(result.aiThinking.trackingStrategy);
        }
        
        if (result.aiThinking.codeApproach) {
          log(`\n--- CODE APPROACH ---`);
          log(result.aiThinking.codeApproach);
        }
        
        if (result.aiThinking.codeBreakdown) {
          log(`\n--- CODE BREAKDOWN ---`);
          log(result.aiThinking.codeBreakdown);
        }
        
        if (result.aiThinking.explanation) {
          log(`\n--- DETAILED EXPLANATION ---`);
          log(result.aiThinking.explanation);
        }
      }

      // Show AI meta status/timing if available
      if (result.aiMeta) {
        log(`\n🤖 AI Agent Status:`);
        log(`  • Requested: ${result.aiMeta.requested}`);
        log(`  • Enabled: ${result.aiMeta.enabled}`);
        log(`  • Status: ${result.aiMeta.status}`);
        if (result.aiMeta.model) {
          log(`  • Model: ${result.aiMeta.model}`);
        }
        if (result.aiMeta.startedAt) {
          log(`  • Started: ${result.aiMeta.startedAt}`);
        }
        if (result.aiMeta.finishedAt) {
          log(`  • Finished: ${result.aiMeta.finishedAt}`);
        }
        if (typeof result.aiMeta.durationMs === 'number') {
          log(`  • Duration: ${result.aiMeta.durationMs}ms`);
        }
        if (result.aiMeta.error) {
          log(`  • Error: ${result.aiMeta.error}`);
        }
      }

      // Success
      log(`\n✅ Integration complete!`);
      // Prefix download URL with APP_BASE if it's a root-relative path
      if (result.downloadUrl && typeof result.downloadUrl === 'string') {
        downloadLink.href = result.downloadUrl.startsWith('/')
          ? `${APP_BASE}${result.downloadUrl}`
          : result.downloadUrl;
      } else {
        downloadLink.href = '#';
      }
      downloadLink.download = result.filename;
      downloadLink.style.display = 'inline-block';

      setStatus(`✅ Success! Your file is ready to download. Check the log to see the AI's thinking process.`, 'success');
      showProgress(false);

      integrateBtn.textContent = '🔄 Integrate Another';
      integrateBtn.disabled = false;

    } catch (error) {
      console.error('Integration error:', error);
      log(`❌ Error: ${error.message}`);
      setStatus(`❌ Error: ${error.message}`, 'error');
      showProgress(false);

      integrateBtn.textContent = '🔄 Try Again';
      integrateBtn.disabled = false;
    }
  }

  // Initialize
  log('✓ xAPI Integrator loaded');
  setStatus('Ready! Upload a ZIP file to begin.', 'info');
  const providerSel = document.getElementById('aiProvider');
  if (providerSel) {
    providerSel.addEventListener('change', () => {
      const provider = getSelectedAIProvider();
      loadModelsForProvider(provider);
      updateApiKeyVisibility(provider);
    });
  }
  const initialProvider = getSelectedAIProvider();
  loadModelsForProvider(initialProvider);
  updateApiKeyVisibility(initialProvider);
  loadAiStatus();
})();
