import { PROVIDERS, getProviderById } from '../lib/providers.js';
import { getSettings, saveSettings, getApiKeys, getConversations, saveConversation, generateId, formatTimestamp, renderMarkdown, escapeHtml, getActiveConversationId, setActiveConversationId } from '../lib/utils.js';
import { runChat } from '../lib/chat-engine.js';
import { getTranslations } from '../lib/i18n.js';

const providerSelect = document.getElementById('provider-select');
const modelSelect = document.getElementById('model-select');
const chatContainer = document.getElementById('chat-container');
const userInput = document.getElementById('user-input');
const btnSend = document.getElementById('btn-send');
const btnStop = document.getElementById('btn-stop');
const btnHistory = document.getElementById('btn-history');
const btnSettings = document.getElementById('btn-settings');
const btnPinModel = document.getElementById('btn-pin-model');
const btnAddApiKey = document.getElementById('btn-add-api-key');
const historySidebar = document.getElementById('chat-history-sidebar');
const chatHistoryList = document.getElementById('chat-history-list');
const btnCloseSidebar = document.getElementById('btn-close-sidebar');
const btnNewChatSidebar = document.getElementById('btn-new-chat-sidebar');
const btnExportChat = document.getElementById('btn-export-chat');
const apiKeyModal = document.getElementById('api-key-modal');
const settingsModal = document.getElementById('settings-modal');
const btnCloseSettings = document.getElementById('btn-close-settings');
const btnOpenFullSettings = document.getElementById('btn-open-full-settings');
const settingsLanguage = document.getElementById('settings-language');
const settingsTheme = document.getElementById('settings-theme');
const settingsFontSize = document.getElementById('settings-font-size');
const settingsExport = document.getElementById('settings-export');
const apiKeyModalTitle = document.getElementById('api-key-modal-title');
const apiKeyModalInput = document.getElementById('api-key-modal-input');
const apiKeyModalSave = document.getElementById('api-key-modal-save');
const apiKeyModalCancel = document.getElementById('api-key-modal-cancel');

let currentMessages = [];
let currentConversationId = null;
let isGenerating = false;
let abortController = null;
let apiKeysCache = {};
let currentLang = 'de';

function tr(key) {
  const t = getTranslations(currentLang);
  return t[key] || key;
}

async function applyI18n(lang) {
  currentLang = lang;
  const translations = getTranslations(lang);
  document.querySelectorAll('[data-i18n]').forEach(el => {
    const key = el.getAttribute('data-i18n');
    if (translations[key]) el.textContent = translations[key];
  });
  document.querySelectorAll('[data-i18n-title]').forEach(el => {
    const key = el.getAttribute('data-i18n-title');
    if (translations[key]) el.title = translations[key];
  });
  document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
    const key = el.getAttribute('data-i18n-placeholder');
    if (translations[key]) el.placeholder = translations[key];
  });
}

async function init() {
  const settings = await getSettings();
  currentLang = settings.language || 'de';
  apiKeysCache = await getApiKeys();
  await applyI18n(currentLang);
  await populateProviders();
  await loadConversation();
  await loadChatHistory();
  updatePinButton();
  bindEvents();
}

async function populateProviders() {
  const settings = await getSettings();
  const t = getTranslations(currentLang);

  providerSelect.innerHTML = '';
  const providersWithKeys = PROVIDERS.filter(p => apiKeysCache[p.id]?.trim());
  const providersWithoutKeys = PROVIDERS.filter(p => !apiKeysCache[p.id]?.trim());

  if (providersWithKeys.length > 0) {
    const group = document.createElement('optgroup');
    group.label = t.configured;
    providersWithKeys.forEach(p => {
      const opt = document.createElement('option');
      opt.value = p.id;
      opt.textContent = p.name;
      group.appendChild(opt);
    });
    providerSelect.appendChild(group);
  }

  const group = document.createElement('optgroup');
  group.label = t.noApiKey;
  providersWithoutKeys.forEach(p => {
    const opt = document.createElement('option');
    opt.value = p.id;
    opt.textContent = `${p.name}`;
    group.appendChild(opt);
  });
  providerSelect.appendChild(group);

  const lastProvider = settings.lastUsedProvider || settings.defaultProvider;
  if (lastProvider && providersWithKeys.find(p => p.id === lastProvider)) {
    providerSelect.value = lastProvider;
  } else {
    providerSelect.value = providersWithKeys[0]?.id || '';
  }

  updateModelSelect();
}

