'use client'

import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react'
import { RAG_PDF_MAPPING } from './rag-pdf-mapping'
import { REGULATIONS_IN_RAG, REGULATION_INFO } from '../rag-constants'
import { RegGroupKey } from './ChunkBrowserConstants'
import { getStructuralInfo } from './ChunkBrowserHelpers'
import { ChunkBrowserSidebar } from './ChunkBrowserSidebar'
import { ChunkBrowserToolbar } from './ChunkBrowserToolbar'
import { ChunkBrowserContent } from './ChunkBrowserContent'

interface ChunkBrowserQAProps {
  apiProxy: string
}

export function ChunkBrowserQA({ apiProxy }: ChunkBrowserQAProps) {
  // Filter-Sidebar
  const [selectedRegulation, setSelectedRegulation] = useState<string | null>(null)
  const [regulationCounts, setRegulationCounts] = useState<Record<string, number>>({})
  const [filterSearch, setFilterSearch] = useState('')
  const [countsLoading, setCountsLoading] = useState(false)

  // Dokument-Chunks (sequenziell)
  const [docChunks, setDocChunks] = useState<Record<string, unknown>[]>([])
  const [docChunkIndex, setDocChunkIndex] = useState(0)
  const [docTotalChunks, setDocTotalChunks] = useState(0)
  const [docLoading, setDocLoading] = useState(false)
  const docChunksRef = useRef(docChunks)
  docChunksRef.current = docChunks

  // Split-View
  const [splitViewActive, setSplitViewActive] = useState(true)
  const [chunksPerPage, setChunksPerPage] = useState(6)
  const [fullscreen, setFullscreen] = useState(false)

  // Collection
  const [collection, setCollection] = useState('bp_compliance_ce')

  // PDF existence check
  const [pdfExists, setPdfExists] = useState<boolean | null>(null)

  // Sidebar collapsed groups
  const [collapsedGroups, setCollapsedGroups] = useState<Set<string>>(new Set())

  // Build grouped regulations for sidebar
  const regulationsInCollection = Object.entries(REGULATIONS_IN_RAG)
    .filter(([, info]) => info.collection === collection)
    .map(([code]) => code)

  const groupedRegulations = useMemo(() => {
    const groups: Record<RegGroupKey, { code: string; name: string; type: string }[]> = {
      eu_regulation: [], eu_directive: [], de_law: [], at_law: [], ch_law: [],
      national_law: [], bsi_standard: [], eu_guideline: [], international_standard: [], other: [],
    }
    for (const code of regulationsInCollection) {
      const reg = REGULATION_INFO.find(r => r.code === code)
      const type = (reg?.type || 'other') as RegGroupKey
      const groupKey = type in groups ? type : 'other'
      groups[groupKey].push({ code, name: reg?.name || code, type: reg?.type || 'unknown' })
    }
    return groups
  }, [regulationsInCollection.join(',')])

  // Load regulation counts for current collection
  const loadRegulationCounts = useCallback(async (col: string) => {
    const entries = Object.entries(REGULATIONS_IN_RAG)
      .filter(([, info]) => info.collection === col && info.qdrant_id)
    if (entries.length === 0) return

    const qdrantIdToCode: Record<string, string[]> = {}
    for (const [code, info] of entries) {
      if (!qdrantIdToCode[info.qdrant_id]) qdrantIdToCode[info.qdrant_id] = []
      qdrantIdToCode[info.qdrant_id].push(code)
    }
    const uniqueQdrantIds = Object.keys(qdrantIdToCode)

    setCountsLoading(true)
    try {
      const params = new URLSearchParams({
        action: 'regulation-counts-batch',
        collection: col,
        qdrant_ids: uniqueQdrantIds.join(','),
      })
      const res = await fetch(`${apiProxy}?${params}`)
      if (res.ok) {
        const data = await res.json()
        const mapped: Record<string, number> = {}
        for (const [qid, count] of Object.entries(data.counts as Record<string, number>)) {
          const codes = qdrantIdToCode[qid] || []
          for (const code of codes) { mapped[code] = count }
        }
        setRegulationCounts(prev => ({ ...prev, ...mapped }))
      }
    } catch (error) {
      console.error('Failed to load regulation counts:', error)
    } finally {
      setCountsLoading(false)
    }
  }, [apiProxy])

  // Load all chunks for a regulation (paginated scroll)
  const loadDocumentChunks = useCallback(async (regulationCode: string) => {
    const ragInfo = REGULATIONS_IN_RAG[regulationCode]
    if (!ragInfo || !ragInfo.qdrant_id) return

    setDocLoading(true)
    setDocChunks([])
    setDocChunkIndex(0)
    setDocTotalChunks(0)

    const allChunks: Record<string, unknown>[] = []
    let offset: string | null = null

    try {
      let safety = 0
      do {
        const params = new URLSearchParams({
          action: 'scroll',
          collection: ragInfo.collection,
          limit: '100',
          filter_key: 'regulation_id',
          filter_value: ragInfo.qdrant_id,
        })
        if (offset) params.append('offset', offset)

        const res = await fetch(`${apiProxy}?${params}`)
        if (!res.ok) break

        const data = await res.json()
        const chunks = data.chunks || []
        allChunks.push(...chunks)
        offset = data.next_offset || null
        safety++
      } while (offset && safety < 200)

      allChunks.sort((a, b) => {
        const ai = Number(a.chunk_index ?? a.chunk_id ?? 0)
        const bi = Number(b.chunk_index ?? b.chunk_id ?? 0)
        return ai - bi
      })

      setDocChunks(allChunks)
      setDocTotalChunks(allChunks.length)
      setDocChunkIndex(0)
    } catch (error) {
      console.error('Failed to load document chunks:', error)
    } finally {
      setDocLoading(false)
    }
  }, [apiProxy])

  // Initial load
  useEffect(() => {
    loadRegulationCounts(collection)
  }, [collection, loadRegulationCounts])

  // Check PDF existence when regulation changes
  useEffect(() => {
    if (!selectedRegulation) { setPdfExists(null); return }
    const mapping = RAG_PDF_MAPPING[selectedRegulation]
    if (!mapping) { setPdfExists(false); return }
    const url = `/rag-originals/${mapping.filename}`
    fetch(url, { method: 'HEAD' })
      .then(res => setPdfExists(res.ok))
      .catch(() => setPdfExists(false))
  }, [selectedRegulation])

  // Keyboard navigation
  const handleKeyDown = useCallback((e: KeyboardEvent) => {
    if (e.key === 'Escape' && fullscreen) {
      e.preventDefault()
      setFullscreen(false)
    } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
      e.preventDefault()
      setDocChunkIndex(i => Math.max(0, i - 1))
    } else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
      e.preventDefault()
      setDocChunkIndex(i => Math.min(docChunksRef.current.length - 1, i + 1))
    }
  }, [fullscreen])

  useEffect(() => {
    if (fullscreen || (selectedRegulation && docChunks.length > 0)) {
      window.addEventListener('keydown', handleKeyDown)
      return () => window.removeEventListener('keydown', handleKeyDown)
    }
  }, [selectedRegulation, docChunks.length, handleKeyDown, fullscreen])

  // Handlers
  const handleSelectRegulation = (code: string) => {
    setSelectedRegulation(code)
    loadDocumentChunks(code)
  }

  const handleCollectionChange = (col: string) => {
    setCollection(col)
    setSelectedRegulation(null)
    setDocChunks([])
    setDocChunkIndex(0)
    setDocTotalChunks(0)
    setRegulationCounts({})
  }

  const toggleGroup = (group: string) => {
    setCollapsedGroups(prev => {
      const next = new Set(prev)
      if (next.has(group)) next.delete(group)
      else next.add(group)
      return next
    })
  }

  // Filter sidebar items
  const filteredRegulations = useMemo(() => {
    if (!filterSearch.trim()) return groupedRegulations
    const term = filterSearch.toLowerCase()
    const filtered: typeof groupedRegulations = {
      eu_regulation: [], eu_directive: [], de_law: [], at_law: [], ch_law: [],
      national_law: [], bsi_standard: [], eu_guideline: [], international_standard: [], other: [],
    }
    for (const [group, items] of Object.entries(groupedRegulations)) {
      filtered[group as RegGroupKey] = items.filter(
        r => r.code.toLowerCase().includes(term) || r.name.toLowerCase().includes(term)
      )
    }
    return filtered
  }, [groupedRegulations, filterSearch])

  const currentChunk = docChunks[docChunkIndex] || null
  const structInfo = getStructuralInfo(currentChunk)

  return (
    <div
      className={`flex flex-col ${fullscreen ? 'fixed inset-0 z-50 bg-slate-100 p-4' : ''}`}
      style={fullscreen ? { height: '100vh' } : { height: 'calc(100vh - 220px)' }}
    >
      <ChunkBrowserToolbar
        collection={collection}
        onCollectionChange={handleCollectionChange}
        selectedRegulation={selectedRegulation}
        structInfo={structInfo}
        docChunkIndex={docChunkIndex}
        docTotalChunks={docTotalChunks}
        docChunksLength={docChunks.length}
        chunksPerPage={chunksPerPage}
        setChunksPerPage={setChunksPerPage}
        splitViewActive={splitViewActive}
        setSplitViewActive={setSplitViewActive}
        fullscreen={fullscreen}
        setFullscreen={setFullscreen}
        onPrev={() => { if (docChunkIndex > 0) setDocChunkIndex(i => i - 1) }}
        onNext={() => { if (docChunkIndex < docChunks.length - 1) setDocChunkIndex(i => i + 1) }}
        onJumpTo={setDocChunkIndex}
      />

      <div className="flex gap-3 flex-1 min-h-0">
        <ChunkBrowserSidebar
          filterSearch={filterSearch}
          setFilterSearch={setFilterSearch}
          countsLoading={countsLoading}
          filteredRegulations={filteredRegulations}
          regulationCounts={regulationCounts}
          selectedRegulation={selectedRegulation}
          collapsedGroups={collapsedGroups}
          onSelectRegulation={handleSelectRegulation}
          onToggleGroup={toggleGroup}
        />

        <ChunkBrowserContent
          selectedRegulation={selectedRegulation}
          docLoading={docLoading}
          docChunks={docChunks}
          docChunkIndex={docChunkIndex}
          docTotalChunks={docTotalChunks}
          splitViewActive={splitViewActive}
          chunksPerPage={chunksPerPage}
          pdfExists={pdfExists}
        />
      </div>
    </div>
  )
}
