<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { useProjectsStore } from '@/stores/projects'
import { useSettingsStore, AVAILABLE_MODELS, PROVIDER_CONFIG, hasProviderApiKey, type AIProvider } from '@/stores/settings'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { analyzeSession, type SessionExtraction } from '@/services/session-analyzer'
import { generateMasterDoc } from '@/services/project-doc'
import { parseFile } from '@/services/parse-transcription'
import { saveSession, saveSessionSummary, saveProjectState, getSessionCount, getSessionsByProject } from '@/services/transcriptions-db'
import { parseTeamsUTC, toColombiaTime } from '@/services/timezone'
import {
  Card,
  CardContent,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Upload,
  FileText,
  Sparkles,
  CheckCircle2,
  Loader2,
  AlertCircle,
  Settings2,
  Brain,
  FolderOpen,
  FileDown,
  ListChecks,
  Target,
  GitCommit,
  Calendar,
  Hash,
  ChevronLeft,
  ChevronRight,
  ChevronDown,
  Check,
} from 'lucide-vue-next'

const { t } = useI18n()
const projectsStore = useProjectsStore()
const settingsStore = useSettingsStore()
const fileInput = ref<HTMLInputElement | null>(null)

// ─── Upload state ────────────────────────────────────────
const parsedText = ref('')
const parsedFileName = ref('')
const parsing = ref(false)
const uploadError = ref<string | null>(null)

// ─── Session analysis state ──────────────────────────────
const sessionLoading = ref(false)
const sessionResult = ref<SessionExtraction | null>(null)
const sessionError = ref<string | null>(null)
const sessionTeamsInfo = ref<{ utc: string; timeStr: string } | null>(null)
const docGenerating = ref(false)
const docGenerated = ref(false)

// ─── Project document state ──────────────────────────────
const docMarkdown = ref('')
const docSessionCount = ref(0)
const docUpdatedAt = ref('')
const sessionDatesList = ref<{ date: string; title: string; fileName: string }[]>([])
const viewerRef = ref<HTMLTextAreaElement | null>(null)

// ─── Calendar state ──────────────────────────────────────
const calMonth = ref(new Date().getMonth())
const calYear = ref(new Date().getFullYear())

const emit = defineEmits<{ 'navigate-settings': [] }>()
const projects = computed(() => projectsStore.projects)
const selectedProjectId = ref<number | null>(null)

const selectedProject = computed(() =>
  projects.value.find(p => p.id === selectedProjectId.value) ?? null
)

// ─── Load doc when project changes ──────────────────────
watch(selectedProjectId, async (id) => {
  if (!id) return
  clearAll()
  await loadSessionDates(id)
  const count = sessionDatesList.value.length
  docSessionCount.value = count
  if (count > 0) {
    const md = await generateMasterDoc(id, selectedProject.value?.name || '')
    docMarkdown.value = md
  }
}, { immediate: false })

async function loadSessionDates(projectId: number) {
  const sessions = await getSessionsByProject(projectId)
  sessionDatesList.value = sessions.map(s => ({
    date: s.date,
    title: s.title,
    fileName: s.fileName,
  }))
}

function scrollToSession(date: string) {
  if (!viewerRef.value || !docMarkdown.value) return
  const md = docMarkdown.value
  // Buscar la sesión por fecha en el markdown: ## 📍 Sesión: YYYY-MM-DD
  const re = new RegExp(`## 📍 Sesión: ${escapeRegex(date)}`)
  const match = re.exec(md)
  if (!match) return
  const lineNum = md.slice(0, match.index).split('\n').length
  const lineHeight = 20
  viewerRef.value.scrollTop = (lineNum - 5) * lineHeight
  viewerRef.value.focus()
}

function escapeRegex(s: string) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

function sessionDates(): string[] {
  return sessionDatesList.value.map(s => s.date).filter(Boolean)
}

// ─── Calendar helpers ────────────────────────────────────
const monthNames = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']

function daysInMonth(m: number, y: number) {
  return new Date(y, m + 1, 0).getDate()
}

function firstDayOfMonth(m: number, y: number) {
  return new Date(y, m, 1).getDay()
}

function isSessionDate(d: number) {
  const dateStr = `${calYear.value}-${String(calMonth.value + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`
  return sessionDatesList.value.some(s => s.date === dateStr)
}

