<script setup>
import { ref, onMounted, nextTick } from 'vue'
import DashboardLayout from '../layouts/DashboardLayout.vue'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'

const model = ref('codex/gpt-5.3-codex')
const promptInput = ref('')
const sending = ref(false)
const messages = ref([])
const messagesEnd = ref(null)
const convHistory = ref([])
const showHistory = ref(false)
const currentConvId = ref(null)
const traceData = ref(null)
const docTitle = ref('Chưa có trace')
const approvalPending = ref(null) // { sessionId, cycle, tools, thinking }

function uuidv4() {
  return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  )
}

function getToken() { return localStorage.getItem('canifa_token') || '' }

async function authFetch(url, opts = {}) {
  opts.headers = { ...opts.headers, Authorization: 'Bearer ' + getToken() }
  return fetch(url, opts)
}

async function loadHistory() {
  try {
    const r = await authFetch('/api/ai-sql/conversations')
    const d = await r.json()
    convHistory.value = d.conversations || []
  } catch (_) {}
}

async function loadConversation(convId) {
  currentConvId.value = convId
  showHistory.value = false
  messages.value = [{ type: 'thinking' }]
  try {
    const r = await authFetch(`/api/ai-sql/conversations/${convId}`)
    const d = await r.json()
    const sessions = d.sessions || []
    messages.value = sessions.flatMap(s => [
      { type: 'user', text: s.question },
      { type: 'ai', text: `${s.status === 'completed' ? '✅ Done' : '❌ Error'} · ${s.session_data?.total_queries || 0} queries`, status: s.status }
    ])
    if (sessions.length) {
      const latest = sessions[sessions.length - 1]
      traceData.value = { ...latest.session_data, question: latest.question, status: latest.status }
      docTitle.value = latest.question || 'SQL Trace'
    }
  } catch (_) { messages.value = [{ type: 'error', text: 'Lỗi tải dữ liệu' }] }
}

function startNew() {
  currentConvId.value = uuidv4()
  messages.value = [{ type: 'ai', text: '🔍 AI SQL Trace sẵn sàng phân tích.\n\nNhập câu hỏi để AI tự phân tích, tạo SQL, chạy query và trả kết quả dữ liệu.' }]
  traceData.value = null; docTitle.value = 'Chưa có trace'; showHistory.value = false
}

async function submit() {
  const question = promptInput.value.trim()
  if (!question || sending.value) return
  promptInput.value = ''; sending.value = true
  messages.value.push({ type: 'user', text: question })

  const session = { question, status: 'running', total_queries: 0, successful_queries: 0, failed_queries: 0, results: [], cycles: [], _pendingTools: [], _pendingToolIdx: 0 }
  const aiMsg = { type: 'ai', text: '', thinking: true, steps: [], approvalPending: null, sessionId: null }
  messages.value.push(aiMsg)
  traceData.value = session; docTitle.value = question; approvalPending.value = null

  try {
    const r = await authFetch('/api/ai-sql/trace', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ question, conversation_id: currentConvId.value, model: model.value })
    })
    const reader = r.body.getReader()
    const decoder = new TextDecoder()
    let buf = ''
    while (true) {
      const { value, done } = await reader.read()
      if (done) break
      buf += decoder.decode(value, { stream: true })
      const lines = buf.split('\n'); buf = lines.pop()
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          try { handleEvent(JSON.parse(line.slice(6)), session, aiMsg) } catch (_) {}
        }
      }
    }
  } catch (e) {
    aiMsg.text = '❌ Lỗi kết nối'; aiMsg.thinking = false
  } finally { sending.value = false }
  await nextTick(); messagesEnd.value?.scrollIntoView({ behavior: 'smooth' })
}

