<template>
  <div class="flex-1 overflow-y-auto py-4 px-7">
    <p v-if="!referenceSources.length" class="text-sm text-gray-500">No references available.</p>
    <Accordion v-else type="multiple" v-model="openOuterAccordions" class="space-y-4">
      <AccordionItem
        v-for="(src, idx) in groupedReferenceSources"
        :key="idx"
        :value="String(idx)"
        class="data-[state=open]:border-b"
      >
        <div class="flex text-sm font-medium space-x-2 py-2">
          <div class="flex space-x-2 flex-1">
            <div>
              <i class="dku-icon-tool-wrench-16 !rotate-0 mt-0.5"></i>
            </div>
            <span>{{ src.toolCallDescription }}</span>
          </div>
          <TooltipProvider>
            <Tooltip>
              <TooltipTrigger as-child>
                <AccordionTrigger class="flex justify-center w-6 h-6 py-0 mt-0.5">
                  <template #icon>
                    <ChevronDown
                      class="text-muted-foreground size-4 shrink-0 transition-transform duration-200"
                    />
                  </template>
                </AccordionTrigger>
              </TooltipTrigger>
              <TooltipContent>
                <p>
                  {{
                    openOuterAccordions.includes(String(idx)) ? 'Collapse panel' : 'Expand panel'
                  }}
                </p>
              </TooltipContent>
            </Tooltip>
          </TooltipProvider>
        </div>

        <AccordionContent class="space-y-2 pt-2">
          <Accordion type="multiple" v-model="openInnerAccordions[idx]" class="space-y-2">
            <AccordionItem
              v-for="(groupedItem, i) in src.groupedItems"
              :key="i"
              :value="String(i)"
              class="border rounded-md px-3 data-[state=open]:border-b"
            >
              <div class="flex text-sm font-medium py-2">
                <span class="flex-1 inline-flex items-center gap-1 h-fit">
                  <template v-if="groupedItem.type === 'sql-group'"> SQL Query Execution </template>
                  <template v-else-if="groupedItem.item?.url">
                    <TooltipProvider>
                      <Tooltip>
                        <TooltipTrigger as-child>
                          <a
                            :href="groupedItem.item.url"
                            target="_blank"
                            rel="noopener noreferrer"
                            class="hover:text-primary inline-flex items-center gap-1"
                            @click.stop
                          >
                            <span class="underline">
                              {{
                                groupedItem.item.title ||
                                computeSourceTitle(groupedItem.item, groupedItem.index)
                              }}
                              <i
                                class="dku-icon-arrow-external-link-16 inline-block align-middle"
                              ></i>
                            </span>
                          </a>
                        </TooltipTrigger>
                        <TooltipContent>
                          <p>Open document in a new window</p>
                        </TooltipContent>
                      </Tooltip>
                    </TooltipProvider>
                  </template>
                  <template
                    v-else-if="groupedItem.item?.images?.length && groupedItem.item?.fileRef"
                  >
                    <TooltipProvider>
                      <Tooltip>
                        <TooltipTrigger as-child>
                          <a
                            href="#"
                            class="hover:text-primary inline-flex items-center gap-1"
                            @click.stop.prevent="openImageDocument(groupedItem.item)"
                          >
                            <span class="underline"
                              >{{
                                groupedItem.item.title ||
                                computeSourceTitle(groupedItem.item, groupedItem.index)
                              }}
                              <i
                                class="dku-icon-arrow-external-link-16 inline-block align-middle"
                              ></i>
                            </span>
                          </a>
                        </TooltipTrigger>
                        <TooltipContent>
                          <p>Open document in a new window</p>
                        </TooltipContent>
                      </Tooltip>
                    </TooltipProvider>
                  </template>
                  <template v-else>
                    {{
                      groupedItem.item?.title ||
                      computeSourceTitle(groupedItem.item!, groupedItem.index)
                    }}
                  </template>
                </span>
                <TooltipProvider>
                  <Tooltip>
                    <TooltipTrigger as-child>
                      <AccordionTrigger class="!flex-none w-6 h-6 py-0 mt-0.5">
                        <template #icon>
                          <ChevronDown
                            class="text-muted-foreground size-4 shrink-0 transition-transform duration-200"
                          />
                        </template>
                      </AccordionTrigger>
                    </TooltipTrigger>
                    <TooltipContent>
                      <p>
                        {{
                          openInnerAccordions[idx]?.includes(String(i))
                            ? 'Collapse panel'
                            : 'Expand panel'
                        }}
                      </p>
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>
              </div>

              <AccordionContent class="pb-3">
                <!-- SQL Group: Display all three items together -->
                <template v-if="groupedItem.type === 'sql-group' && groupedItem.groupItems">
                  <div class="space-y-4">
                    <!-- INFO section -->
                    <div v-if="groupedItem.groupItems.info" class="space-y-2">
                      <h6 class="text-sm font-semibold text-foreground">Table Selection</h6>
                      <div
                        v-for="(tableInfo, idx) in parseTableInfo(
                          groupedItem.groupItems.info.textSnippet || ''
                        )"
                        :key="idx"
                        class="mb-3"
                      >
                        <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm">
                          <span>Table name</span>
                          <span>{{ tableInfo.tableName }}</span>
                          <span>Columns</span>
                          <span>{{ tableInfo.columns.join(', ') }}</span>
                        </div>
                      </div>
                    </div>

                    <!-- SQL Query section -->
                    <div v-if="groupedItem.groupItems.query" class="space-y-2">
                      <h6 class="text-sm font-semibold text-foreground">SQL Query</h6>
                      <CodeBlock
                        :code="groupedItem.groupItems.query.textSnippet || ''"
                        type="GENERATED_SQL_QUERY"
                      />
                    </div>

                    <!-- Records section -->
                    <div v-if="groupedItem.groupItems.records" class="space-y-2">
                      <h6 class="text-sm font-semibold text-foreground">Query Results</h6>
                      <div
                        v-if="
                          groupedItem.groupItems.records.records &&
                          groupedItem.groupItems.records.records.columns
                        "
                        class="source-content max-w-full overflow-hidden whitespace-normal"
                      >
                        <DataTable
                          :rows="groupedItem.groupItems.records.records.rows"
                          :columns="groupedItem.groupItems.records.records.columns"
                        ></DataTable>
                      </div>
                    </div>
                  </div>
                </template>

                <!-- Single item: Display as before -->
                <template v-else-if="groupedItem.type === 'single' && groupedItem.item">
                  <div class="space-y-2">
                    <!-- Header -->
                    <div class="flex items-start justify-between">
                      <h5 class="text-sm font-semibold">
                        <span
                          v-if="
                            groupedItem.item.type && groupedItem.item.type !== 'SIMPLE_DOCUMENT'
                          "
                          class="text-sm text-foreground font-bold"
                          >{{ getSourceTypeLabel(groupedItem.item.type) }}
                        </span>
                        <!-- IMAGE items: plain title / others: clickable link -->
                        <template>
                          <a
                            v-if="groupedItem.item.url"
                            :href="groupedItem.item.url"
                            target="_blank"
                            rel="noopener"
                            class="hover:underline"
                          >
                            {{ groupedItem.item.title || groupedItem.item.url }}
                          </a>
                          <span v-else>{{
                            groupedItem.item.title || groupedItem.item.type || 'Untitled'
                          }}</span>
                        </template>
                      </h5>
                    </div>

                    <!-- INLINE IMAGES -->
                    <template v-if="groupedItem.item.type === 'IMAGE'">
                      <div class="flex flex-wrap gap-2 mt-1">
                        <template
                          v-for="(u, k) in groupedItem.item.urls || [groupedItem.item.url]"
                          :key="k"
                        >
                          <img
                            v-if="resolveImgSrc(u)"
                            :src="resolveImgSrc(u)"
                            class="max-h-40 rounded border"
                            :alt="groupedItem.item.title"
                          />
                        </template>
                      </div>
                    </template>

                    <!-- Text / HTML snippets for non-image items -->
                    <template v-else>
                      <!-- Code blocks with syntax highlighting -->
                      <CodeBlock
                        v-if="
                          shouldRenderAsCode(groupedItem.item.type) &&
                          (groupedItem.item.textSnippet || groupedItem.item.htmlSnippet)
                        "
                        :code="groupedItem.item.textSnippet || groupedItem.item.htmlSnippet || ''"
                        :type="groupedItem.item.type"
                      />
                      <!-- Regular HTML snippets -->
                      <div v-else-if="groupedItem.item.htmlSnippet">
                        <MarkdownRenderer
                          class="bg-gray-100 p-2 rounded-md mt-1"
                          :content="sanitize(groupedItem.item.htmlSnippet)"
                        />
                      </div>
                      <!-- Regular text snippets -->
                      <div v-else-if="groupedItem.item.textSnippet" class="text-sm text-gray-700">
                        <template
                          v-if="
                            groupedItem.item.type === 'INFO' &&
                            groupedItem.item.textSnippet.startsWith('Decided to use [')
                          "
                        >
                          <div
                            v-for="(tableInfo, idx) in parseTableInfo(groupedItem.item.textSnippet)"
                            :key="idx"
                            class="mb-3"
                          >
                            <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1">
                              <span>Table name</span>
                              <span>{{ tableInfo.tableName }}</span>
                              <span>Columns</span>
                              <span>{{ tableInfo.columns.join(', ') }}</span>
                            </div>
                          </div>
                        </template>
                        <template v-else>
                          <div>
                            <MarkdownRenderer
                              :content="groupedItem.item.textSnippet"
                              class="bg-gray-100 p-2 rounded-md"
                            />
                          </div>
                        </template>
                      </div>
                      <!-- Images -->
                      <div
                        v-else-if="groupedItem.item.images && groupedItem.item.images.length"
                        class="source-images flex-col gap-2"
                      >
                        <img
                          v-for="(img, imgIndex) in groupedItem.item.images"
                          :key="imgIndex"
                          :src="img.file_data"
                          @click="openLightbox(img.file_data)"
                          class="source-image h-auto object-cover my-1 cursor-zoom-in transition-transform duration-200 shadow-sm hover:scale-102 hover:shadow-md"
                        />
                      </div>
                      <!-- Data tables -->
                      <div
                        v-if="groupedItem.item.records && groupedItem.item.records.columns"
                        class="source-content max-w-full overflow-hidden whitespace-normal pb-3"
                      >
                        <DataTable
                          :rows="groupedItem.item.records.rows"
                          :columns="groupedItem.item.records.columns"
                        ></DataTable>
                      </div>
                    </template>

                    <!-- Metadata -->
                    <div
                      v-if="
                        groupedItem.item.metadata &&
                        hasDisplayableMetadata(groupedItem.item.metadata)
                      "
                      class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1"
                    >
                      <span class="text-foreground font-semibold col-span-2">Metadata</span>
                      <template v-for="(val, key) in groupedItem.item.metadata" :key="key">
                        <!-- Regular metadata fields (excluding tags) -->
                        <template v-if="key !== 'tags'">
                          <span class="text-sm">{{ formatKey(key) }}</span>
                          <span
                            class="text-sm"
                            v-if="typeof val === 'string' || typeof val === 'number'"
                            >{{ val }}</span
                          >
                          <span class="text-sm" v-else>{{ JSON.stringify(val) }}</span>
                        </template>
                        <!-- Tags - render with full structure -->
                        <template v-else-if="Array.isArray(val)">
                          <span class="text-sm">Tags</span>
                          <div class="text-sm space-y-2">
                            <div
                              v-for="(tag, tagIdx) in val"
                              :key="tagIdx"
                              class="space-y-0.5"
                              :class="{ 'border-t border-border/70': tagIdx !== 0 }"
                            >
                              <div v-if="tag.name">name: {{ tag.name }}</div>
                              <div v-if="tag.type">type: {{ tag.type }}</div>
                              <div v-if="tag.value">value: {{ tag.value }}</div>
                            </div>
                          </div>
                        </template>
                      </template>
                    </div>
                  </div>
                </template>
              </AccordionContent>
            </AccordionItem>
          </Accordion>
          <transition name="lightbox-zoom">
            <div
              v-if="lightboxImage"
              class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-70 cursor-zoom-out lightbox-overlay"
              @click="closeLightbox"
            >
              <img
                :src="lightboxImage"
                class="max-w-[90vw] max-h-[90vh] object-contain rounded shadow-lg"
                id="source-image-preview"
              />
            </div>
          </transition>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, reactive, watch } from 'vue'