function getSessionForDate(d: number) {
  const dateStr = `${calYear.value}-${String(calMonth.value + 1).padStart(2, '0')}-${String(d).padStart(2, '0')}`
  return sessionDatesList.value.find(s => s.date === dateStr) || null
}

function prevMonth() {
  if (calMonth.value === 0) { calMonth.value = 11; calYear.value-- }
  else calMonth.value--
}

function nextMonth() {
  if (calMonth.value === 11) { calMonth.value = 0; calYear.value++ }
  else calMonth.value++
}

// ─── Uploaded files queue ───────────────────────────────
interface QueuedFile {
  fileName: string
  text: string
  parsed: boolean
}
const fileQueue = ref<QueuedFile[]>([])
const activeFileIndex = ref(-1)

async function handleFiles(files: FileList | File[]) {
  console.log(`[Alpha] handleFiles: ${files.length} file(s)`)
  const newFiles: QueuedFile[] = []
  parsing.value = true

  for (const file of Array.from(files)) {
    console.log(`[Alpha] Parsing: ${file.name} (${file.size} bytes)`)
    try {
      const result = await parseFile(file)
      console.log(`[Alpha] Parsed OK: ${result.fileName}, ${result.text.length} chars`)
      newFiles.push({ fileName: result.fileName, text: result.text, parsed: true })
    } catch (e: any) {
      console.error(`[Alpha] Failed to parse ${file.name}:`, e)
    }
  }

  parsing.value = false

  if (newFiles.length === 0) return

  fileQueue.value.push(...newFiles)

  if (activeFileIndex.value === -1) {
    activeFileIndex.value = 0
    loadActiveFile()
  }
}

function loadActiveFile() {
  if (activeFileIndex.value < 0 || activeFileIndex.value >= fileQueue.value.length) {
    clearActiveFile()
    return
  }
  const f = fileQueue.value[activeFileIndex.value]
  parsedText.value = f.text
  parsedFileName.value = f.fileName
  sessionResult.value = null
  docGenerated.value = false
}

function clearActiveFile() {
  parsedText.value = ''
  parsedFileName.value = ''
  sessionResult.value = null
  docGenerated.value = false
  activeFileIndex.value = -1
}

function removeFromQueue(idx: number) {
  fileQueue.value.splice(idx, 1)
  if (idx === activeFileIndex.value) {
    if (fileQueue.value.length > 0) {
      activeFileIndex.value = Math.min(activeFileIndex.value, fileQueue.value.length - 1)
      loadActiveFile()
    } else {
      clearActiveFile()
    }
  } else if (idx < activeFileIndex.value) {
    activeFileIndex.value--
  }
}

function selectFile(idx: number) {
  activeFileIndex.value = idx
  loadActiveFile()
}

function handleFileDrop(e: DragEvent) {
  const files = e.dataTransfer?.files
  if (files && files.length > 0) handleFiles(files)
}

function handleFileSelect(e: Event) {
  const files = (e.target as HTMLInputElement).files
  if (files && files.length > 0) handleFiles(files)
  // Reset input so same file can be re-selected
  ;(e.target as HTMLInputElement).value = ''
}




function openFilePicker() {
  fileInput.value?.click()
}