function handleEvent(data, session, msg) {
  switch (data.type) {
    case 'session_started':
      msg.sessionId = data.session_id
      session.session_id = data.session_id
      break
    case 'thinking':
      msg.steps.push({ icon: '💭', text: data.step })
      break
    case 'pending_approval':
      session._pendingTools = data.tools || []
      session._pendingToolIdx = 0
      msg.approvalPending = { sessionId: session.session_id, cycle: data.cycle, tools: data.tools || [], thinking: data.thinking || '' }
      approvalPending.value = msg.approvalPending
      break
    case 'executing':
      msg.steps.push({ icon: '⚡', text: `Đang chạy ${data.tools_count} queries...` })
      msg.approvalPending = null
      break
    case 'tool_result':
      session.total_queries++
      if (data.success) session.successful_queries++; else session.failed_queries++
      const pt = session._pendingTools[session._pendingToolIdx++] || {}
      session.results.push({ tool: data.tool, success: data.success, preview: data.preview, purpose: pt.purpose || '', sql: pt.params?.sql || '' })
      msg.steps.push({ icon: data.success ? '✅' : '❌', text: `${data.tool}: ${data.preview?.row_count || 0} rows` })
      traceData.value = { ...session }
      break
    case 'reflect':
      if (data.ai_summary) session.ai_summary = data.ai_summary
      msg.steps.push({ icon: data.data_sufficient ? '✅' : '🔄', text: data.data_sufficient ? 'Đủ dữ liệu' : 'Cần thêm data...' })
      break
    case 'rejected':
      msg.steps.push({ icon: '🚫', text: 'SQL bị từ chối' }); msg.approvalPending = null
      break
    case 'complete':
      session.status = 'completed'; session.summary = data; session.ai_summary = data.ai_summary
      msg.thinking = false; msg.approvalPending = null
      msg.text = `✅ Done · ${data.total_queries || 0} queries · ${data.cycles_completed || 0} cycles · ${((data.generation_time_ms || 0) / 1000).toFixed(1)}s`
      traceData.value = { ...session }
      loadHistory()
      break
    case 'error':
      session.status = 'error'; msg.thinking = false; msg.text = '❌ ' + (data.message || 'Lỗi')
      break
  }
}