import DOMPurify from 'dompurify'
import DataTable from '@/components/DataTable.vue'
import CodeBlock from '@/components/CodeBlock.vue'
import {
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
} from '@/components/ui/accordion'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { ChevronDown } from 'lucide-vue-next'
import { getSourceTypeLabel } from '@/constants/events'
import { getBackendUrl } from '@/lib/backendUrl'
import MarkdownRenderer from '@/components/MarkdownRenderer.vue'
import type { EventLogEntry } from '@/types/messages'

/* ------------------------------------------------------------------ */
/* Types ------------------------------------------------------------- */
interface ReferenceItem {
  type?: string
  title?: string
  url?: string // first image URL (b-compat)
  urls?: string[] // NEW – all images
  htmlSnippet?: string
  textSnippet?: string
  metadata?: Record<string, any>
  images?: Array<Record<string, any>>
  records?: any
  fileRef?: {
    folderId?: string
    path?: string
    pageRange?: {
      start: number
      end: number
    }
  }
}

interface ReferenceSource {
  toolCallDescription: string
  items: ReferenceItem[]
}

interface GroupedItem {
  type: 'single' | 'sql-group'
  item?: ReferenceItem
  groupItems?: {
    info?: ReferenceItem
    query?: ReferenceItem
    records?: ReferenceItem
  }
  index: number
}