// ─── Session analysis ────────────────────────────────────
async function analyzeAsSession() {
  if (!parsedText.value || !selectedProjectId.value) return
  sessionLoading.value = true
  sessionError.value = null
  sessionResult.value = null

  try {
    const result = await analyzeSession(
      parsedText.value,
      selectedProject.value?.name || '',
    )

    // 1. Determinar fecha (prioridad: UTC del filename → AI → hoy)
    const now = new Date().toISOString()
    const teamsDate = parseTeamsUTC(parsedFileName.value)
    sessionTeamsInfo.value = teamsDate ? { utc: teamsDate.utc, timeStr: teamsDate.timeStr } : null
    const sessionDate = teamsDate?.dateStr || result.sessionDate || now.slice(0, 10)

    // 1b. Deduplicación: verificar si ya existe una sesión con el mismo UTC timestamp
    const existing = await getSessionsByProject(selectedProjectId.value)
    const isDuplicate = existing.some(s => {
      // Comparar por UTC timestamp en filename o por fecha + título similar
      const existingUTC = parseTeamsUTC(s.fileName)
      return teamsDate !== null && existingUTC !== null && teamsDate.utc === existingUTC.utc
    })
    if (isDuplicate) {
      sessionError.value = `Esta sesión ya fue registrada (UTC ${teamsDate?.utc}). Se descarta.`
      sessionLoading.value = false
      return
    }

    // 1c. Guardar transcripción en BD
    const sessionId = await saveSession({
      projectId: selectedProjectId.value,
      date: sessionDate,
      title: result.sessionTitle,
      fileName: parsedFileName.value,
      fileType: parsedFileName.value.split('.').pop() || 'txt',
      fileSize: parsedText.value.length,
      rawText: parsedText.value,
      processedAt: now,
    })

    // 2. Guardar resumen de IA en BD
    await saveSessionSummary({
      sessionId,
      summary: result.summary,
      objectives: JSON.stringify(result.objectives),
      tasks: JSON.stringify(result.pendingTasks),
      commitments: JSON.stringify(result.commitments),
      decisions: JSON.stringify(result.decisions),
      keyPoints: JSON.stringify(result.keyPoints),
      modelUsed: settingsStore.modelId,
    })

    // 3. Consolidar y actualizar project_state
    await consolidateProjectState(selectedProjectId.value)

    // 4. Regenerar documento MD
    const md = await generateMasterDoc(selectedProjectId.value, selectedProject.value?.name || '')
    docMarkdown.value = md
    await loadSessionDates(selectedProjectId.value)
    docSessionCount.value = sessionDatesList.value.length
    docUpdatedAt.value = now.slice(0, 16).replace('T', ' ')
    docGenerated.value = true

    // 5. Mostrar resultado en UI
    sessionResult.value = result
    parsedText.value = ''
    parsedFileName.value = ''

  } catch (e: any) {
    sessionError.value = e.message
  } finally {
    sessionLoading.value = false
  }
}

async function consolidateProjectState(projectId: number) {
  // Reconstruye project_state desde todas las summaries del proyecto
  const { getSummariesByProject, getProjectState } = await import('@/services/transcriptions-db')
  const summaries = await getSummariesByProject(projectId)
  const prev = await getProjectState(projectId)

  const allObjectives: string[] = []
  const allTasks: { description: string; origin: string; priority: string; status?: string }[] = []
  const allCommitments: { description: string; responsible: string; dueDate: string; status: string }[] = []
  let consolidatedSummary = ''

  for (const s of summaries) {
    const objs = safeParseJSON<{ text: string; isNew: boolean }[]>(s.objectives, [])
    objs.forEach(o => { if (!allObjectives.includes(o.text)) allObjectives.push(o.text) })

    const tasks = safeParseJSON<{ description: string; origin: string; priority: string }[]>(s.tasks, [])
    tasks.forEach(t => {
      const exists = allTasks.find(ex => ex.description === t.description)
      if (!exists) allTasks.push({ ...t, status: 'pendiente' })
    })

    const cmts = safeParseJSON<{ description: string; responsible: string; dueDate: string; status: string }[]>(s.commitments, [])
    cmts.forEach(c => {
      const exists = allCommitments.find(ex => ex.description === c.description)
      if (!exists) allCommitments.push(c)
    })

    if (!consolidatedSummary) consolidatedSummary = s.summary
  }

  // Preservar estados de tareas existentes (por si se marcaron como completadas)
  if (prev) {
    const prevTasks = safeParseJSON<{ description: string; status?: string }[]>(prev.tasks, [])
    for (const pt of prevTasks) {
      const match = allTasks.find(t => t.description === pt.description)
      if (match && pt.status === 'completada') match.status = 'completada'
    }
  }

  await saveProjectState({
    projectId,
    summary: consolidatedSummary,
    objectives: JSON.stringify(allObjectives),
    tasks: JSON.stringify(allTasks),
    commitments: JSON.stringify(allCommitments),
    updatedAt: new Date().toISOString(),
  })
}

function safeParseJSON<T>(json: string | undefined | null, fallback: T): T {
  if (!json) return fallback
  try { return JSON.parse(json) as T } catch { return fallback }
}