async function doApprove(sessionId, action) {
  try {
    await authFetch(`/api/ai-sql/approve/${sessionId}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ action })
    })
  } catch (_) {}
  approvalPending.value = null
  if (messages.value.length) {
    const last = messages.value[messages.value.length - 1]
    if (last.approvalPending) last.approvalPending = null
  }
}

function fmtVal(v) {
  if (typeof v === 'number') return v.toLocaleString('vi-VN')
  return String(v ?? '—')
}

onMounted(() => { startNew(); loadHistory() })
</script>

<template>
  <DashboardLayout>
    <div class="flex h-[calc(100vh-56px)] overflow-hidden">

      <!-- History sidebar -->
      <div v-if="showHistory" class="fixed inset-0 z-40 flex">
        <div class="w-72 bg-white border-r border-gray-100 shadow-xl flex flex-col">
          <div class="flex items-center justify-between p-4 border-b">
            <h3 class="font-bold text-sm text-gray-800">🗂 SQL Trace History</h3>
            <Button variant="ghost" size="sm" @click="showHistory = false">✕</Button>
          </div>
          <div class="p-2 flex-1 overflow-y-auto">
            <button @click="startNew" class="w-full text-left px-3 py-2 text-xs text-purple-700 bg-purple-50 rounded-lg mb-2 hover:bg-purple-100">+ New Session</button>
            <div v-for="c in convHistory" :key="c.conversation_id"
                 @click="loadConversation(c.conversation_id)"
                 class="px-3 py-2 rounded-lg hover:bg-gray-50 cursor-pointer mb-1">
              <p class="text-xs font-medium text-gray-700 truncate">{{ c.title || 'Untitled' }}</p>
              <div class="flex items-center gap-1 mt-0.5">
                <span :class="['text-[9px] px-1 py-0.5 rounded font-bold', c.status === 'completed' ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-600']">
                  {{ c.status || 'done' }}
                </span>
                <span class="text-[9px] text-gray-400">{{ c.updated_at ? new Date(c.updated_at).toLocaleString('vi-VN') : '' }}</span>
              </div>
            </div>
            <div v-if="!convHistory.length" class="text-center py-8 text-xs text-gray-400">Chưa có lịch sử</div>
          </div>
        </div>
        <div class="flex-1 bg-black/20" @click="showHistory = false"></div>
      </div>

      <!-- Chat panel -->
      <div class="w-[380px] shrink-0 flex flex-col border-r border-gray-100">
        <div class="flex items-center gap-2 px-4 py-3 border-b bg-gray-50">
          <button @click="showHistory = true" class="text-gray-500 hover:text-gray-800">
            <svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/></svg>
          </button>
          <h2 class="text-sm font-bold text-gray-700 flex-1">🔍 AI SQL Trace</h2>
          <Select v-model="model" class="w-40">
            <SelectTrigger class="h-7 text-[10px]"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="codex/gpt-5.3-codex">GPT-5.3 Codex</SelectItem>
              <SelectItem value="gemini-2.0-flash">Gemini 2.0 Flash</SelectItem>
              <SelectItem value="gemini-2.5-pro">Gemini 2.5 Pro</SelectItem>
            </SelectContent>
          </Select>
        </div>

        <div class="flex-1 overflow-y-auto p-3 space-y-2.5">
          <div v-for="(msg, i) in messages" :key="i" :class="['flex', msg.type === 'user' ? 'justify-end' : 'justify-start']">
            <div v-if="msg.type === 'user'" class="max-w-[85%] bg-purple-600 text-white rounded-2xl px-3 py-2 text-xs">{{ msg.text }}</div>
            <div v-else-if="msg.type === 'ai'" class="max-w-[90%] bg-white border border-gray-100 rounded-2xl px-3 py-2.5 shadow-sm space-y-1.5">
              <!-- Steps -->
              <div v-for="(step, si) in msg.steps" :key="si" class="flex items-center gap-1.5 text-[10px] text-gray-500">
                <span>{{ step.icon }}</span><span>{{ step.text }}</span>
              </div>
              <!-- Approval buttons -->
              <div v-if="msg.approvalPending" class="border border-amber-200 bg-amber-50/60 rounded-xl p-3 space-y-2">
                <p class="text-[10px] font-bold text-amber-700">⚠️ Cycle {{ msg.approvalPending.cycle }} — Duyệt SQL?</p>
                <div v-for="t in msg.approvalPending.tools" :key="t.name" class="text-[10px] text-gray-600">
                  <span class="font-bold text-purple-700">{{ t.name }}</span> · {{ t.purpose }}
                  <pre v-if="t.params?.sql" class="text-[9px] bg-gray-50 border border-gray-100 rounded p-1 mt-1 overflow-x-auto">{{ (t.params.sql || '').slice(0, 200) }}</pre>
                </div>
                <div class="flex gap-2 mt-2">
                  <Button size="sm" class="h-7 text-xs flex-1 bg-green-600 hover:bg-green-700" @click="doApprove(msg.approvalPending.sessionId, 'accept')">✅ Accept</Button>
                  <Button size="sm" variant="outline" class="h-7 text-xs flex-1 border-red-300 text-red-600" @click="doApprove(msg.approvalPending.sessionId, 'reject')">✕ Reject</Button>
                </div>
              </div>
              <!-- Typing -->
              <div v-if="msg.thinking && !msg.steps.length" class="flex gap-1">
                <span v-for="j in 3" :key="j" class="w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce" :style="{ animationDelay: j * 150 + 'ms' }"></span>
              </div>
              <p v-if="msg.text" class="text-xs leading-relaxed text-gray-700">{{ msg.text }}</p>
            </div>
            <div v-else-if="msg.type === 'error'" class="text-xs text-red-600 bg-red-50 border border-red-100 rounded-xl px-3 py-2">{{ msg.text }}</div>
            <div v-else-if="msg.type === 'thinking'" class="flex gap-1 px-3 py-2 bg-white border border-gray-100 rounded-2xl">
              <span v-for="j in 3" :key="j" class="w-1.5 h-1.5 bg-gray-400 rounded-full animate-bounce" :style="{ animationDelay: j * 150 + 'ms' }"></span>
            </div>
          </div>
          <div ref="messagesEnd"></div>
        </div>

        <div class="p-3 border-t bg-gray-50">
          <Textarea v-model="promptInput" placeholder="Hỏi dữ liệu sản phẩm, tồn kho, doanh thu..."
                    class="min-h-[64px] text-xs resize-none mb-2"
                    @keydown.enter.prevent.exact="submit" />
          <Button @click="submit" :disabled="sending || !promptInput.trim()" class="w-full bg-purple-600 hover:bg-purple-700">
            {{ sending ? '⏳ Đang phân tích...' : '🔍 Phân tích SQL' }}
          </Button>
        </div>
      </div>

      <!-- Right: Trace output -->
      <div class="flex-1 overflow-hidden flex flex-col">
        <div class="flex items-center justify-between px-4 py-2 border-b bg-gray-50">
          <h2 class="text-sm font-bold text-gray-700 truncate">{{ docTitle }}</h2>
          <button v-if="traceData?.results?.length" @click="navigator.clipboard?.writeText(JSON.stringify(traceData.results, null, 2))"
                  class="text-xs text-gray-500 hover:text-gray-800 border border-gray-200 px-2 py-0.5 rounded">
            📋 Copy JSON
          </button>
        </div>

        <div class="flex-1 overflow-y-auto p-4">
          <div v-if="!traceData" class="flex flex-col items-center justify-center h-full text-gray-400">
            <div class="text-5xl mb-3">🔍</div>
            <p class="text-sm">Nhập câu hỏi để bắt đầu phân tích SQL</p>
          </div>

          <div v-else class="space-y-3">
            <!-- Summary card -->
            <div class="bg-white border border-gray-100 rounded-2xl p-4 shadow-sm">
              <div class="flex items-center justify-between mb-3">
                <p class="text-xs font-bold text-gray-700 truncate">{{ traceData.question }}</p>
                <span :class="['text-[10px] px-2 py-0.5 rounded-full font-bold',
                  traceData.status === 'completed' ? 'bg-green-100 text-green-700' :
                  traceData.status === 'error' ? 'bg-red-100 text-red-600' : 'bg-amber-100 text-amber-700']">
                  {{ traceData.status || 'running' }}
                </span>
              </div>
              <div class="grid grid-cols-4 gap-3">
                <div v-for="stat in [
                  { label: 'Queries', value: traceData.total_queries || 0 },
                  { label: 'OK', value: traceData.successful_queries || 0 },
                  { label: 'Lỗi', value: traceData.failed_queries || 0 },
                  { label: 'Cycles', value: traceData.summary?.cycles_completed || '...' }
                ]" :key="stat.label" class="text-center">
                  <p class="text-lg font-black text-gray-800">{{ stat.value }}</p>
                  <p class="text-[9px] text-gray-400">{{ stat.label }}</p>
                </div>
              </div>
            </div>

            <!-- AI Summary -->
            <div v-if="traceData.ai_summary" class="bg-white border-l-4 border-purple-400 border border-gray-100 rounded-r-2xl p-4 shadow-sm">
              <div class="flex items-start gap-2">
                <span class="text-lg">🤖</span>
                <p class="text-xs text-gray-700 leading-relaxed">{{ traceData.ai_summary }}</p>
              </div>
            </div>

            <!-- Query results -->
            <div v-for="(r, i) in (traceData.results || []).filter(r => r.preview?.row_count > 0)" :key="i"
                 class="bg-white border border-gray-100 rounded-2xl shadow-sm overflow-hidden">
              <div class="flex items-center justify-between px-4 py-2.5 border-b bg-gray-50">
                <div>
                  <p class="text-xs font-bold text-gray-700">{{ r.purpose || r.tool }}</p>
                  <p v-if="r.sql" class="text-[9px] font-mono text-gray-400 truncate max-w-xs">{{ r.sql.slice(0, 80) }}</p>
                </div>
                <span class="text-[10px] bg-green-100 text-green-700 px-2 py-0.5 rounded-full font-bold">{{ r.preview.row_count }} rows</span>
              </div>
              <div class="overflow-x-auto">
                <table class="w-full text-xs">
                  <thead class="bg-gray-50 border-b border-gray-100">
                    <tr>
                      <th v-for="col in (r.preview.columns || Object.keys(r.preview.preview_rows?.[0] || {}))" :key="col"
                          class="px-3 py-1.5 text-left font-semibold text-gray-500 text-[10px] uppercase tracking-wider whitespace-nowrap">
                        {{ col }}
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr v-for="(row, ri) in (r.preview.preview_rows || []).slice(0, 10)" :key="ri"
                        class="border-b border-gray-50 hover:bg-gray-50/50">
                      <td v-for="col in (r.preview.columns || Object.keys(row))" :key="col"
                          class="px-3 py-1.5 text-gray-700 whitespace-nowrap">
                        {{ fmtVal(row[col]) }}
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </DashboardLayout>
</template>
