"use client"

import { useState, useEffect, useMemo } from "react"
import { useMutation, useQuery } from "convex/react"
import { api } from "@/convex/_generated/api"
import type { Id } from "@/convex/_generated/dataModel"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "@/components/ui/tooltip"
import { Usb, Shield, ShieldOff, ShieldAlert, Clock, CheckCircle2, XCircle, Loader2, History, Filter, ChevronDown, RotateCcw, Info, HardDrive } from "lucide-react"
import { toast } from "sonner"
import { formatDistanceToNow, startOfDay, endOfDay, parseISO } from "date-fns"
import { ptBR } from "date-fns/locale"
import { DateRangeButton } from "@/components/date-range-button"

type UsbPolicyValue = "ALLOW" | "BLOCK_ALL" | "READONLY"

interface UsbPolicyEvent {
  id: string
  oldPolicy?: string
  newPolicy: string
  status: string
  error?: string
  actorEmail?: string
  actorName?: string
  createdAt: number
  appliedAt?: number
}

const POLICY_OPTIONS: Array<{ value: UsbPolicyValue; label: string; description: string; icon: typeof Shield }> = [
  {
    value: "ALLOW",
    label: "Permitido",
    description: "Acesso total a dispositivos USB de armazenamento",
    icon: Shield,
  },
  {
    value: "BLOCK_ALL",
    label: "Bloqueado",
    description: "Nenhum acesso a dispositivos USB de armazenamento",
    icon: ShieldOff,
  },
  {
    value: "READONLY",
    label: "Somente leitura",
    description: "Permite leitura, bloqueia escrita em dispositivos USB",
    icon: ShieldAlert,
  },
]

function getPolicyConfig(policy: string | undefined | null) {
  return POLICY_OPTIONS.find((opt) => opt.value === policy) ?? POLICY_OPTIONS[0]
}

function getStatusBadge(status: string | undefined | null) {
  switch (status) {
    case "PENDING":
      return (
        <Badge variant="outline" className="gap-1 border-amber-200 bg-amber-50 text-amber-700">
          <Clock className="size-3" />
          Pendente
        </Badge>
      )
    case "APPLYING":
      return (
        <Badge variant="outline" className="gap-1 border-blue-200 bg-blue-50 text-blue-700">
          <Loader2 className="size-3 animate-spin" />
          Aplicando
        </Badge>
      )
    case "APPLIED":
      return (
        <Badge variant="outline" className="gap-1 border-emerald-200 bg-emerald-50 text-emerald-700">
          <CheckCircle2 className="size-3" />
          Aplicado
        </Badge>
      )
    case "FAILED":
      return (
        <Badge variant="outline" className="gap-1 border-red-200 bg-red-50 text-red-700">
          <XCircle className="size-3" />
          Falhou
        </Badge>
      )
    default:
      return null
  }
}

function getProgressValue(status: string | undefined | null): number {
  switch (status) {
    case "PENDING":
      return 33
    case "APPLYING":
      return 66
    case "APPLIED":
      return 100
    case "FAILED":
      return 100
    default:
      return 0
  }
}

function getProgressColor(status: string | undefined | null): string {
  switch (status) {
    case "PENDING":
      return "bg-amber-500"
    case "APPLYING":
      return "bg-blue-500"
    case "APPLIED":
      return "bg-emerald-500"
    case "FAILED":
      return "bg-red-500"
    default:
      return "bg-neutral-300"
  }
}

interface UsbPolicyControlProps {
  machineId: string
  machineName?: string
  actorEmail?: string
  actorName?: string
  actorId?: string
  disabled?: boolean
  variant?: "card" | "inline"
}

const STATUS_FILTER_OPTIONS = [
  { value: "all", label: "Todos os status" },
  { value: "PENDING", label: "Pendente" },
  { value: "APPLYING", label: "Aplicando" },
  { value: "APPLIED", label: "Aplicado" },
  { value: "FAILED", label: "Falhou" },
]