const props = defineProps<{
  eventLog: Array<EventLogEntry>
}>()

/* ------------------------------------------------------------------ */
/* State ------------------------------------------------------------- */
const lightboxImage = ref<string | null>(null)

// Track open accordions
const openOuterAccordions = ref<string[]>([])
const openInnerAccordions = reactive<Record<number, string[]>>({})

/* ------------------------------------------------------------------ */
/* Computed ---------------------------------------------------------- */
const referenceSources = computed<ReferenceSource[]>(() =>
  props.eventLog
    .filter((evt) => evt.eventKind === 'references')
    .flatMap((evt) => (evt.eventData.sources as ReferenceSource[]) || [])
)

const groupedReferenceSources = computed(() => {
  return referenceSources.value.map((src, idx) => {
    const groupedItems: GroupedItem[] = []
    let i = 0

    while (i < src.items.length) {
      const item = src.items[i]

      // Check if this is the start of an INFO + SQL + RECORDS sequence
      if (
        item.type === 'INFO' &&
        item.textSnippet?.startsWith('Decided to use [') &&
        i + 2 < src.items.length &&
        src.items[i + 1].type === 'GENERATED_SQL_QUERY' &&
        src.items[i + 2].type === 'RECORDS'
      ) {
        // Group these three items together
        groupedItems.push({
          type: 'sql-group',
          groupItems: {
            info: src.items[i],
            query: src.items[i + 1],
            records: src.items[i + 2],
          },
          index: i,
        })
        i += 3 // Skip the next two items
      } else {
        // Regular single item
        groupedItems.push({
          type: 'single',
          item,
          index: i,
        })
        i++
      }
    }

    // Initialize inner accordion states for this source
    if (!openInnerAccordions[idx]) {
      openInnerAccordions[idx] = groupedItems.map((_, i) => String(i))
    }

    return {
      ...src,
      groupedItems,
    }
  })
})