function updateModelSelect() {
  const provider = getProviderById(providerSelect.value);
  modelSelect.innerHTML = '';

  if (!provider) return;

  const settings = getSettingsSync();
  const pinnedModel = settings.pinnedModels?.[provider.id];

  provider.models.forEach(model => {
    const opt = document.createElement('option');
    opt.value = model;
    const pin = model === pinnedModel ? ' ★' : '';
    opt.textContent = model + pin;
    modelSelect.appendChild(opt);
  });

  if (provider.models.length === 0) {
    const opt = document.createElement('option');
    opt.value = 'default';
    opt.textContent = 'Standard';
    modelSelect.appendChild(opt);
  }

  const lastModel = settings.lastUsedModels?.[provider.id] || pinnedModel;
  if (lastModel) {
    modelSelect.value = lastModel;
  } else if (settings.defaultModel) {
    modelSelect.value = settings.defaultModel;
  }
}

async function getSettingsSync() {
  return await getSettings();
}

function updatePinButton() {
  const t = getTranslations(currentLang);
  const providerId = providerSelect.value;
  const model = modelSelect.value;
  const settings = getSettingsSync();
  const isPinned = settings.pinnedModels?.[providerId] === model;
  btnPinModel.classList.toggle('pinned', isPinned);
  btnPinModel.title = isPinned ? t.modelPinned : t.modelPin;

  const hasKey = apiKeysCache[providerId]?.trim();
  btnAddApiKey.classList.toggle('no-key', !hasKey);
  btnAddApiKey.title = hasKey ? t.apiKeyPresent : t.apiKeyAdd;
}

async function togglePinModel() {
  const providerId = providerSelect.value;
  const model = modelSelect.value;
  const settings = await getSettings();
  if (!settings.pinnedModels) settings.pinnedModels = {};

  if (settings.pinnedModels[providerId] === model) {
    delete settings.pinnedModels[providerId];
  } else {
    settings.pinnedModels[providerId] = model;
  }

  await saveSettings(settings);
  updatePinButton();
  updateModelSelect();
}

async function saveLastUsed() {
  const providerId = providerSelect.value;
  const model = modelSelect.value;
  const settings = await getSettings();
  settings.lastUsedProvider = providerId;
  if (!settings.lastUsedModels) settings.lastUsedModels = {};
  settings.lastUsedModels[providerId] = model;
  await saveSettings(settings);
}

function bindEvents() {
  providerSelect.addEventListener('change', () => {
    updateModelSelect();
    saveLastUsed();
    updatePinButton();

    const provider = getProviderById(providerSelect.value);
    if (provider && !apiKeysCache[provider.id]?.trim()) {
      showApiKeyModal(provider);
    }
  });

  btnAddApiKey.addEventListener('click', () => {
    const provider = getProviderById(providerSelect.value);
    if (provider) {
      showApiKeyModal(provider);
    }
  });

  modelSelect.addEventListener('change', () => {
    saveLastUsed();
    updatePinButton();
  });

  btnSend.addEventListener('click', handleSend);
  btnStop.addEventListener('click', () => {
    if (abortController) {
      abortController.abort();
      isGenerating = false;
      btnSend.classList.remove('hidden');
      btnStop.classList.add('hidden');
    }
  });

  userInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  });

  userInput.addEventListener('input', autoResize);

  btnHistory.addEventListener('click', () => {
    historySidebar.classList.toggle('open');
    if (historySidebar.classList.contains('open')) {
      loadChatHistory();
    }
  });

  btnCloseSidebar.addEventListener('click', () => {
    historySidebar.classList.remove('open');
  });

  btnNewChatSidebar.addEventListener('click', async () => {
    currentMessages = [];
    currentConversationId = null;
    await setActiveConversationId(null);
    chatContainer.innerHTML = '';
    historySidebar.classList.remove('open');
    await loadChatHistory();
  });

  btnExportChat.addEventListener('click', exportChatAsMarkdown);

  btnSettings.addEventListener('click', () => {
    openSettingsModal();
  });

  btnPinModel.addEventListener('click', togglePinModel);

  document.querySelectorAll('.quick-bar-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      userInput.value = btn.dataset.prompt;
      autoResize();
      userInput.focus();
    });
  });

  apiKeyModalSave.addEventListener('click', saveApiKeyFromModal);
  apiKeyModalCancel.addEventListener('click', closeApiKeyModal);
  apiKeyModal.addEventListener('click', (e) => {
    if (e.target === apiKeyModal) closeApiKeyModal();
  });
  apiKeyModalInput.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') saveApiKeyFromModal();
    if (e.key === 'Escape') closeApiKeyModal();
  });

  document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && isGenerating) {
      e.preventDefault();
      if (abortController) {
        abortController.abort();
        isGenerating = false;
        btnSend.classList.remove('hidden');
        btnStop.classList.add('hidden');
      }
    }
    if (e.key === 'n' && e.ctrlKey && !isGenerating) {
      e.preventDefault();
      btnNewChatSidebar.click();
    }
  });

  btnCloseSettings.addEventListener('click', closeSettingsModal);
  settingsModal.addEventListener('click', (e) => {
    if (e.target === settingsModal) closeSettingsModal();
  });

  settingsLanguage.addEventListener('change', async (e) => {
    const s = await getSettings();
    s.language = e.target.value;
    await saveSettings(s);
    await applyI18n(s.language);
  });

  settingsTheme.addEventListener('change', async (e) => {
    const s = await getSettings();
    s.theme = e.target.value;
    await saveSettings(s);
    document.documentElement.setAttribute('data-theme', e.target.value);
    chrome.storage.sync.set({ theme: e.target.value });
  });

  settingsFontSize.addEventListener('change', async (e) => {
    const s = await getSettings();
    s.fontSize = e.target.value;
    await saveSettings(s);
    const sizes = { small: '12px', medium: '13px', large: '15px' };
    document.documentElement.style.setProperty('--font-size-base', sizes[e.target.value] || '13px');
  });

  settingsExport.addEventListener('click', () => {
    exportChatAsMarkdown();
  });

  btnOpenFullSettings.addEventListener('click', () => {
    closeSettingsModal();
    chrome.runtime.sendMessage({ type: 'SYNTRIX_OPEN_OPTIONS' });
  });
}

