import { Fragment, useState } from 'react'
import { ChevronDown, ChevronRight, Download, FileSpreadsheet, Info, Loader2, Plus, Trash2 } from 'lucide-react'
import api from '@/services/api'
import { useAuth } from '@/context/AuthContext'
import { useReports, useGenerateReport, useDeleteReports, useReportData } from '@/hooks/useReports'
import { ReportViewer } from '@/components/ReportViewer'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Checkbox } from '@/components/ui/checkbox'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from '@/components/ui/table'
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from '@/components/ui/select'
import { Skeleton } from '@/components/ui/skeleton'
import { Alert, AlertDescription } from '@/components/ui/alert'
import {
  Tooltip, TooltipContent, TooltipTrigger,
} from '@/components/ui/tooltip'

const REPORT_TYPES = [
  { value: 'gesamt', label: 'Gesamt' },
  { value: 'onko_intensiv', label: 'Onko-Intensiv' },
  { value: 'galle_schild', label: 'Galle-Schild' },
] as const

const REPORT_TYPE_LABELS: Record<string, string> = {
  gesamt: 'Gesamt',
  onko_intensiv: 'Onko-Intensiv',
  galle_schild: 'Galle-Schild',
}

export function ReportsPage() {
  const { isAdmin } = useAuth()
  const currentYear = new Date().getFullYear()
  const currentKw = getISOWeek(new Date())

  // TanStack Query hooks — exclude Wochenübersicht reports (shown on separate page)
  const { data, isLoading: loading } = useReports()
  const reports = (data?.items ?? []).filter(r => !r.report_type.startsWith('wochenuebersicht'))
  const totalReports = reports.length

  const generateMutation = useGenerateReport()
  const deleteMutation = useDeleteReports()

  // Report generation state
  const [genJahr, setGenJahr] = useState(currentYear)
  const [genKw, setGenKw] = useState(currentKw)
  const [genReportType, setGenReportType] = useState('gesamt')
  const [genError, setGenError] = useState('')
  const [genSuccess, setGenSuccess] = useState('')

  // Selection state for deletion
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set())

  // Inline expansion state
  const [expandedId, setExpandedId] = useState<number | null>(null)
  const { data: reportData, isLoading: reportDataLoading } = useReportData(expandedId)

  const generateReport = async () => {
    setGenError('')
    setGenSuccess('')
    try {
      const result = await generateMutation.mutateAsync({
        jahr: genJahr, kw: genKw, report_type: genReportType,
      })
      const typeLabel = REPORT_TYPE_LABELS[result.report_type] ?? result.report_type
      setGenSuccess(`Bericht "${typeLabel}" für KW ${result.kw}/${result.jahr} wurde generiert.`)
    } catch {
      setGenError('Fehler beim Generieren des Berichts.')
    }
  }

  const downloadReport = (reportId: number) => {
    const token = localStorage.getItem('access_token')
    api.get(`/reports/download/${reportId}`, { responseType: 'blob' })
      .then((res) => {
        const blob = new Blob([res.data as BlobPart], {
          type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        })
        const blobUrl = window.URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = blobUrl
        const contentDisposition = res.headers['content-disposition']
        let filename = `bericht_${reportId}.xlsx`
        if (contentDisposition) {
          const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)
          if (match) filename = match[1].replace(/['"]/g, '')
        }
        link.download = filename
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(blobUrl)
      })
      .catch(() => {
        if (token) {
          window.open(`/api/reports/download/${reportId}?token=${encodeURIComponent(token)}`, '_blank')
        }
      })
  }

  const toggleSelect = (id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) {
        next.delete(id)
      } else {
        next.add(id)
      }
      return next
    })
  }

  const toggleSelectAll = () => {
    if (selectedIds.size === reports.length) {
      setSelectedIds(new Set())
    } else {
      setSelectedIds(new Set(reports.map((r) => r.id)))
    }
  }

  const deleteSelected = async () => {
    if (selectedIds.size === 0) return
    try {
      await deleteMutation.mutateAsync(Array.from(selectedIds))
      setSelectedIds(new Set())
    } catch {
      setGenError('Fehler beim Löschen der Berichte.')
    }
  }

  return (
    <div className="p-6 space-y-6">
      <h1 className="text-2xl font-bold">Berichte</h1>

      {/* Report generation (admin only) */}
      {isAdmin && (
        <Card>
          <CardHeader>
            <CardTitle className="text-lg flex items-center gap-2">
              <FileSpreadsheet className="h-5 w-5" />
              Bericht generieren
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-4">
            <div className="flex flex-wrap items-end gap-4">
              <div className="space-y-1">
                <Label htmlFor="gen-jahr">Jahr</Label>
                <Input
                  id="gen-jahr"
                  type="number"
                  value={genJahr}
                  onChange={(e) => setGenJahr(Number(e.target.value))}
                  className="w-28"
                  min={2020}
                  max={2030}
                />
              </div>
              <div className="space-y-1">
                <Label htmlFor="gen-kw">Kalenderwoche</Label>
                <Input
                  id="gen-kw"
                  type="number"
                  value={genKw}
                  onChange={(e) => setGenKw(Number(e.target.value))}
                  className="w-28"
                  min={1}
                  max={53}
                />
              </div>
              <div className="space-y-1">
                <Label>Berichtstyp</Label>
                <Select value={genReportType} onValueChange={setGenReportType}>
                  <SelectTrigger className="w-44">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {REPORT_TYPES.map((t) => (
                      <SelectItem key={t.value} value={t.value}>{t.label}</SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <Button onClick={generateReport} disabled={generateMutation.isPending}>
                {generateMutation.isPending ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Wird generiert...
                  </>
                ) : (
                  <>
                    <Plus className="mr-2 h-4 w-4" />
                    Bericht generieren
                  </>
                )}
              </Button>
            </div>
            {genError && (
              <Alert variant="destructive">
                <AlertDescription>{genError}</AlertDescription>
              </Alert>
            )}
            {genSuccess && (
              <Alert>
                <AlertDescription>{genSuccess}</AlertDescription>
              </Alert>
            )}
          </CardContent>
        </Card>
      )}

      {/* Reports table */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <CardTitle className="text-lg">
              Bisherige Berichte ({totalReports})
            </CardTitle>
            {isAdmin && selectedIds.size > 0 && (
              <Button
                variant="destructive"
                size="sm"
                onClick={deleteSelected}
                disabled={deleteMutation.isPending}
              >
                {deleteMutation.isPending ? (
                  <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                ) : (
                  <Trash2 className="mr-2 h-4 w-4" />
                )}
                {selectedIds.size} Bericht{selectedIds.size > 1 ? 'e' : ''} löschen
              </Button>
            )}
          </div>
        </CardHeader>
        <CardContent>
          {loading ? (
            <div className="space-y-2">
              {Array.from({ length: 5 }).map((_, i) => (
                <Skeleton key={i} className="h-10 w-full" />
              ))}
            </div>
          ) : reports.length > 0 ? (
            <Table>
              <TableHeader>
                <TableRow>
                  {isAdmin && (
                    <TableHead className="w-10">
                      <Checkbox
                        checked={reports.length > 0 && selectedIds.size === reports.length}
                        onCheckedChange={toggleSelectAll}
                      />
                    </TableHead>
                  )}
                  <TableHead>
                    <Tooltip>
                      <TooltipTrigger asChild>
                        <span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
                          Berichtsdatum
                          <Info className="size-3 text-muted-foreground" />
                        </span>
                      </TooltipTrigger>
                      <TooltipContent>Stichtag des Berichts</TooltipContent>
                    </Tooltip>
                  </TableHead>
                  <TableHead>Jahr</TableHead>
                  <TableHead>
                    <Tooltip>
                      <TooltipTrigger asChild>
                        <span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
                          KW
                          <Info className="size-3 text-muted-foreground" />
                        </span>
                      </TooltipTrigger>
                      <TooltipContent>Kalenderwoche des Berichtszeitraums</TooltipContent>
                    </Tooltip>
                  </TableHead>
                  <TableHead>
                    <Tooltip>
                      <TooltipTrigger asChild>
                        <span className="inline-flex items-center gap-1 cursor-help border-b border-dashed border-muted-foreground/40">
                          Typ
                          <Info className="size-3 text-muted-foreground" />
                        </span>
                      </TooltipTrigger>
                      <TooltipContent>Berichtstyp: Gesamt, Onko-Intensiv oder Galle-Schild</TooltipContent>
                    </Tooltip>
                  </TableHead>
                  <TableHead>Erstellt am</TableHead>
                  <TableHead className="text-right">Aktion</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {reports.map((r) => {
                  const isExpanded = expandedId === r.id
                  const colCount = isAdmin ? 7 : 6
                  return (
                    <Fragment key={r.id}>
                      <TableRow
                        className="cursor-pointer hover:bg-muted/50"
                        onClick={() => setExpandedId(isExpanded ? null : r.id)}
                      >
                        {isAdmin && (
                          <TableCell onClick={(e) => e.stopPropagation()}>
                            <Checkbox
                              checked={selectedIds.has(r.id)}
                              onCheckedChange={() => toggleSelect(r.id)}
                            />
                          </TableCell>
                        )}
                        <TableCell>
                          <span className="inline-flex items-center gap-1.5">
                            {isExpanded
                              ? <ChevronDown className="size-4 text-muted-foreground" />
                              : <ChevronRight className="size-4 text-muted-foreground" />}
                            {formatDate(r.report_date)}
                          </span>
                        </TableCell>
                        <TableCell>{r.jahr}</TableCell>
                        <TableCell>KW {r.kw}</TableCell>
                        <TableCell>{REPORT_TYPE_LABELS[r.report_type] ?? r.report_type}</TableCell>
                        <TableCell>{formatDateTime(r.generated_at)}</TableCell>
                        <TableCell className="text-right" onClick={(e) => e.stopPropagation()}>
                          <Button
                            variant="outline"
                            size="sm"
                            onClick={() => downloadReport(r.id)}
                          >
                            <Download className="mr-1.5 h-4 w-4" />
                            Download
                          </Button>
                        </TableCell>
                      </TableRow>
                      {isExpanded && (
                        <TableRow>
                          <TableCell colSpan={colCount} className="p-0">
                            {reportDataLoading ? (
                              <div className="p-6">
                                <Skeleton className="h-64 w-full" />
                              </div>
                            ) : reportData ? (
                              <div className="p-4 border-t bg-muted/20">
                                <ReportViewer data={reportData} />
                              </div>
                            ) : (
                              <div className="p-6 text-center text-muted-foreground">
                                Keine Berichtsdaten verfügbar.
                              </div>
                            )}
                          </TableCell>
                        </TableRow>
                      )}
                    </Fragment>
                  )
                })}
              </TableBody>
            </Table>
          ) : (
            <p className="py-8 text-center text-muted-foreground">
              Keine Berichte vorhanden.
            </p>
          )}
        </CardContent>
      </Card>
    </div>
  )
}

function getISOWeek(date: Date): number {
  const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()))
  const dayNum = d.getUTCDay() || 7
  d.setUTCDate(d.getUTCDate() + 4 - dayNum)
  const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1))
  return Math.ceil(((d.getTime() - yearStart.getTime()) / 86_400_000 + 1) / 7)
}

function formatDate(dateStr: string): string {
  try {
    return new Date(dateStr).toLocaleDateString('de-DE', {
      day: '2-digit', month: '2-digit', year: 'numeric',
    })
  } catch {
    return dateStr
  }
}

function formatDateTime(dateStr: string): string {
  try {
    return new Date(dateStr).toLocaleString('de-DE', {
      day: '2-digit', month: '2-digit', year: 'numeric',
      hour: '2-digit', minute: '2-digit',
    })
  } catch {
    return dateStr
  }
}
