// ═══════════════════════════════════════════════════════
//  CVC Dashboard — Chat Module
// ═══════════════════════════════════════════════════════
import type { ChatMessage } from './types';
import * as api from './api';

declare const marked: { parse(md: string): string };

let chatHistory: ChatMessage[] = [];
let isStreaming = false;

export function initChat(): void {
  const input = document.getElementById('chat-input') as HTMLTextAreaElement;
  const sendBtn = document.getElementById('chat-send') as HTMLButtonElement;

  // Auto-resize textarea
  input.addEventListener('input', () => {
    input.style.height = 'auto';
    input.style.height = Math.min(input.scrollHeight, 200) + 'px';
  });

  // Ctrl+Enter / Cmd+Enter to send
  input.addEventListener('keydown', (e: KeyboardEvent) => {
    if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
      e.preventDefault();
      sendMessage();
    }
  });

  sendBtn.addEventListener('click', sendMessage);

  // Suggestion buttons
  document.querySelectorAll('.suggestion-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      const msg = (btn as HTMLElement).dataset.msg;
      if (msg) {
        input.value = msg;
        sendMessage();
      }
    });
  });

  // Load current model
  loadChatModel();
}

async function loadChatModel(): Promise<void> {
  try {
    const m = await api.getCurrentModel();
    const tag = document.getElementById('chat-model');
    if (tag) tag.textContent = m.model || m.provider || '—';
  } catch { /* ignore */ }
}

async function sendMessage(): Promise<void> {
  if (isStreaming) return;
  const input = document.getElementById('chat-input') as HTMLTextAreaElement;
  const text = input.value.trim();
  if (!text) return;

  input.value = '';
  input.style.height = 'auto';

  // Remove welcome screen
  const welcome = document.querySelector('.chat-welcome');
  if (welcome) welcome.remove();

  // Add user message
  const userMsg: ChatMessage = { role: 'user', content: text };
  chatHistory.push(userMsg);
  appendMessage(userMsg);

  // Stream assistant response (with tool calls)
  isStreaming = true;
  const assistantMsg: ChatMessage = { role: 'assistant', content: '' };
  chatHistory.push(assistantMsg);
  const msgEl = appendMessage(assistantMsg, true);
  const bodyEl = msgEl.querySelector('.chat-message-body') as HTMLElement;
  let contentEl = bodyEl.querySelector('.msg-content') as HTMLElement;

  try {
    const stream = api.chatStream({
      messages: chatHistory.slice(0, -1),
      stream: true,
    });

    for await (const event of stream) {
      if (event.type === 'text') {
        assistantMsg.content += event.content ?? '';
        renderMarkdown(contentEl, assistantMsg.content);
      } else if (event.type === 'tool_start') {
        const card = createToolCard(event.name ?? '', event.args ?? {});
        bodyEl.appendChild(card);
      } else if (event.type === 'tool_result') {
        const cards = bodyEl.querySelectorAll(`.tool-card[data-tool="${event.name}"]`);
        const card = cards[cards.length - 1] as HTMLElement | undefined;
        if (card) fillToolResult(card, event.output ?? '');
      } else if (event.type === 'status') {
        showAgentStatus(bodyEl, event.message ?? '');
      }

      if (event.type === 'tool_result') {
        contentEl = ensureFreshContentEl(bodyEl);
        assistantMsg.content = '';
      }

      scrollToBottom();
    }
  } catch (err) {
    assistantMsg.content += `\n\n_Error: ${(err as Error).message}_`;
    renderMarkdown(contentEl, assistantMsg.content);
  }

  const cursor = contentEl.querySelector('.streaming-indicator');
  if (cursor) cursor.remove();
  bodyEl.querySelectorAll('.agent-status').forEach(s => s.remove());
  renderMarkdown(contentEl, assistantMsg.content);
  isStreaming = false;
  scrollToBottom();
}

// ── Tool Card helpers ───────────────────────────

