{% extends "base.html" %}

{% block title %}Agent Chat — Langfuse Lens{% endblock %}
{% block page_title %}<span data-i18n="chat.title">Agent Chat</span>{% endblock %}

{% block content %}
<div class="ai-chat">
  <!-- Conversation thread -->
  <div class="ai-chat-thread" id="chat-thread">
    <!-- Empty state — shown when no messages -->
    <div class="ai-chat-welcome" id="chat-welcome">
      <div class="ai-chat-welcome-icon">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round">
          <path d="M12 2a8 8 0 0 1 8 8c0 3.1-1.7 5.8-4.3 7.1L12 22l-3.7-4.9A8 8 0 0 1 12 2z"/>
          <circle cx="12" cy="10" r="2"/>
        </svg>
      </div>
      <h2 class="ai-chat-welcome-title" data-i18n="chat.welcomeTitle">Langfuse Lens Agent</h2>
      <p class="ai-chat-welcome-sub" data-i18n="chat.welcomeSub">Langfuse 트레이싱 분석, 프롬프트 개선, 평가를 AI 에이전트에게 요청하세요.</p>

      <div class="ai-chat-suggestions">
        <button class="ai-chat-suggest-card" data-msg="mode=overview limit=20">
          <span class="suggest-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
          </span>
          <span class="suggest-label" data-i18n="chat.overview">Overview</span>
          <span class="suggest-desc" data-i18n="chat.overviewDesc">전체 트레이싱 요약</span>
        </button>
        <button class="ai-chat-suggest-card" data-msg="mode=observability limit=20">
          <span class="suggest-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
          </span>
          <span class="suggest-label" data-i18n="chat.observability">Observability</span>
          <span class="suggest-desc" data-i18n="chat.observabilityDesc">성능 및 에러 모니터링</span>
        </button>
        <button class="ai-chat-suggest-card" data-msg="mode=prompt limit=10">
          <span class="suggest-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
          </span>
          <span class="suggest-label" data-i18n="chat.promptAnalysis">Prompt Analysis</span>
          <span class="suggest-desc" data-i18n="chat.promptAnalysisDesc">프롬프트 품질 분석</span>
        </button>
        <button class="ai-chat-suggest-card" data-msg="mode=evaluation limit=20 compare_models=true">
          <span class="suggest-icon">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="m22 8-4 4m0-4 4 4"/></svg>
          </span>
          <span class="suggest-label" data-i18n="chat.evaluation">Evaluation</span>
          <span class="suggest-desc" data-i18n="chat.evaluationDesc">모델 비교 평가</span>
        </button>
      </div>
    </div>

    <!-- Messages will be appended here -->
  </div>

  <!-- Input area — pinned bottom, centered -->
  <div class="ai-chat-input-wrap">
    <div class="ai-chat-input-bar">
      <div class="ai-chat-input-row">
        <textarea
          class="ai-chat-textarea"
          id="chat-input"
          data-i18n-placeholder="chat.placeholder"
          placeholder="메시지를 입력하세요..."
          rows="1"
          autofocus
        ></textarea>
        <button class="ai-chat-send-btn" id="chat-send" data-i18n-title="chat.sendMessage" title="Send message">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <path d="M22 2 11 13"/>
            <path d="m22 2-7 20-4-9-9-4z"/>
          </svg>
        </button>
      </div>
      <div class="ai-chat-input-footer">
        <select class="ai-chat-model-select" id="chat-model" title="LLM Model">
          <option value="" data-i18n="chat.autoModel">Auto</option>
        </select>
        <select class="ai-chat-model-select" id="chat-project" title="Langfuse Project">
          <option value="" data-i18n="chat.defaultProject">Default Project</option>
        </select>
        <select class="ai-chat-model-select" id="chat-endpoint">
          <option value="/api/chat" data-i18n="chat.chatGeneral">Chat (General)</option>
          <option value="/api/ops/query" data-i18n="chat.opsQuery">Ops Query</option>
          <option value="/v1/agent/invoke" data-i18n="chat.invokeRaw">Invoke (Raw)</option>
        </select>
        <span class="ai-chat-hint" data-i18n="chat.hint">Shift+Enter 줄바꿈 &middot; Enter 전송</span>
      </div>
    </div>
  </div>
</div>
{% endblock %}

{% block scripts %}
<script type="module">
import { api } from '/static/js/api.js';
import { toast, mdToHtml, escapeHtml, t } from '/static/js/common.js';

const thread = document.getElementById('chat-thread');
const welcome = document.getElementById('chat-welcome');
const input = document.getElementById('chat-input');
const sendBtn = document.getElementById('chat-send');
const projectSelect = document.getElementById('chat-project');
const modelSelect = document.getElementById('chat-model');
let isLoading = false;

/* ---- Load available models ---- */
async function loadAvailableModels() {
  try {
    const data = await api.get('/api/models/available');
    const groups = data.groups || [];
    groups.forEach(g => {
      const optgroup = document.createElement('optgroup');
      optgroup.label = g.provider.toUpperCase();
      g.models.forEach(m => {
        const opt = document.createElement('option');
        opt.value = m.id;
        opt.textContent = m.id === data.default ? `${m.label} ★` : m.label;
        optgroup.appendChild(opt);
      });
      modelSelect.appendChild(optgroup);
    });
    const saved = localStorage.getItem('chat_model_id');
    if (saved && modelSelect.querySelector(`option[value="${saved}"]`)) {
      modelSelect.value = saved;
    }
  } catch {}
}
modelSelect.addEventListener('change', () => {
  localStorage.setItem('chat_model_id', modelSelect.value);
});