function autoResize() {
  userInput.style.height = 'auto';
  userInput.style.height = Math.min(userInput.scrollHeight, 120) + 'px';
}

async function openSettingsModal() {
  const settings = await getSettings();
  settingsLanguage.value = settings.language || 'de';
  settingsTheme.value = settings.theme || 'dark';
  settingsFontSize.value = settings.fontSize || 'medium';
  settingsModal.classList.add('open');
}

function closeSettingsModal() {
  settingsModal.classList.remove('open');
}

function exportChatAsMarkdown() {
  if (currentMessages.length === 0) return;
  let md = '# Syntrix Nova Chat\n\n';
  const date = new Date().toLocaleString();
  md += `*Exportiert am ${date}*\n\n---\n\n`;
  for (const msg of currentMessages) {
    if (msg.role === 'user') {
      md += `## Du\n\n${msg.content}\n\n`;
    } else if (msg.role === 'assistant') {
      md += `## Syntrix Nova\n\n${msg.content || ''}\n\n`;
      if (msg.tools && msg.tools.length > 0) {
        for (const tool of msg.tools) {
          md += `<details>\n<summary>Tool: ${tool.name} ${tool.error ? '❌' : '✓'}</summary>\n\n\`\`\`\n${typeof tool.result === 'string' ? tool.result : JSON.stringify(tool.result, null, 2)}\n\`\`\`\n</details>\n\n`;
        }
      }
    }
  }
  const blob = new Blob([md], { type: 'text/markdown' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `syntrix-chat-${Date.now()}.md`;
  a.click();
  URL.revokeObjectURL(url);
}

let pendingApiKeyProviderId = null;

function showApiKeyModal(provider) {
  const t = getTranslations(currentLang);
  pendingApiKeyProviderId = provider.id;
  apiKeyModalTitle.textContent = `${t.enterApiKey} (${provider.name})`;
  apiKeyModalInput.value = '';
  apiKeyModal.classList.add('open');
  apiKeyModalInput.focus();
}

async function saveApiKeyFromModal() {
  if (!pendingApiKeyProviderId) return;
  const key = apiKeyModalInput.value.trim();
  apiKeysCache[pendingApiKeyProviderId] = key;
  const { saveApiKeys } = await import('../lib/utils.js');
  await saveApiKeys(apiKeysCache);
  closeApiKeyModal();
  await populateProviders();
}

function closeApiKeyModal() {
  apiKeyModal.classList.remove('open');
  pendingApiKeyProviderId = null;
}

async function loadConversation() {
  const convId = await getActiveConversationId();
  if (!convId) return;
  const conversations = await getConversations();
  const conv = conversations[convId];
  if (!conv) return;
  currentConversationId = convId;
  currentMessages = conv.messages || [];
  renderMessages(currentMessages);
}

async function loadChatHistory() {
  const t = getTranslations(currentLang);
  const conversations = await getConversations();
  const sorted = Object.entries(conversations)
    .sort((a, b) => (b[1].createdAt || 0) - (a[1].createdAt || 0));

  chatHistoryList.innerHTML = '';

  if (sorted.length === 0) {
    chatHistoryList.innerHTML = `<div style="padding:12px;color:var(--text-muted);font-size:12px;text-align:center;">${t.noChats}</div>`;
    return;
  }

  for (const [id, conv] of sorted) {
    const firstMsg = conv.messages?.find(m => m.role === 'user');
    const title = firstMsg?.content?.slice(0, 40) || t.emptyChat;
    const timeStr = conv.createdAt ? formatTimestamp(conv.createdAt) : '';
    const provider = getProviderById(conv.providerId);

    const item = document.createElement('div');
    item.className = `sidebar-list-item${id === currentConversationId ? ' active' : ''}`;
    item.style.position = 'relative';
    item.innerHTML = `
      <span class="sidebar-list-item-title">${escapeHtml(title)}</span>
      <span class="sidebar-list-item-meta">${provider?.name || conv.providerId} · ${timeStr}</span>
      <button class="sidebar-list-item-delete" title="${t.deleteChat}">×</button>
    `;

    item.addEventListener('click', async (e) => {
      if (e.target.classList.contains('sidebar-list-item-delete')) {
        e.stopPropagation();
        if (confirm(t.deleteChatConfirm)) {
          const { deleteConversation } = await import('../lib/utils.js');
          await deleteConversation(id);
          if (id === currentConversationId) {
            currentMessages = [];
            currentConversationId = null;
            chatContainer.innerHTML = '';
          }
          await loadChatHistory();
        }
        return;
      }
      currentConversationId = id;
      currentMessages = conv.messages || [];
      await setActiveConversationId(id);
      chatContainer.innerHTML = '';
      renderMessages(currentMessages);
      historySidebar.classList.remove('open');
      await loadChatHistory();

      if (conv.providerId) providerSelect.value = conv.providerId;
      if (conv.model) modelSelect.value = conv.model;
      updateModelSelect();
    });

    chatHistoryList.appendChild(item);
  }
}

function renderMessages(messages) {
  messages.forEach(msg => {
    if (msg.role === 'user') {
      appendUserMessage(msg.content);
    } else if (msg.role === 'assistant') {
      appendAssistantMessage(msg.content, msg.tools);
    }
  });
  scrollToBottom();
}

function appendUserMessage(content) {
  const div = document.createElement('div');
  div.className = 'message user';
  div.innerHTML = `
    <div class="message-body">${escapeHtml(content)}</div>
    <div class="message-avatar">DU</div>
  `;
  chatContainer.appendChild(div);
  scrollToBottom();
}

function appendAssistantMessage(content, tools = []) {
  const t = getTranslations(currentLang);
  const div = document.createElement('div');
  div.className = 'message assistant';
  let toolsHtml = '';
  for (const tool of tools) {
    const resultStr = typeof tool.result === 'string' ? escapeHtml(tool.result) : escapeHtml(JSON.stringify(tool.result, null, 2));
    toolsHtml += `
      <div class="tool-block open">
        <div class="tool-header">
          <span style="display:flex;align-items:center;gap:4px;">
            <span class="tool-chevron">▶</span>
            <span class="tool-name">${escapeHtml(tool.name)}</span>
          </span>
          <span>${tool.error ? '❌ ' + t.error : '✓'}</span>
        </div>
        <div class="tool-content">${resultStr}</div>
      </div>
    `;
  }
  div.innerHTML = `
    <div class="message-avatar">SN</div>
    <div class="message-body">${renderMarkdown(content)}${toolsHtml}</div>
  `;
  chatContainer.appendChild(div);
  scrollToBottom();
  return div;
}

function createStreamingMessage() {
  const div = document.createElement('div');
  div.className = 'message assistant';
  div.innerHTML = `
    <div class="message-avatar">SN</div>
    <div class="message-body">
      <div class="typing-indicator"><span></span><span></span><span></span></div>
    </div>
  `;
  chatContainer.appendChild(div);
  scrollToBottom();
  return div;
}

function appendToolBlock(chatEl, name, args) {
  const t = getTranslations(currentLang);
  const body = chatEl.querySelector('.message-body');
  const div = document.createElement('div');
  div.className = 'tool-block';
  div.innerHTML = `
    <div class="tool-header">
      <span style="display:flex;align-items:center;gap:4px;">
        <span class="tool-chevron">▶</span>
        <span class="tool-name">${escapeHtml(name)}</span>
      </span>
      <span class="tool-status">⏳ ${t.executing}</span>
    </div>
    <div class="tool-content">${escapeHtml(JSON.stringify(args, null, 2))}</div>
  `;
  div.querySelector('.tool-header').addEventListener('click', () => {
    div.classList.toggle('open');
  });
  body.appendChild(div);
  scrollToBottomIfNear();
  return div;
}

function updateToolBlock(toolEl, result, isError = false) {
  const t = getTranslations(currentLang);
  const status = toolEl.querySelector('.tool-status');
  status.textContent = isError ? `❌ ${t.error}` : `✓ ${t.done}`;
  const content = toolEl.querySelector('.tool-content');
  const resultStr = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
  content.textContent = resultStr;
  toolEl.classList.add('open');
}

function scrollToBottom() {
  chatContainer.scrollTop = chatContainer.scrollHeight;
}

function isNearBottom(threshold = 100) {
  return chatContainer.scrollHeight - chatContainer.scrollTop - chatContainer.clientHeight < threshold;
}

function scrollToBottomIfNear() {
  if (isNearBottom()) {
    chatContainer.scrollTop = chatContainer.scrollHeight;
  }
}

async function handleSend() {
  const content = userInput.value.trim();
  if (!content || isGenerating) return;

  const t = getTranslations(currentLang);
  isGenerating = true;
  btnSend.classList.add('hidden');
  btnStop.classList.remove('hidden');
  abortController = new AbortController();
  const settingsWithSignal = { ...await getSettings(), signal: abortController.signal };

  appendUserMessage(content);
  userInput.value = '';
  autoResize();

  const userMsg = { role: 'user', content };
  currentMessages.push(userMsg);

  const providerId = providerSelect.value;
  const model = modelSelect.value;
  const providerName = getProviderById(providerId)?.name || providerId;
  await saveLastUsed();

  const streamingEl = createStreamingMessage();
  const bodyEl = streamingEl.querySelector('.message-body');
  let fullContent = '';
  let toolResults = [];

  try {
    const result = await runChat(
      providerId,
      model,
      currentMessages,
      (chunk) => {
        if (abortController.signal.aborted) return;
        const typing = bodyEl.querySelector('.typing-indicator');
        if (typing) typing.remove();

        if (chunk.type === 'content') {
          fullContent += chunk.content;
          const rendered = renderMarkdown(fullContent);
          const toolsHtml = toolResults.map(tool => {
            const r = typeof tool.result === 'string' ? escapeHtml(tool.result) : escapeHtml(JSON.stringify(tool.result, null, 2));
            return `<div class="tool-block open"><div class="tool-header"><span style="display:flex;align-items:center;gap:4px;"><span class="tool-chevron">▶</span><span class="tool-name">${escapeHtml(tool.name)}</span></span><span>${tool.error ? '❌' : '✓'}</span></div><div class="tool-content">${r}</div></div>`;
          }).join('');
          bodyEl.innerHTML = rendered + toolsHtml;
          scrollToBottomIfNear();
        }
        if (chunk.type === 'tool_start') {
          const toolEl = appendToolBlock(streamingEl, chunk.name, chunk.args);
          toolEl._toolName = chunk.name;
          toolEl._toolArgs = chunk.args;
        }
        if (chunk.type === 'tool_end') {
          const allToolEls = bodyEl.querySelectorAll('.tool-block');
          const lastTool = allToolEls[allToolEls.length - 1];
          if (lastTool) {
            const isError = chunk.result?.error;
            updateToolBlock(lastTool, chunk.result, isError);
            toolResults.push({ name: chunk.name, result: chunk.result, error: isError });
          }
        }
        if (chunk.type === 'error') {
          bodyEl.innerHTML += `<div class="error-text">${t.error}: ${escapeHtml(chunk.content)}</div>`;
        }
      },
      null,
      { tab: { id: (await chrome.tabs.query({ active: true, currentWindow: true }))[0]?.id } },
      settingsWithSignal
    );

    if (result) {
      currentMessages.push({ role: 'assistant', content: result.content, tools: toolResults });
    }
  } catch (e) {
    const t = getTranslations(currentLang);
    if (e.message !== 'Aborted') {
      bodyEl.innerHTML += `<div class="error-text">${t.error}: ${escapeHtml(e.message)}</div>`;
    }
  }

  isGenerating = false;
  btnSend.classList.remove('hidden');
  btnStop.classList.add('hidden');

  if (!currentConversationId) {
    currentConversationId = generateId();
    await setActiveConversationId(currentConversationId);
  }
  await saveConversation(currentConversationId, { messages: currentMessages, providerId, model, createdAt: Date.now() });
  await loadChatHistory();
}

init();