const TOOL_ICONS: Record<string, string> = {
  read_file: '📄', write_file: '✏️', edit_file: '✏️', patch_file: '🩹',
  bash: '🖥️', glob: '🔍', grep: '🔎', list_dir: '📁',
  web_search: '🌐', cvc_status: '📊', cvc_log: '📋', cvc_commit: '💾',
  cvc_branch: '🌿', cvc_restore: '⏮️', cvc_merge: '🔀', cvc_search: '🔍',
  cvc_diff: '📝', cvc_smart_search: '🧠',
};

function createToolCard(toolName: string, args: Record<string, unknown>): HTMLElement {
  const card = document.createElement('div');
  card.className = 'tool-card';
  card.dataset.tool = toolName;

  const icon = TOOL_ICONS[toolName] || '🔧';
  const argsPreview = Object.entries(args).map(([k, v]) => `${k}: ${v}`).join(', ');

  card.innerHTML = `
    <div class="tool-card-header" onclick="this.parentElement.classList.toggle('expanded')">
      <span class="tool-icon">${icon}</span>
      <span class="tool-name">${escHtml(toolName)}</span>
      <span class="tool-args-preview">${escHtml(argsPreview).substring(0, 120)}</span>
      <span class="tool-spinner"></span>
      <span class="tool-chevron">&#9660;</span>
    </div>
    <div class="tool-card-body">
      <div class="tool-args"><strong>Arguments:</strong><pre>${escHtml(JSON.stringify(args, null, 2))}</pre></div>
      <div class="tool-output"><em>Running…</em></div>
    </div>
  `;
  return card;
}

function fillToolResult(card: HTMLElement, output: string): void {
  card.classList.add('completed');
  card.classList.remove('expanded');
  const spinner = card.querySelector('.tool-spinner');
  if (spinner) spinner.remove();
  const outputEl = card.querySelector('.tool-output') as HTMLElement;
  if (outputEl) {
    outputEl.innerHTML = `<strong>Output:</strong><pre>${escHtml(output)}</pre>`;
  }
}

function showAgentStatus(bodyEl: HTMLElement, message: string): void {
  bodyEl.querySelectorAll('.agent-status').forEach(s => s.remove());
  const badge = document.createElement('div');
  badge.className = 'agent-status';
  badge.textContent = message;
  bodyEl.appendChild(badge);
}

function ensureFreshContentEl(bodyEl: HTMLElement): HTMLElement {
  const el = document.createElement('div');
  el.className = 'msg-content';
  bodyEl.appendChild(el);
  return el;
}

function escHtml(s: string): string {
  const d = document.createElement('div');
  d.textContent = s || '';
  return d.innerHTML;
}

function appendMessage(msg: ChatMessage, streaming: boolean = false): HTMLElement {
  const container = document.getElementById('chat-messages')!;
  const el = document.createElement('div');
  el.className = 'chat-message';

  const isUser = msg.role === 'user';
  el.innerHTML = `
    <div class="chat-avatar ${isUser ? 'user' : 'assistant'}">${isUser ? 'U' : 'C'}</div>
    <div class="chat-message-body">
      <div class="role">${isUser ? 'You' : 'CVC Agent'}</div>
      <div class="msg-content">${streaming ? '<span class="streaming-indicator"></span>' : ''}</div>
    </div>
  `;

  if (!streaming && msg.content) {
    const contentEl = el.querySelector('.msg-content') as HTMLElement;
    renderMarkdown(contentEl, msg.content);
  }

  container.appendChild(el);
  scrollToBottom();
  return el;
}

function renderMarkdown(el: HTMLElement, text: string): void {
  try {
    if (typeof marked !== 'undefined') {
      el.innerHTML = marked.parse(text);
    } else {
      el.textContent = text;
    }
  } catch {
    el.textContent = text;
  }
}

function scrollToBottom(): void {
  const container = document.getElementById('chat-messages')!;
  container.scrollTop = container.scrollHeight;
}

export function clearChat(): void {
  chatHistory = [];
  const container = document.getElementById('chat-messages')!;
  container.innerHTML = '';
}
