"use client"

import { useState, useEffect } 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 } from "lucide-react"
import { toast } from "sonner"
import { formatDistanceToNow } from "date-fns"
import { ptBR } from "date-fns/locale"

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 "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
  }
}

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

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)

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

  const policyEvents = useQuery(
    api.usbPolicy.listUsbPolicyEvents,
    showHistory ? { machineId: machineId as Id<"machines">, limit: 10 } : "skip"
  )

  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 no topo */}
      {usbPolicy?.status && (
        <div className="flex items-center justify-between rounded-lg border bg-slate-50 p-3">
          <span className="text-sm font-medium text-slate-600">Status da política</span>
          {getStatusBadge(usbPolicy.status)}
        </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>

      <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 && policyEvents && (
          <div className="mt-3 space-y-2">
            {policyEvents.length === 0 ? (
              <p className="text-center text-xs text-muted-foreground py-2">
                Nenhuma alteração registrada
              </p>
            ) : (
              policyEvents.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>
        )}
      </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>
  )
}
