'use client'

import { useState, useEffect, useCallback, useRef } from 'react'
import { CanonicalControl, Framework, BACKEND_URL } from './helpers'
import { ControlsMeta, ControlFormData } from './types'

const PAGE_SIZE = 50

export function useControlLibrary() {
  const [frameworks, setFrameworks] = useState<Framework[]>([])
  const [controls, setControls] = useState<CanonicalControl[]>([])
  const [totalCount, setTotalCount] = useState(0)
  const [meta, setMeta] = useState<ControlsMeta | null>(null)
  const [selectedControl, setSelectedControl] = useState<CanonicalControl | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  // Filters
  const [searchQuery, setSearchQuery] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [severityFilter, setSeverityFilter] = useState<string>('')
  const [domainFilter, setDomainFilter] = useState<string>('')
  const [stateFilter, setStateFilter] = useState<string>('')
  const [verificationFilter, setVerificationFilter] = useState<string>('')
  const [categoryFilter, setCategoryFilter] = useState<string>('')
  const [evidenceTypeFilter, setEvidenceTypeFilter] = useState<string>('')
  const [audienceFilter, setAudienceFilter] = useState<string>('')
  const [sourceFilter, setSourceFilter] = useState<string>('')
  const [typeFilter, setTypeFilter] = useState<string>('')
  const [hideDuplicates, setHideDuplicates] = useState(true)
  const [sortBy, setSortBy] = useState<'id' | 'newest' | 'oldest' | 'source'>('id')

  // CRUD state
  const [mode, setMode] = useState<'list' | 'detail' | 'create' | 'edit'>('list')
  const [saving, setSaving] = useState(false)

  // Generator state
  const [showGenerator, setShowGenerator] = useState(false)
  const [processedStats, setProcessedStats] = useState<Array<Record<string, unknown>>>([])
  const [showStats, setShowStats] = useState(false)

  // Pagination
  const [currentPage, setCurrentPage] = useState(1)

  // Review mode
  const [reviewMode, setReviewMode] = useState(false)
  const [reviewIndex, setReviewIndex] = useState(0)
  const [reviewItems, setReviewItems] = useState<CanonicalControl[]>([])
  const [reviewCount, setReviewCount] = useState(0)
  const [reviewTab, setReviewTab] = useState<'duplicates' | 'rule3'>('duplicates')
  const [reviewDuplicates, setReviewDuplicates] = useState<CanonicalControl[]>([])
  const [reviewRule3, setReviewRule3] = useState<CanonicalControl[]>([])

  // V1 Compare mode
  const [compareMode, setCompareMode] = useState(false)
  const [compareV1Control, setCompareV1Control] = useState<CanonicalControl | null>(null)
  const [compareMatches, setCompareMatches] = useState<Array<{
    matched_control_id: string; matched_title: string; matched_objective: string
    matched_severity: string; matched_category: string
    matched_source: string | null; matched_article: string | null
    matched_source_citation: Record<string, string> | null
    similarity_score: number; match_rank: number; match_method: string
  }>>([])

  const [bulkProcessing, setBulkProcessing] = useState(false)

  // Abort controllers
  const metaAbortRef = useRef<AbortController | null>(null)
  const controlsAbortRef = useRef<AbortController | null>(null)

  // Debounce search
  const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null)
  useEffect(() => {
    if (searchTimer.current) clearTimeout(searchTimer.current)
    searchTimer.current = setTimeout(() => setDebouncedSearch(searchQuery), 400)
    return () => { if (searchTimer.current) clearTimeout(searchTimer.current) }
  }, [searchQuery])

  const buildParams = useCallback((extra?: Record<string, string>) => {
    const p = new URLSearchParams()
    if (severityFilter) p.set('severity', severityFilter)
    if (domainFilter) p.set('domain', domainFilter)
    if (stateFilter) p.set('release_state', stateFilter)
    if (verificationFilter) p.set('verification_method', verificationFilter)
    if (categoryFilter) p.set('category', categoryFilter)
    if (evidenceTypeFilter) p.set('evidence_type', evidenceTypeFilter)
    if (audienceFilter) p.set('target_audience', audienceFilter)
    if (sourceFilter) p.set('source', sourceFilter)
    if (typeFilter) p.set('control_type', typeFilter)
    if (hideDuplicates) p.set('exclude_duplicates', 'true')
    if (debouncedSearch) p.set('search', debouncedSearch)
    if (extra) for (const [k, v] of Object.entries(extra)) p.set(k, v)
    return p.toString()
  }, [severityFilter, domainFilter, stateFilter, verificationFilter, categoryFilter, evidenceTypeFilter, audienceFilter, sourceFilter, typeFilter, hideDuplicates, debouncedSearch])

  const loadFrameworks = useCallback(async () => {
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=frameworks`)
      if (res.ok) setFrameworks(await res.json())
    } catch { /* ignore */ }
  }, [])

  const loadMeta = useCallback(async () => {
    if (metaAbortRef.current) metaAbortRef.current.abort()
    const controller = new AbortController()
    metaAbortRef.current = controller
    try {
      const qs = buildParams()
      const res = await fetch(`${BACKEND_URL}?endpoint=controls-meta${qs ? `&${qs}` : ''}`, { signal: controller.signal })
      if (res.ok && !controller.signal.aborted) setMeta(await res.json())
    } catch (e) {
      if (e instanceof DOMException && e.name === 'AbortError') return
    }
  }, [buildParams])

  const loadControls = useCallback(async () => {
    if (controlsAbortRef.current) controlsAbortRef.current.abort()
    const controller = new AbortController()
    controlsAbortRef.current = controller
    try {
      setLoading(true)
      const sortField = sortBy === 'id' ? 'control_id' : sortBy === 'source' ? 'source' : 'created_at'
      const sortOrder = sortBy === 'newest' ? 'desc' : sortBy === 'oldest' ? 'asc' : 'asc'
      const offset = (currentPage - 1) * PAGE_SIZE
      const qs = buildParams({ sort: sortField, order: sortOrder, limit: String(PAGE_SIZE), offset: String(offset) })
      const countQs = buildParams()
      const [ctrlRes, countRes] = await Promise.all([
        fetch(`${BACKEND_URL}?endpoint=controls&${qs}`, { signal: controller.signal }),
        fetch(`${BACKEND_URL}?endpoint=controls-count&${countQs}`, { signal: controller.signal }),
      ])
      if (!controller.signal.aborted) {
        if (ctrlRes.ok) setControls(await ctrlRes.json())
        if (countRes.ok) {
          const data = await countRes.json()
          setTotalCount(data.total || 0)
        }
      }
    } catch (err) {
      if (err instanceof DOMException && err.name === 'AbortError') return
      setError(err instanceof Error ? err.message : 'Fehler beim Laden')
    } finally {
      if (!controller.signal.aborted) setLoading(false)
    }
  }, [buildParams, sortBy, currentPage])

  const loadReviewCount = useCallback(async () => {
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=controls-count&release_state=needs_review`)
      if (res.ok) {
        const data = await res.json()
        setReviewCount(data.total || 0)
      }
    } catch { /* ignore */ }
  }, [])

  useEffect(() => { loadFrameworks(); loadReviewCount() }, [loadFrameworks, loadReviewCount])
  useEffect(() => { loadMeta() }, [loadMeta])
  useEffect(() => { loadControls() }, [loadControls])
  useEffect(() => { setCurrentPage(1) }, [severityFilter, domainFilter, stateFilter, verificationFilter, categoryFilter, evidenceTypeFilter, audienceFilter, sourceFilter, typeFilter, hideDuplicates, debouncedSearch, sortBy])

  const totalPages = Math.max(1, Math.ceil(totalCount / PAGE_SIZE))

  const fullReload = useCallback(async () => {
    await Promise.all([loadControls(), loadMeta(), loadFrameworks(), loadReviewCount()])
  }, [loadControls, loadMeta, loadFrameworks, loadReviewCount])

  const handleCreate = async (data: ControlFormData) => {
    setSaving(true)
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=create-control`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data),
      })
      if (!res.ok) { const err = await res.json(); alert(`Fehler: ${err.error || err.details || 'Unbekannt'}`); return }
      await fullReload(); setMode('list')
    } catch { alert('Netzwerkfehler') } finally { setSaving(false) }
  }

  const handleUpdate = async (data: ControlFormData) => {
    if (!selectedControl) return
    setSaving(true)
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=update-control&id=${selectedControl.control_id}`, {
        method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data),
      })
      if (!res.ok) { const err = await res.json(); alert(`Fehler: ${err.error || err.details || 'Unbekannt'}`); return }
      await fullReload(); setSelectedControl(null); setMode('list')
    } catch { alert('Netzwerkfehler') } finally { setSaving(false) }
  }

  const handleDelete = async (controlId: string) => {
    if (!confirm(`Control ${controlId} wirklich loeschen?`)) return
    try {
      const res = await fetch(`${BACKEND_URL}?id=${controlId}`, { method: 'DELETE' })
      if (!res.ok && res.status !== 204) { alert('Fehler beim Loeschen'); return }
      await fullReload(); setSelectedControl(null); setMode('list')
    } catch { alert('Netzwerkfehler') }
  }

  const handleReview = async (controlId: string, action: string) => {
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=review&id=${controlId}`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action }),
      })
      if (res.ok) {
        await fullReload()
        if (reviewMode) {
          const remaining = reviewItems.filter(c => c.control_id !== controlId)
          setReviewItems(remaining)
          if (remaining.length > 0) {
            const nextIdx = Math.min(reviewIndex, remaining.length - 1)
            setReviewIndex(nextIdx); setSelectedControl(remaining[nextIdx])
          } else { setReviewMode(false); setSelectedControl(null); setMode('list') }
        } else { setSelectedControl(null); setMode('list') }
      }
    } catch { /* ignore */ }
  }

  const handleBulkReject = async (sourceState: string) => {
    const count = stateFilter === sourceState ? totalCount : reviewCount
    if (!confirm(`Alle ${count} Controls mit Status "${sourceState}" auf "deprecated" setzen? Diese Aktion kann nicht rueckgaengig gemacht werden.`)) return
    setBulkProcessing(true)
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=bulk-review`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ release_state: sourceState, action: 'reject' }),
      })
      if (res.ok) { const data = await res.json(); alert(`${data.affected_count} Controls auf "deprecated" gesetzt.`); await fullReload() }
      else { const err = await res.json(); alert(`Fehler: ${err.error || err.details || 'Unbekannt'}`) }
    } catch { alert('Netzwerkfehler') } finally { setBulkProcessing(false) }
  }

  const loadProcessedStats = async () => {
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=processed-stats`)
      if (res.ok) { const data = await res.json(); setProcessedStats(data.stats || []) }
    } catch { /* ignore */ }
  }

  const enterReviewMode = async () => {
    try {
      const res = await fetch(`${BACKEND_URL}?endpoint=controls&release_state=needs_review&limit=1000`)
      if (res.ok) {
        const items: CanonicalControl[] = await res.json()
        if (items.length > 0) {
          const dupes = items.filter(c =>
            c.generation_metadata?.similar_controls &&
            Array.isArray(c.generation_metadata.similar_controls) &&
            (c.generation_metadata.similar_controls as unknown[]).length > 0
          )
          const rule3 = items.filter(c =>
            !c.generation_metadata?.similar_controls ||
            !Array.isArray(c.generation_metadata.similar_controls) ||
            (c.generation_metadata.similar_controls as unknown[]).length === 0
          )
          setReviewDuplicates(dupes); setReviewRule3(rule3)
          const startTab = dupes.length > 0 ? 'duplicates' : 'rule3'
          const startItems = startTab === 'duplicates' ? dupes : rule3
          setReviewTab(startTab); setReviewItems(startItems); setReviewMode(true)
          setReviewIndex(0); setSelectedControl(startItems[0]); setMode('detail')
        }
      }
    } catch { /* ignore */ }
  }

  const switchReviewTab = (tab: 'duplicates' | 'rule3') => {
    const items = tab === 'duplicates' ? reviewDuplicates : reviewRule3
    setReviewTab(tab); setReviewItems(items); setReviewIndex(0)
    if (items.length > 0) setSelectedControl(items[0])
  }

  return {
    // State
    frameworks, controls, totalCount, meta, selectedControl, setSelectedControl,
    loading, error, searchQuery, setSearchQuery, debouncedSearch,
    severityFilter, setSeverityFilter, domainFilter, setDomainFilter,
    stateFilter, setStateFilter, verificationFilter, setVerificationFilter,
    categoryFilter, setCategoryFilter, evidenceTypeFilter, setEvidenceTypeFilter,
    audienceFilter, setAudienceFilter, sourceFilter, setSourceFilter,
    typeFilter, setTypeFilter, hideDuplicates, setHideDuplicates,
    sortBy, setSortBy, mode, setMode, saving,
    showGenerator, setShowGenerator, processedStats, showStats, setShowStats,
    currentPage, setCurrentPage, totalPages,
    reviewMode, setReviewMode, reviewIndex, setReviewIndex,
    reviewItems, setReviewItems, reviewCount, reviewTab, setReviewTab,
    reviewDuplicates, reviewRule3, bulkProcessing,
    compareMode, setCompareMode, compareV1Control, setCompareV1Control, compareMatches, setCompareMatches,
    // Actions
    fullReload, loadControls, loadMeta, loadFrameworks, loadReviewCount,
    loadProcessedStats, handleCreate, handleUpdate, handleDelete,
    handleReview, handleBulkReject, enterReviewMode, switchReviewTab,
  }
}