async function generateDoc() {
  if (!selectedProjectId.value) return
  docGenerating.value = true

  try {
    const md = await generateMasterDoc(selectedProjectId.value, selectedProject.value?.name || '')
    docMarkdown.value = md
    await loadSessionDates(selectedProjectId.value)
    docSessionCount.value = sessionDatesList.value.length
    docUpdatedAt.value = new Date().toISOString().slice(0, 16).replace('T', ' ')
    docGenerated.value = true
  } catch (e: any) {
    sessionError.value = e.message
  } finally {
    docGenerating.value = false
  }
}

function downloadDoc() {
  if (!docMarkdown.value) return
  const name = selectedProject.value?.name || `proyecto-${selectedProjectId.value}`
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '')
  const blob = new Blob([docMarkdown.value], { type: 'text/markdown' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `${slug}-sesiones.md`
  a.click()
  setTimeout(() => URL.revokeObjectURL(url), 1000)
}

const allProviders: AIProvider[] = ['openrouter', 'minimax', 'opencode']
function modelsForProvider(p: AIProvider) {
  return AVAILABLE_MODELS.filter(m => m.provider === p)
}
function switchModel(provider: AIProvider, modelId: string) {
  if (provider !== settingsStore.provider) {
    settingsStore.setActiveProvider(provider)
  }
  settingsStore.setModel(modelId)
}

function clearAll() {
  parsedText.value = ''
  parsedFileName.value = ''
  fileQueue.value = []
  activeFileIndex.value = -1
  parsing.value = false
  uploadError.value = null
  sessionResult.value = null
  sessionError.value = null
  sessionLoading.value = false
  docGenerated.value = false
  docGenerating.value = false
}
</script>

<template>
  <div class="@container/main flex flex-1 flex-col gap-4 px-4 lg:px-6 py-4">
    <!-- Global processing banner -->
    <div
      v-if="parsing || sessionLoading || docGenerating"
      class="flex items-center gap-3 px-4 py-2.5 rounded-lg bg-primary/5 border border-primary/20 text-sm"
    >
      <Loader2 class="size-4 animate-spin text-primary shrink-0" />
      <span v-if="parsing" class="text-primary font-medium">{{ t('transcriptions.statusParsing') }}</span>
      <span v-else-if="sessionLoading" class="text-primary font-medium">{{ t('transcriptions.statusAnalyzing') }}</span>
      <span v-else-if="docGenerating" class="text-primary font-medium">{{ t('transcriptions.statusGenerating') }}</span>
    </div>

    <!-- Header with inline project selector -->
    <div class="flex items-start justify-between gap-4 flex-wrap">
      <div class="flex items-center gap-3 min-w-0 flex-1">
        <h1 class="text-2xl font-bold tracking-tight shrink-0">{{ t('transcriptions.titleView') }}</h1>
        <div class="min-w-[240px] md:w-[360px]">
          <Select v-model="selectedProjectId">
            <SelectTrigger id="transcriptions-project-trigger" class="h-9 text-sm">
              <FolderOpen class="size-4 shrink-0" />
              <SelectValue :placeholder="t('transcriptions.selectProject')" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem
                v-for="p in projects"
                :key="p.id"
                :value="p.id"
              >{{ p.name }}</SelectItem>
            </SelectContent>
          </Select>
        </div>
      </div>
      <div class="flex items-center gap-2 shrink-0">
        <Button
          v-if="!settingsStore.apiKeyConfigured"
          variant="outline"
          size="sm"
          @click="$emit('navigate-settings')"
        >
          <Settings2 class="size-4 mr-1" />
          {{ t('transcriptions.configureAI') }}
        </Button>
        <DropdownMenu v-else>
          <DropdownMenuTrigger as-child>
            <Button variant="outline" size="sm" class="text-xs h-7 gap-1 font-mono">
              {{ settingsStore.selectedModel?.label || settingsStore.modelId }}
              <ChevronDown class="size-3" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end" class="w-64">
            <DropdownMenuLabel>{{ t('projectAi.switchModel') }}</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <template v-for="p in allProviders" :key="p">
              <DropdownMenuItem
                v-if="modelsForProvider(p).length > 0"
                class="flex flex-col items-start py-2 cursor-default"
                disabled
              >
                <div class="flex items-center gap-2 w-full">
                  <span class="text-xs font-medium">{{ PROVIDER_CONFIG[p].label }}</span>
                  <Badge
                    v-if="hasProviderApiKey(p)"
                    variant="outline"
                    class="text-[9px] text-green-600 border-green-300 dark:text-green-400 dark:border-green-700"
                  >{{ t('projectAi.keyReady') }}</Badge>
                  <Badge
                    v-else
                    variant="outline"
                    class="text-[9px] text-muted-foreground"
                  >{{ t('projectAi.noKey') }}</Badge>
                </div>
              </DropdownMenuItem>
              <DropdownMenuItem
                v-for="m in modelsForProvider(p)"
                :key="m.id"
                :disabled="!hasProviderApiKey(p)"
                @click="switchModel(p, m.id)"
                class="flex items-center gap-2 py-1.5 pl-6"
              >
                <Check
                  v-if="settingsStore.provider === p && settingsStore.modelId === m.id"
                  class="size-3.5 text-primary shrink-0"
                />
                <div v-else class="size-3.5 shrink-0" />
                <span class="text-xs">{{ m.label }}</span>
                <code class="text-[9px] text-muted-foreground ml-auto truncate max-w-[120px]">{{ m.id }}</code>
              </DropdownMenuItem>
              <DropdownMenuSeparator v-if="p !== allProviders[allProviders.length - 1]" />
            </template>
            <DropdownMenuSeparator />
            <DropdownMenuItem
              class="text-xs text-muted-foreground justify-center"
              @click="$emit('navigate-settings')"
            >
              <Settings2 class="size-3 mr-1" />
              {{ t('projectAi.settings') }}
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
        <Button
          v-if="docMarkdown"
          variant="outline"
          size="sm"
          @click="downloadDoc()"
        >
          <FileDown class="size-4 mr-1" />
          {{ t('transcriptions.downloadDoc') }}
        </Button>
      </div>
    </div>

    <!-- Upload card (full width) -->
    <Card id="transcriptions-upload" class="border-dashed overflow-hidden">
      <div
        class="flex flex-col items-center justify-center gap-3 p-6 min-h-[120px] transition-opacity"
        :class="selectedProjectId ? 'cursor-pointer' : 'opacity-50 pointer-events-none'"
        @drop.prevent="selectedProjectId ? handleFileDrop($event) : null"
        @dragover.prevent="selectedProjectId ? null : null"
        @click="selectedProjectId ? openFilePicker() : null"
      >
          <input
            ref="fileInput"
            type="file"
            accept=".docx,.vtt,.txt,.md"
            multiple
            class="hidden"
            @change="handleFileSelect"
          />
          <template v-if="!selectedProjectId">
            <FolderOpen class="size-6 text-muted-foreground" />
            <p class="text-xs text-muted-foreground text-center">
              {{ t('transcriptions.selectProjectFirst') }}
            </p>
          </template>
          <template v-else-if="!parsedText && !parsing">
            <Upload class="size-6 text-muted-foreground" />
            <p class="text-xs text-muted-foreground text-center">
              {{ t('transcriptions.dropzone') }}<br>
              <span class="text-[10px]">{{ t('transcriptions.dropzoneFormats') }}</span>
            </p>
          </template>
          <template v-else-if="parsing">
            <Loader2 class="size-6 animate-spin text-muted-foreground" />
            <p class="text-xs text-muted-foreground">{{ t('transcriptions.parsing') }}</p>
          </template>
          <template v-else>
            <div class="w-full space-y-2">
              <!-- Files loaded badge -->
              <div class="flex items-center gap-2 text-xs text-green-600 dark:text-green-400">
                <CheckCircle2 class="size-3.5" />
                <span>{{ fileQueue.length }} {{ t('transcriptions.filesLoaded') }}</span>
              </div>
              <!-- Active file info -->
              <div class="flex items-center gap-2">
                <FileText class="size-5 text-primary shrink-0" />
                <span class="text-sm font-medium truncate max-w-[200px]">{{ parsedFileName }}</span>
                <Badge variant="outline" class="text-[10px] shrink-0">{{ (parsedText.length).toLocaleString() }} {{ t('transcriptions.chars') }}</Badge>
              </div>
              <!-- File queue -->
              <div v-if="fileQueue.length > 1" class="flex flex-wrap gap-1">
                <button
                  v-for="(f, i) in fileQueue"
                  :key="i"
                  class="text-[10px] px-2 py-0.5 rounded-full border transition-colors"
                  :class="i === activeFileIndex ? 'bg-primary text-primary-foreground border-primary' : 'hover:bg-muted'"
                  @click.stop="selectFile(i)"
                >
                  {{ i + 1 }}. {{ f.fileName.slice(0, 20) }}{{ f.fileName.length > 20 ? '…' : '' }}
                  <span class="ml-1 cursor-pointer hover:text-destructive" @click.stop="removeFromQueue(i)">×</span>
                </button>
              </div>
              <!-- Actions -->
              <div class="flex gap-1 flex-wrap">
                <Button size="sm" @click.stop="openFilePicker" variant="outline" class="text-xs h-7">
                  {{ t('transcriptions.addMore') }}
                </Button>
                <Button
                  size="sm"
                  class="text-xs h-7"
                  :disabled="sessionLoading || !selectedProjectId"
                  @click.stop="analyzeAsSession()"
                  id="transcriptions-analyze-btn"
                >
                  <Loader2 v-if="sessionLoading" class="size-3 mr-1 animate-spin" />
                  <Sparkles v-else class="size-3 mr-1" />
                  {{ t('transcriptions.analyzeSession') }}
                </Button>
              </div>
            </div>
          </template>
        </div>
    </Card>

    <!-- Stats row -->
    <div v-if="selectedProjectId" class="grid gap-3 @md:grid-cols-2">
      <!-- Session count -->
      <Card id="transcriptions-stats-sessions">
        <CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle class="text-sm font-medium">{{ t('transcriptions.sessionCountTitle') }}</CardTitle>
          <Hash class="size-4 text-muted-foreground" />
        </CardHeader>
        <CardContent>
          <div class="text-2xl font-bold">{{ docSessionCount }}</div>
          <p class="text-xs text-muted-foreground">{{ t('transcriptions.sessionsRecorded') }}</p>
        </CardContent>
      </Card>

      <!-- Mini calendar -->
      <Card id="transcriptions-calendar">
        <CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
          <CardTitle class="text-sm font-medium flex items-center gap-1">
            <Calendar class="size-4" />
            {{ t('transcriptions.sessionDates') }}
          </CardTitle>
          <div class="flex items-center gap-1">
            <Button variant="ghost" size="icon" class="size-6" @click="prevMonth">
              <ChevronLeft class="size-3" />
            </Button>
            <span class="text-xs font-medium w-20 text-center">{{ monthNames[calMonth] }} {{ calYear }}</span>
            <Button variant="ghost" size="icon" class="size-6" @click="nextMonth">
              <ChevronRight class="size-3" />
            </Button>
          </div>
        </CardHeader>
        <CardContent class="pt-0">
          <div v-if="sessionDatesList.length === 0" class="text-xs text-muted-foreground text-center py-2">
            {{ t('transcriptions.noSessions') }}
          </div>
          <template v-else>
            <div class="grid grid-cols-7 gap-0 text-center text-[10px] mb-1">
              <span v-for="d in ['Dom','Lun','Mar','Mié','Jue','Vie','Sáb']" :key="d" class="text-muted-foreground py-0.5">{{ d }}</span>
            </div>
            <div class="grid grid-cols-7 gap-0 text-center text-xs">
              <span v-for="_ in firstDayOfMonth(calMonth, calYear)" :key="'e'+_" />
              <button
                v-for="d in daysInMonth(calMonth, calYear)"
                :key="d"
                class="py-0.5 rounded hover:bg-muted transition-colors relative"
                :class="isSessionDate(d) ? 'bg-primary/10 text-primary font-bold' : 'text-muted-foreground'"
                @click="() => { const s = getSessionForDate(d); if (s) scrollToSession(s.date) }"
                :title="getSessionForDate(d)?.title || ''"
              >
                {{ d }}
                <span v-if="isSessionDate(d)" class="absolute -bottom-0.5 left-1/2 -translate-x-1/2 size-1 rounded-full bg-primary" />
              </button>
            </div>
          </template>
        </CardContent>
      </Card>
    </div>

    <!-- Session analysis error -->
    <Card v-if="sessionError" class="border-destructive/50">
      <CardHeader class="pb-2">
        <CardTitle class="text-sm font-medium flex items-center gap-2 text-destructive">
          <AlertCircle class="size-4" />
          {{ t('transcriptions.sessionError') }}
        </CardTitle>
      </CardHeader>
      <CardContent>
        <p class="text-sm">{{ sessionError }}</p>
      </CardContent>
    </Card>

    <!-- Session extraction results -->
    <Card v-if="sessionResult" id="transcriptions-session-result">
      <CardHeader class="pb-3 flex flex-row items-center justify-between">
        <CardTitle class="text-sm font-medium flex items-center gap-2">
          <ListChecks class="size-4" />
          {{ sessionResult.sessionTitle }}
        </CardTitle>
        <div class="flex items-center gap-2 mt-1">
          <span class="text-xs text-muted-foreground">{{ sessionResult.sessionDate || '' }}</span>
          <span v-if="sessionTeamsInfo" class="text-xs text-muted-foreground/60">
            · UTC {{ sessionTeamsInfo.utc }} → Colombia {{ sessionTeamsInfo.timeStr }}
          </span>
        </div>
        <Button size="sm" @click="generateDoc()" :disabled="docGenerating">
          <Loader2 v-if="docGenerating" class="size-4 mr-1 animate-spin" />
          <CheckCircle2 v-else class="size-4 mr-1" />
          {{ t('transcriptions.generateDoc') }}
        </Button>
      </CardHeader>
      <CardContent class="space-y-3 text-sm">
        <p class="text-muted-foreground">{{ sessionResult.summary }}</p>
        <div class="grid gap-3 @md:grid-cols-2">
          <div v-if="sessionResult.objectives.length > 0">
            <p class="text-xs text-muted-foreground font-semibold mb-1">{{ t('transcriptions.sessionObjectives') }}</p>
            <ul class="space-y-0.5">
              <li v-for="o in sessionResult.objectives" :key="o.text" class="flex items-start gap-1">
                <span v-if="o.isNew" class="text-green-500 text-xs">🆕</span>
                <span>{{ o.text }}</span>
              </li>
            </ul>
          </div>
          <div v-if="sessionResult.decisions.length > 0">
            <p class="text-xs text-muted-foreground font-semibold mb-1">{{ t('transcriptions.sessionDecisions') }}</p>
            <ul class="space-y-0.5">
              <li v-for="d in sessionResult.decisions" :key="d" class="flex items-start gap-1"><span class="text-muted-foreground">→</span> {{ d }}</li>
            </ul>
          </div>
        </div>
      </CardContent>
    </Card>

    <!-- Markdown viewer -->
    <Card v-if="docMarkdown" id="transcriptions-viewer">
      <CardHeader class="pb-2 flex flex-row items-center justify-between">
        <CardTitle class="text-sm font-medium flex items-center gap-2">
          <FileText class="size-4" />
          {{ selectedProject?.name || '' }} — {{ t('transcriptions.docViewer') }}
        </CardTitle>
        <div class="flex items-center gap-2 text-xs text-muted-foreground">
          <span>{{ docSessionCount }} {{ t('transcriptions.sessionsLabel') }}</span>
          <span>·</span>
          <span>{{ t('transcriptions.updatedAt') }} {{ docUpdatedAt }}</span>
        </div>
      </CardHeader>
      <CardContent>
        <textarea
          ref="viewerRef"
          :value="docMarkdown"
          class="w-full min-h-[400px] max-h-[600px] text-xs font-mono leading-relaxed rounded-lg border bg-muted/30 px-4 py-3 resize-y"
          readonly
        />
      </CardContent>
    </Card>

    <!-- Empty state -->
    <div v-if="!selectedProjectId" class="flex flex-1 items-center justify-center py-12">
      <div class="text-center space-y-2">
        <FolderOpen class="size-10 text-muted-foreground mx-auto" />
        <p class="text-sm text-muted-foreground">{{ t('transcriptions.selectProjectHint') }}</p>
      </div>
    </div>
  </div>
</template>