// Initialize outer accordion state when sources change
watch(
  groupedReferenceSources,
  (sources) => {
    if (openOuterAccordions.value.length === 0 && sources.length > 0) {
      openOuterAccordions.value = sources.map((_, i) => String(i))
    }
  },
  { immediate: true }
)

/* ------------------------------------------------------------------ */
/* Constants --------------------------------------------------------- */

// Types that should be rendered as code with syntax highlighting
const codeTypes = [
  'GENERATED_SQL_QUERY',
  'SQL',
  'PYTHON',
  'JAVASCRIPT',
  'TYPESCRIPT',
  'JSON',
  'YAML',
  'BASH',
  'MARKDOWN',
]

/* ------------------------------------------------------------------ */
/* Functions --------------------------------------------------------- */
function openLightbox(imgUrl: string) {
  lightboxImage.value = imgUrl
}

function closeLightbox() {
  lightboxImage.value = null
}

function sanitize(html: string) {
  return DOMPurify.sanitize(html)
}

function shouldRenderAsCode(type?: string): boolean {
  return type ? codeTypes.includes(type) : false
}

/** Turn "/api/images/…" (or "api/images/…") into a fully-qualified, DSS-safe URL */
function resolveImgSrc(u?: string): string {
  if (!u) return ''
  if (/^https?:\/\//i.test(u)) return u // already absolute
  const base = getBackendUrl().replace(/\/$/, '') // drop trailing "/" if any
  return `${base}${u.startsWith('/') ? '' : '/'}${u}`
}

/** Parse table info from "Decided to use [...]" text snippet */
function parseTableInfo(textSnippet: string): Array<{ tableName: string; columns: string[] }> {
  try {
    // Extract the JSON array from the text
    const jsonStart = textSnippet.indexOf('[')
    if (jsonStart === -1) return []

    const jsonStr = textSnippet.substring(jsonStart)
    // Replace single quotes with double quotes for valid JSON
    const validJsonStr = jsonStr.replace(/'/g, '"')
    const tables = JSON.parse(validJsonStr)

    return tables.map((table: any) => ({
      tableName: table.table_name || '',
      columns: table.columns || [],
    }))
  } catch (error) {
    console.error('Failed to parse table info:', error)
    return []
  }
}

/** Check if metadata has displayable content (not empty) */
function hasDisplayableMetadata(metadata: Record<string, any>): boolean {
  if (!metadata || typeof metadata !== 'object') return false
  return Object.keys(metadata).length > 0
}

/** Compute the title for a source item */
function computeSourceTitle(item: ReferenceItem, index: number): string {
  let title = `Document ${index + 1}`

  // Check if fileRef exists
  if (item.fileRef && typeof item.fileRef === 'object') {
    const fileRef = item.fileRef as any

    // Extract filename from path
    if (fileRef.path) {
      const filename = fileRef.path.split('/').pop() || fileRef.path

      // Add page range if available
      if (fileRef.pageRange) {
        const { start, end } = fileRef.pageRange
        if (start === end) {
          title += `: ${filename} (p. ${start})`
        } else {
          title += `: ${filename} (p. ${start}-${end})`
        }
      } else {
        title += `: ${filename}`
      }
    }
  }

  return title
}

function formatKey(key: string | number): any {
  return typeof key === 'string'
    ? key
        .replace(/([A-Z])/g, ' $1') // add space before caps
        .replace(/^./, (s) => s.toUpperCase()) // capitalize first letter
    : key
}

function openImageDocument(item: ReferenceItem) {
  // Extract folderId from fileRef (format: projectKey.folderId)
  if (!item.fileRef?.folderId) {
    console.warn('No folderId found in item.fileRef')
    return
  }

  const folderId = item.fileRef.folderId
  const parts = folderId.split('.')

  if (parts.length !== 2) {
    console.warn('Invalid folderId format:', folderId)
    return
  }

  const [projectKey, odbId] = parts
  const itemPath = item.fileRef.path || ''

  // Determine content type from file extension
  const extension = itemPath.split('.').pop()?.toLowerCase()
  let contentType = 'application/octet-stream'

  if (extension === 'pdf') {
    contentType = 'application/pdf'
  } else if (['jpg', 'jpeg'].includes(extension || '')) {
    contentType = 'image/jpeg'
  } else if (extension === 'png') {
    contentType = 'image/png'
  } else if (extension === 'gif') {
    contentType = 'image/gif'
  } else if (['doc', 'docx'].includes(extension || '')) {
    contentType = 'application/msword'
  } else if (['xls', 'xlsx'].includes(extension || '')) {
    contentType = 'application/vnd.ms-excel'
  }

  // Build the preview URL
  const encodedPath = encodeURIComponent(itemPath)
  const encodedContentType = encodeURIComponent(contentType)
  let url = `/dip/api/managedfolder/preview-image?contextProjectKey=${projectKey}&projectKey=${projectKey}&odbId=${odbId}&itemPath=${encodedPath}&contentType=${encodedContentType}`

  // Add page number anchor if available
  if (item.fileRef.pageRange?.start) {
    url += `#page=${item.fileRef.pageRange.start}`
  }

  window.open(url, '_blank')
}
</script>