/* ---- Load Langfuse projects ---- */
async function loadChatProjects() {
  try {
    const data = await api.get('/api/users/me/langfuse-projects');
    const projects = data.data || [];
    projectSelect.innerHTML = `<option value="">${t('chat.defaultProject')}</option>`;
    projects.forEach(p => {
      const star = p.is_default ? '★ ' : '';
      const opt = document.createElement('option');
      opt.value = p.id;
      opt.textContent = `${star}${p.name}`;
      projectSelect.appendChild(opt);
    });
    const saved = localStorage.getItem('chat_project_id');
    if (saved && projectSelect.querySelector(`option[value="${saved}"]`)) {
      projectSelect.value = saved;
    }
  } catch {}
}
projectSelect.addEventListener('change', () => {
  localStorage.setItem('chat_project_id', projectSelect.value);
});

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

/* ---- Clear welcome screen ---- */
function hideWelcome() {
  if (welcome) welcome.style.display = 'none';
}

/* ---- Scroll to bottom ---- */
function scrollBottom() {
  thread.scrollTop = thread.scrollHeight;
}

/* ---- Add message ---- */
function addMessage(content, role) {
  hideWelcome();

  const row = document.createElement('div');
  row.className = `ai-msg ai-msg-${role}`;

  const avatar = document.createElement('div');
  avatar.className = 'ai-msg-avatar';
  if (role === 'assistant') {
    avatar.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a8 8 0 0 1 8 8c0 3.1-1.7 5.8-4.3 7.1L12 22l-3.7-4.9A8 8 0 0 1 12 2z"/><circle cx="12" cy="10" r="2"/></svg>`;
  } else {
    avatar.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`;
  }

  const bubble = document.createElement('div');
  bubble.className = 'ai-msg-bubble';

  const label = document.createElement('div');
  label.className = 'ai-msg-label';
  label.textContent = role === 'assistant' ? 'Langfuse Lens' : t('chat.you');

  const body = document.createElement('div');
  body.className = 'ai-msg-body';
  if (role === 'assistant') {
    body.innerHTML = mdToHtml(content);
  } else {
    body.textContent = content;
  }

  bubble.appendChild(label);
  bubble.appendChild(body);
  row.appendChild(avatar);
  row.appendChild(bubble);
  thread.appendChild(row);
  scrollBottom();
  return body;
}

/* ---- Typing indicator ---- */
function showTyping() {
  hideWelcome();
  const row = document.createElement('div');
  row.className = 'ai-msg ai-msg-assistant';
  row.id = 'typing-indicator';

  const avatar = document.createElement('div');
  avatar.className = 'ai-msg-avatar';
  avatar.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a8 8 0 0 1 8 8c0 3.1-1.7 5.8-4.3 7.1L12 22l-3.7-4.9A8 8 0 0 1 12 2z"/><circle cx="12" cy="10" r="2"/></svg>`;

  const bubble = document.createElement('div');
  bubble.className = 'ai-msg-bubble';

  const label = document.createElement('div');
  label.className = 'ai-msg-label';
  label.textContent = 'Langfuse Lens';

  const dots = document.createElement('div');
  dots.className = 'typing-dots';
  dots.innerHTML = '<span></span><span></span><span></span>';

  bubble.appendChild(label);
  bubble.appendChild(dots);
  row.appendChild(avatar);
  row.appendChild(bubble);
  thread.appendChild(row);
  scrollBottom();
}

function hideTyping() {
  const el = document.getElementById('typing-indicator');
  if (el) el.remove();
}

/* ---- Metrics row ---- */
function addMetrics(metrics) {
  if (!metrics || Object.keys(metrics).length === 0) return;
  const row = document.createElement('div');
  row.className = 'ai-msg-metrics';
  row.innerHTML = Object.entries(metrics)
    .map(([k, v]) => `<span class="badge badge-default">${escapeHtml(k)}: ${escapeHtml(String(v))}</span>`)
    .join('');
  thread.appendChild(row);
  scrollBottom();
}

/* ---- Send ---- */
async function sendMessage() {
  const msg = input.value.trim();
  if (!msg || isLoading) return;

  addMessage(msg, 'user');
  input.value = '';
  autoResize();
  isLoading = true;
  sendBtn.disabled = true;
  sendBtn.classList.add('loading');
  showTyping();

  const endpoint = document.getElementById('chat-endpoint').value;

  try {
    const body = { message: msg };
    const selectedModel = modelSelect.value;
    if (selectedModel) body.model = selectedModel;
    const pid = projectSelect.value;
    if (pid) body.project_id = parseInt(pid, 10);
    const data = await api.post(endpoint, body);
    hideTyping();
    addMessage(data.output || JSON.stringify(data, null, 2), 'assistant');
    if (data.metrics) addMetrics(data.metrics);
  } catch (err) {
    hideTyping();
    addMessage(`${t('common.error')}: ${err.message}`, 'assistant');
    toast(err.message, 'error');
  } finally {
    isLoading = false;
    sendBtn.disabled = false;
    sendBtn.classList.remove('loading');
  }
}

sendBtn.addEventListener('click', sendMessage);
input.addEventListener('keydown', (e) => {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    sendMessage();
  }
});

/* ---- Suggestion cards ---- */
document.querySelectorAll('.ai-chat-suggest-card').forEach(card => {
  card.addEventListener('click', () => {
    input.value = card.dataset.msg;
    sendMessage();
  });
});

loadAvailableModels();
loadChatProjects();
input.focus();
</script>
{% endblock %}
