'use client'

import { useState, useEffect, useRef } from 'react'
import { useSDK, Evidence as SDKEvidence, EvidenceType } from '@/lib/sdk'
import {
  DisplayEvidence,
  EvidenceCheck,
  CheckResult,
  EvidenceMapping,
  CoverageReport,
  EvidenceTabKey,
  mapEvidenceTypeToDisplay,
  getEvidenceStatus,
  evidenceTemplates,
  CHECK_API,
} from '../_components/EvidenceTypes'

type AntiFakeMeta = Record<string, {
  confidenceLevel: string | null
  truthStatus: string | null
  generationMode: string | null
  approvalStatus: string | null
  requiresFourEyes: boolean
}>

export function useEvidence() {
  const { state, dispatch } = useSDK()
  const [activeTab, setActiveTab] = useState<EvidenceTabKey>('evidence')
  const [filter, setFilter] = useState<string>('all')
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [uploading, setUploading] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)
  const [page, setPage] = useState(1)
  const [pageSize] = useState(20)
  const [total, setTotal] = useState(0)
  const [antiFakeMeta, setAntiFakeMeta] = useState<AntiFakeMeta>({})

  // Evidence Checks state
  const [checks, setChecks] = useState<EvidenceCheck[]>([])
  const [checksLoading, setChecksLoading] = useState(false)
  const [runningCheckId, setRunningCheckId] = useState<string | null>(null)
  const [checkResults, setCheckResults] = useState<Record<string, CheckResult[]>>({})

  // Mappings state
  const [mappings, setMappings] = useState<EvidenceMapping[]>([])
  const [coverageReport, setCoverageReport] = useState<CoverageReport | null>(null)
  const [seedingChecks, setSeedingChecks] = useState(false)

  // Phase 3: Review/Reject/AuditTrail state
  const [reviewEvidence, setReviewEvidence] = useState<DisplayEvidence | null>(null)
  const [rejectEvidence, setRejectEvidence] = useState<DisplayEvidence | null>(null)
  const [auditTrailId, setAuditTrailId] = useState<string | null>(null)
  const [confidenceFilter, setConfidenceFilter] = useState<string | null>(null)
  const [refreshKey, setRefreshKey] = useState(0)

  useEffect(() => {
    const fetchEvidence = async () => {
      try {
        setLoading(true)
        const res = await fetch(`/api/sdk/v1/compliance/evidence?page=${page}&limit=${pageSize}`)
        if (res.ok) {
          const data = await res.json()
          if (data.total !== undefined) setTotal(data.total)
          const backendEvidence = data.evidence || data
          if (Array.isArray(backendEvidence) && backendEvidence.length > 0) {
            const metaMap: AntiFakeMeta = {}
            const mapped: SDKEvidence[] = backendEvidence.map((e: Record<string, unknown>) => {
              const id = (e.id || '') as string
              metaMap[id] = {
                confidenceLevel: (e.confidence_level || null) as string | null,
                truthStatus: (e.truth_status || null) as string | null,
                generationMode: (e.generation_mode || null) as string | null,
                approvalStatus: (e.approval_status || null) as string | null,
                requiresFourEyes: !!e.requires_four_eyes,
              }
              return {
                id,
                controlId: (e.control_id || '') as string,
                type: ((e.evidence_type || 'DOCUMENT') as string).toUpperCase() as EvidenceType,
                name: (e.title || e.name || '') as string,
                description: (e.description || '') as string,
                fileUrl: (e.artifact_url || null) as string | null,
                validFrom: e.valid_from ? new Date(e.valid_from as string) : new Date(),
                validUntil: e.valid_until ? new Date(e.valid_until as string) : null,
                uploadedBy: (e.uploaded_by || 'System') as string,
                uploadedAt: e.created_at ? new Date(e.created_at as string) : new Date(),
              }
            })
            setAntiFakeMeta(metaMap)
            dispatch({ type: 'SET_STATE', payload: { evidence: mapped } })
            setError(null)
            return
          }
        }
        loadFromTemplates()
      } catch {
        loadFromTemplates()
      } finally {
        setLoading(false)
      }
    }

    const loadFromTemplates = () => {
      if (state.evidence.length > 0) return
      if (state.controls.length === 0) return
      const relevantEvidence = evidenceTemplates.filter(e =>
        state.controls.some(c => c.id === e.controlId || e.linkedControls.includes(c.id))
      )
      const now = new Date()
      relevantEvidence.forEach(template => {
        const validFrom = new Date(now)
        validFrom.setMonth(validFrom.getMonth() - 1)
        const validUntil = template.validityDays > 0
          ? new Date(validFrom.getTime() + template.validityDays * 24 * 60 * 60 * 1000)
          : null
        const sdkEvidence: SDKEvidence = {
          id: template.id,
          controlId: template.controlId,
          type: template.type,
          name: template.name,
          description: template.description,
          fileUrl: null,
          validFrom,
          validUntil,
          uploadedBy: template.uploadedBy,
          uploadedAt: validFrom,
        }
        dispatch({ type: 'ADD_EVIDENCE', payload: sdkEvidence })
      })
    }

    fetchEvidence()
  }, [page, pageSize, refreshKey]) // eslint-disable-line react-hooks/exhaustive-deps

  const displayEvidence: DisplayEvidence[] = state.evidence.map(ev => {
    const template = evidenceTemplates.find(t => t.id === ev.id)
    const meta = antiFakeMeta[ev.id]
    return {
      id: ev.id,
      name: ev.name,
      description: ev.description,
      displayType: mapEvidenceTypeToDisplay(ev.type),
      format: template?.format || 'pdf',
      controlId: ev.controlId,
      linkedRequirements: template?.linkedRequirements || [],
      linkedControls: template?.linkedControls || [ev.controlId],
      uploadedBy: ev.uploadedBy,
      uploadedAt: ev.uploadedAt,
      validFrom: ev.validFrom,
      validUntil: ev.validUntil,
      status: getEvidenceStatus(ev.validUntil),
      fileSize: template?.fileSize || 'Unbekannt',
      fileUrl: ev.fileUrl,
      confidenceLevel: meta?.confidenceLevel || null,
      truthStatus: meta?.truthStatus || null,
      generationMode: meta?.generationMode || null,
      approvalStatus: meta?.approvalStatus || null,
      requiresFourEyes: meta?.requiresFourEyes || false,
    }
  })

  const filteredEvidence = (filter === 'all'
    ? displayEvidence
    : displayEvidence.filter(e => e.status === filter || e.displayType === filter)
  ).filter(e => !confidenceFilter || e.confidenceLevel === confidenceFilter)

  const validCount = displayEvidence.filter(e => e.status === 'valid').length
  const expiredCount = displayEvidence.filter(e => e.status === 'expired').length
  const pendingCount = displayEvidence.filter(e => e.status === 'pending-review').length

  const handleDelete = async (evidenceId: string) => {
    if (!confirm('Moechten Sie diesen Nachweis wirklich loeschen?')) return
    dispatch({ type: 'DELETE_EVIDENCE', payload: evidenceId })
    try {
      await fetch(`/api/sdk/v1/compliance/evidence/${evidenceId}`, { method: 'DELETE' })
    } catch { /* Silently fail */ }
  }

  const handleUpload = async (file: File) => {
    setUploading(true)
    setError(null)
    try {
      const controlId = state.controls.length > 0 ? state.controls[0].id : 'GENERIC'
      const params = new URLSearchParams({ control_id: controlId, evidence_type: 'document', title: file.name })
      const formData = new FormData()
      formData.append('file', file)
      const res = await fetch(`/api/sdk/v1/compliance/evidence/upload?${params}`, { method: 'POST', body: formData })
      if (!res.ok) {
        const errData = await res.json().catch(() => ({ error: 'Upload fehlgeschlagen' }))
        throw new Error(errData.error || errData.detail || 'Upload fehlgeschlagen')
      }
      const data = await res.json()
      const newEvidence: SDKEvidence = {
        id: data.id || `ev-${Date.now()}`,
        controlId,
        type: 'DOCUMENT',
        name: file.name,
        description: `Hochgeladen am ${new Date().toLocaleDateString('de-DE')}`,
        fileUrl: data.artifact_url || null,
        validFrom: new Date(),
        validUntil: null,
        uploadedBy: 'Aktueller Benutzer',
        uploadedAt: new Date(),
      }
      dispatch({ type: 'ADD_EVIDENCE', payload: newEvidence })
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen')
    } finally {
      setUploading(false)
    }
  }

  const handleView = (ev: DisplayEvidence) => {
    if (ev.fileUrl) window.open(ev.fileUrl, '_blank')
    else alert('Keine Datei vorhanden')
  }

  const handleDownload = (ev: DisplayEvidence) => {
    if (!ev.fileUrl) return
    const a = document.createElement('a')
    a.href = ev.fileUrl
    a.download = ev.name
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
  }

  const handleUploadClick = () => fileInputRef.current?.click()

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) { handleUpload(file); e.target.value = '' }
  }

  const loadChecks = async () => {
    setChecksLoading(true)
    try {
      const res = await fetch(`${CHECK_API}?limit=50`)
      if (res.ok) { const data = await res.json(); setChecks(data.checks || []) }
    } catch { /* silent */ }
    finally { setChecksLoading(false) }
  }

  const runCheck = async (checkId: string) => {
    setRunningCheckId(checkId)
    try {
      const res = await fetch(`${CHECK_API}/${checkId}/run`, { method: 'POST' })
      if (res.ok) {
        const result = await res.json()
        setCheckResults(prev => ({ ...prev, [checkId]: [result, ...(prev[checkId] || [])].slice(0, 5) }))
        loadChecks()
      }
    } catch { /* silent */ }
    finally { setRunningCheckId(null) }
  }

  const loadCheckResults = async (checkId: string) => {
    try {
      const res = await fetch(`${CHECK_API}/${checkId}/results?limit=5`)
      if (res.ok) { const data = await res.json(); setCheckResults(prev => ({ ...prev, [checkId]: data.results || [] })) }
    } catch { /* silent */ }
  }

  const seedChecks = async () => {
    setSeedingChecks(true)
    try { await fetch(`${CHECK_API}/seed`, { method: 'POST' }); loadChecks() }
    catch { /* silent */ }
    finally { setSeedingChecks(false) }
  }

  const loadMappings = async () => {
    try {
      const res = await fetch(`${CHECK_API}/mappings`)
      if (res.ok) { const data = await res.json(); setMappings(data.mappings || []) }
    } catch { /* silent */ }
  }

  const loadCoverageReport = async () => {
    try {
      const res = await fetch(`${CHECK_API}/mappings/report`)
      if (res.ok) setCoverageReport(await res.json())
    } catch { /* silent */ }
  }

  useEffect(() => {
    if (activeTab === 'checks' && checks.length === 0) loadChecks()
    if (activeTab === 'mapping') { loadMappings(); loadCoverageReport() }
    if (activeTab === 'report') loadCoverageReport()
  }, [activeTab]) // eslint-disable-line react-hooks/exhaustive-deps

  return {
    state,
    activeTab,
    setActiveTab,
    filter,
    setFilter,
    loading,
    error,
    setError,
    uploading,
    fileInputRef,
    page,
    setPage,
    pageSize,
    total,
    displayEvidence,
    filteredEvidence,
    validCount,
    expiredCount,
    pendingCount,
    confidenceFilter,
    setConfidenceFilter,
    reviewEvidence,
    setReviewEvidence,
    rejectEvidence,
    setRejectEvidence,
    auditTrailId,
    setAuditTrailId,
    setRefreshKey,
    checks,
    checksLoading,
    checkResults,
    runningCheckId,
    seedingChecks,
    mappings,
    coverageReport,
    handleDelete,
    handleView,
    handleDownload,
    handleUploadClick,
    handleFileChange,
    runCheck,
    loadCheckResults,
    seedChecks,
  }
}