export function UsbPolicyControl({
  machineId,
  machineName,
  actorEmail,
  actorName,
  actorId,
  disabled = false,
  variant = "card",
}: UsbPolicyControlProps) {
  const [selectedPolicy, setSelectedPolicy] = useState<UsbPolicyValue>("ALLOW")
  const [isApplying, setIsApplying] = useState(false)
  const [showHistory, setShowHistory] = useState(false)

  // Filtros do historico
  const [statusFilter, setStatusFilter] = useState<string>("all")
  const [dateFrom, setDateFrom] = useState<string | null>(null)
  const [dateTo, setDateTo] = useState<string | null>(null)
  const [allEvents, setAllEvents] = useState<UsbPolicyEvent[]>([])
  const [cursor, setCursor] = useState<number | undefined>(undefined)

  const usbPolicy = useQuery(api.usbPolicy.getUsbPolicy, {
    machineId: machineId as Id<"machines">,
  })

  // Converte datas para timestamp
  const dateFromTs = useMemo(() => {
    if (!dateFrom) return undefined
    return startOfDay(parseISO(dateFrom)).getTime()
  }, [dateFrom])

  const dateToTs = useMemo(() => {
    if (!dateTo) return undefined
    return endOfDay(parseISO(dateTo)).getTime()
  }, [dateTo])

  const policyEventsResult = useQuery(
    api.usbPolicy.listUsbPolicyEvents,
    showHistory
      ? {
          machineId: machineId as Id<"machines">,
          limit: 10,
          cursor,
          status: statusFilter !== "all" ? statusFilter : undefined,
          dateFrom: dateFromTs,
          dateTo: dateToTs,
        }
      : "skip"
  )

  // Acumula eventos quando carrega mais
  useEffect(() => {
    if (policyEventsResult?.events) {
      if (cursor === undefined) {
        // Reset quando filtros mudam
        setAllEvents(policyEventsResult.events)
      } else {
        // Acumula quando carrega mais
        setAllEvents((prev) => [...prev, ...policyEventsResult.events])
      }
    }
  }, [policyEventsResult?.events, cursor])

  // Reset cursor quando filtros mudam
  useEffect(() => {
    setCursor(undefined)
    setAllEvents([])
  }, [statusFilter, dateFrom, dateTo])

  const handleLoadMore = () => {
    if (policyEventsResult?.nextCursor) {
      setCursor(policyEventsResult.nextCursor)
    }
  }

  const handleResetFilters = () => {
    setStatusFilter("all")
    setDateFrom(null)
    setDateTo(null)
    setCursor(undefined)
    setAllEvents([])
  }

  const hasActiveFilters = statusFilter !== "all" || dateFrom !== null || dateTo !== null

  const setUsbPolicyMutation = useMutation(api.usbPolicy.setUsbPolicy)

  useEffect(() => {
    if (usbPolicy?.policy) {
      setSelectedPolicy(usbPolicy.policy as UsbPolicyValue)
    }
  }, [usbPolicy?.policy])

  const currentConfig = getPolicyConfig(usbPolicy?.policy)
  const CurrentIcon = currentConfig.icon

  const handleApplyPolicy = async () => {
    if (selectedPolicy === usbPolicy?.policy) {
      toast.info("A política selecionada já está aplicada.")
      return
    }

    setIsApplying(true)
    try {
      await setUsbPolicyMutation({
        machineId: machineId as Id<"machines">,
        policy: selectedPolicy,
        actorId: actorId ? (actorId as Id<"users">) : undefined,
        actorEmail,
        actorName,
      })
      toast.success("Política USB enviada para aplicação.")
    } catch (error) {
      console.error("[usb-policy] Falha ao aplicar política", error)
      toast.error("Falha ao aplicar política USB. Tente novamente.")
    } finally {
      setIsApplying(false)
    }
  }

  const formatEventDate = (timestamp: number) => {
    return formatDistanceToNow(new Date(timestamp), {
      addSuffix: true,
      locale: ptBR,
    })
  }

  const content = (
    <div className="space-y-4">
      {/* Status atual com progress bar real */}
      {usbPolicy?.status && (
        <div className="space-y-2 rounded-lg border bg-slate-50 p-3">
          <div className="flex items-center justify-between">
            <span className="text-sm font-medium text-slate-600">Status da política</span>
            {getStatusBadge(usbPolicy.status)}
          </div>
          {/* Progress bar real baseada no estado */}
          {(usbPolicy.status === "PENDING" || usbPolicy.status === "APPLYING") && (
            <div className="space-y-1">
              <div className="h-2 w-full overflow-hidden rounded-full bg-slate-200">
                <div
                  className={`h-full transition-all duration-500 ease-out ${getProgressColor(usbPolicy.status)}`}
                  style={{ width: `${getProgressValue(usbPolicy.status)}%` }}
                />
              </div>
              <p className="text-xs text-muted-foreground">
                {usbPolicy.status === "PENDING" ? "Aguardando agente..." : "Agente aplicando política..."}
              </p>
            </div>
          )}
        </div>
      )}

      {usbPolicy?.error && (
        <div className="rounded-lg border border-red-200 bg-red-50 p-3">
          <p className="text-sm font-medium text-red-700">Erro na aplicação</p>
          <p className="text-xs text-red-600">{usbPolicy.error}</p>
        </div>
      )}

      {/* Política atual */}
      <div className="flex items-center gap-3 rounded-lg border bg-neutral-50 p-3">
        <div className="flex size-10 items-center justify-center rounded-full bg-white shadow-sm">
          <CurrentIcon className="size-5 text-neutral-600" />
        </div>
        <div className="flex-1">
          <p className="text-sm font-medium">{currentConfig.label}</p>
          <p className="text-xs text-muted-foreground">{currentConfig.description}</p>
        </div>
      </div>

      {/* Info sobre dispositivos afetados */}
      <div className="flex items-start gap-3 rounded-lg border bg-slate-50 p-3">
        <Info className="mt-0.5 size-4 shrink-0 text-foreground" />
        <div className="space-y-2">
          <p className="text-sm font-medium text-foreground">Dispositivos afetados</p>
          <div className="flex flex-wrap gap-2">
            <span className="inline-flex items-center gap-1.5 rounded-full border border-slate-200 bg-slate-100 px-2.5 py-1 text-xs font-medium text-foreground">
              <HardDrive className="size-3" />
              Pen drives
            </span>
            <span className="inline-flex items-center gap-1.5 rounded-full border border-slate-200 bg-slate-100 px-2.5 py-1 text-xs font-medium text-foreground">
              <HardDrive className="size-3" />
              HDs externos
            </span>
            <span className="inline-flex items-center gap-1.5 rounded-full border border-slate-200 bg-slate-100 px-2.5 py-1 text-xs font-medium text-foreground">
              <HardDrive className="size-3" />
              Cartões SD
            </span>
          </div>
          <p className="text-xs text-muted-foreground">
            Não afeta teclados, mouses, impressoras ou outros periféricos USB.
          </p>
        </div>
      </div>

      <div className="flex items-end gap-2">
        <div className="flex-1 space-y-1.5">
          <label className="text-xs font-medium text-muted-foreground">Alterar política</label>
          <Select
            value={selectedPolicy}
            onValueChange={(value) => setSelectedPolicy(value as UsbPolicyValue)}
            disabled={disabled || isApplying}
          >
            <SelectTrigger>
              <SelectValue placeholder="Selecione uma política" />
            </SelectTrigger>
            <SelectContent>
              {POLICY_OPTIONS.map((option) => {
                const Icon = option.icon
                return (
                  <SelectItem key={option.value} value={option.value}>
                    <div className="flex items-center gap-2">
                      <Icon className="size-4" />
                      <span>{option.label}</span>
                    </div>
                  </SelectItem>
                )
              })}
            </SelectContent>
          </Select>
        </div>
        <TooltipProvider>
          <Tooltip>
            <TooltipTrigger asChild>
              <Button
                onClick={handleApplyPolicy}
                disabled={disabled || isApplying || selectedPolicy === usbPolicy?.policy}
                size="default"
              >
                {isApplying ? (
                  <>
                    <Loader2 className="mr-2 size-4 animate-spin" />
                    Aplicando...
                  </>
                ) : (
                  "Aplicar"
                )}
              </Button>
            </TooltipTrigger>
            <TooltipContent>
              {selectedPolicy === usbPolicy?.policy
                ? "A política já está aplicada"
                : `Aplicar política "${getPolicyConfig(selectedPolicy).label}"`}
            </TooltipContent>
          </Tooltip>
        </TooltipProvider>
      </div>

      <div className="border-t pt-3">
        <Button
          variant="ghost"
          size="sm"
          className="w-full justify-start gap-2 text-muted-foreground"
          onClick={() => setShowHistory(!showHistory)}
        >
          <History className="size-4" />
          {showHistory ? "Ocultar histórico" : "Ver histórico de alterações"}
        </Button>

        {showHistory && (
          <div className="mt-3 space-y-3">
            {/* Filtros */}
            <div className="space-y-2 rounded-lg border bg-slate-50/80 p-3">
              <div className="flex items-center gap-1.5 text-xs font-medium text-muted-foreground">
                <Filter className="size-3.5" />
                <span>Filtros</span>
                {hasActiveFilters && (
                  <Button
                    variant="ghost"
                    size="sm"
                    className="ml-auto h-6 gap-1 px-2 text-xs text-muted-foreground hover:text-foreground"
                    onClick={handleResetFilters}
                  >
                    <RotateCcw className="size-3" />
                    Limpar
                  </Button>
                )}
              </div>
              <div className="grid grid-cols-2 gap-2">
                <Select value={statusFilter} onValueChange={setStatusFilter}>
                  <SelectTrigger className="h-9 text-sm">
                    <SelectValue placeholder="Status" />
                  </SelectTrigger>
                  <SelectContent>
                    {STATUS_FILTER_OPTIONS.map((opt) => (
                      <SelectItem key={opt.value} value={opt.value}>
                        {opt.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <DateRangeButton
                  from={dateFrom}
                  to={dateTo}
                  onChange={({ from, to }) => {
                    setDateFrom(from)
                    setDateTo(to)
                  }}
                  className="h-9"
                  clearLabel="Limpar"
                />
              </div>
            </div>

            {/* Lista de eventos */}
            {allEvents.length === 0 ? (
              <p className="text-center text-xs text-muted-foreground py-4">
                {hasActiveFilters
                  ? "Nenhuma alteração encontrada com os filtros selecionados"
                  : "Nenhuma alteração registrada"}
              </p>
            ) : (
              <>
                <div className="space-y-2">
                  {allEvents.map((event: UsbPolicyEvent) => (
                    <div
                      key={event.id}
                      className="flex items-start justify-between rounded-md border bg-white p-2 text-xs"
                    >
                      <div className="space-y-0.5">
                        <div className="flex items-center gap-1.5">
                          <span className="font-medium">
                            {getPolicyConfig(event.oldPolicy).label}
                          </span>
                          <span className="text-muted-foreground">&rarr;</span>
                          <span className="font-medium">
                            {getPolicyConfig(event.newPolicy).label}
                          </span>
                          {getStatusBadge(event.status)}
                        </div>
                        <p className="text-muted-foreground">
                          {event.actorName ?? event.actorEmail ?? "Sistema"} &middot; {formatEventDate(event.createdAt)}
                        </p>
                        {event.error && (
                          <p className="text-red-600">{event.error}</p>
                        )}
                      </div>
                    </div>
                  ))}
                </div>

                {/* Paginacao */}
                {policyEventsResult?.hasMore && (
                  <Button
                    variant="ghost"
                    size="sm"
                    className="w-full gap-1 text-xs text-muted-foreground"
                    onClick={handleLoadMore}
                  >
                    <ChevronDown className="size-3.5" />
                    Carregar mais
                  </Button>
                )}
              </>
            )}
          </div>
        )}
      </div>

      {usbPolicy?.reportedAt && (
        <p className="text-xs text-muted-foreground">
          Último relato do agente: {formatEventDate(usbPolicy.reportedAt)}
        </p>
      )}
    </div>
  )

  if (variant === "inline") {
    return content
  }

  return (
    <Card>
      <CardHeader className="pb-3">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Usb className="size-5 text-neutral-500" />
            <CardTitle className="text-base">Controle USB</CardTitle>
          </div>
        </div>
        <CardDescription>
          Gerencie o acesso a dispositivos de armazenamento USB neste dispositivo.
        </CardDescription>
      </CardHeader>
      <CardContent>
        {content}
      </CardContent>
    </Card>
  )
}
