'use client'

import { useState, useEffect } from 'react'
import {
  Monitor,
  Laptop,
  Server,
  Smartphone,
  Tablet,
  Router,
  Network,
  Shield,
  Wifi,
  Printer,
  HelpCircle,
  X,
  Pencil,
} from 'lucide-react'
import { trpc } from '@/lib/trpc-client'
import { cn } from '@/lib/utils'
import { mapDeviceToDetail } from '@/mocks/deviceDetailData'
import InfoSection from './InfoSection'
import SoftwareList from './SoftwareList'
import ActionBar from './ActionBar'

const DEVICE_TYPE_ICONS: Record<string, React.ReactNode> = {
  PC: <Monitor className="h-6 w-6" />,
  LAPTOP: <Laptop className="h-6 w-6" />,
  SERVIDOR: <Server className="h-6 w-6" />,
  CELULAR: <Smartphone className="h-6 w-6" />,
  TABLET: <Tablet className="h-6 w-6" />,
  ROUTER: <Router className="h-6 w-6" />,
  SWITCH: <Network className="h-6 w-6" />,
  FIREWALL: <Shield className="h-6 w-6" />,
  AP: <Wifi className="h-6 w-6" />,
  IMPRESORA: <Printer className="h-6 w-6" />,
  OTRO: <HelpCircle className="h-6 w-6" />,
}

const DEVICE_TYPE_OPTIONS: { value: string; label: string }[] = [
  { value: 'PC', label: 'PC' },
  { value: 'LAPTOP', label: 'Laptop' },
  { value: 'SERVIDOR', label: 'Servidor' },
  { value: 'CELULAR', label: 'Celular' },
  { value: 'TABLET', label: 'Tablet' },
  { value: 'ROUTER', label: 'Router' },
  { value: 'SWITCH', label: 'Switch' },
  { value: 'FIREWALL', label: 'Firewall' },
  { value: 'AP', label: 'Access Point' },
  { value: 'IMPRESORA', label: 'Impresora' },
  { value: 'OTRO', label: 'Otro' },
]

const DEVICE_STATUS_OPTIONS: { value: string; label: string }[] = [
  { value: 'DESCONOCIDO', label: 'Desconocido' },
  { value: 'ONLINE', label: 'En línea' },
  { value: 'OFFLINE', label: 'Fuera de línea' },
  { value: 'ALERTA', label: 'Advertencia' },
  { value: 'MANTENIMIENTO', label: 'Mantenimiento' },
]

const INPUT_CLASS =
  'w-full rounded-lg border border-white/10 bg-dark-300 px-4 py-2.5 text-sm text-gray-200 placeholder-gray-500 focus:border-primary-500/50 focus:outline-none focus:ring-2 focus:ring-primary-500/20'

type DeviceTypeValue =
  | 'PC'
  | 'LAPTOP'
  | 'SERVIDOR'
  | 'CELULAR'
  | 'TABLET'
  | 'ROUTER'
  | 'SWITCH'
  | 'FIREWALL'
  | 'AP'
  | 'IMPRESORA'
  | 'OTRO'

type DeviceStatusValue = 'ONLINE' | 'OFFLINE' | 'ALERTA' | 'MANTENIMIENTO' | 'DESCONOCIDO'

interface EditFormState {
  tipo: string
  nombre: string
  descripcion: string
  ubicacionId: string
  estado: string
  ip: string
  mac: string
  sistemaOperativo: string
  versionSO: string
  fabricante: string
  modelo: string
  serial: string
}

interface DeviceFromApi {
  tipo: string
  nombre: string
  descripcion?: string | null
  ubicacionId?: string | null
  estado: string
  ip?: string | null
  mac?: string | null
  sistemaOperativo?: string | null
  versionSO?: string | null
  fabricante?: string | null
  modelo?: string | null
  serial?: string | null
}

function buildEditFormFromDevice(device: DeviceFromApi): EditFormState {
  return {
    tipo: device.tipo,
    nombre: device.nombre,
    descripcion: device.descripcion ?? '',
    ubicacionId: device.ubicacionId ?? '',
    estado: device.estado,
    ip: device.ip ?? '',
    mac: device.mac ?? '',
    sistemaOperativo: device.sistemaOperativo ?? '',
    versionSO: device.versionSO ?? '',
    fabricante: device.fabricante ?? '',
    modelo: device.modelo ?? '',
    serial: device.serial ?? '',
  }
}

interface DeviceDetailModalProps {
  open: boolean
  onClose: () => void
  deviceId: string | null
  deviceName?: string
  onConnect?: (id: string) => void
  onTerminal?: (id: string) => void
  onFiles?: (id: string) => void
}

export default function DeviceDetailModal({
  open,
  onClose,
  deviceId,
  deviceName = 'Dispositivo',
  onConnect,
  onTerminal,
  onFiles,
}: DeviceDetailModalProps) {
  const [isEditing, setIsEditing] = useState(false)
  const [editForm, setEditForm] = useState<EditFormState | null>(null)
  const [editError, setEditError] = useState<string | null>(null)

  const utils = trpc.useUtils()
  const deviceQuery = trpc.equipos.byId.useQuery(
    { id: deviceId! },
    { enabled: open && !!deviceId }
  )
  const device = deviceQuery.data
  const clientId = device?.clienteId

  const locationsQuery = trpc.clientes.ubicaciones.list.useQuery(
    { clienteId: clientId! },
    { enabled: open && !!clientId && isEditing }
  )

  const updateMutation = trpc.equipos.update.useMutation({
    onSuccess: () => {
      utils.equipos.byId.invalidate({ id: deviceId! })
      utils.equipos.list.invalidate()
      utils.clientes.dashboardStats.invalidate()
      setIsEditing(false)
      setEditForm(null)
      setEditError(null)
    },
    onError: (err) => {
      setEditError(err.message)
    },
  })

  useEffect(() => {
    if (!open) {
      setIsEditing(false)
      setEditForm(null)
      setEditError(null)
    }
  }, [open])

  useEffect(() => {
    if (isEditing && device) {
      setEditForm(buildEditFormFromDevice(device))
      setEditError(null)
    }
  }, [isEditing, device])

  const detail = device ? mapDeviceToDetail(device) : null
  const isLoading = deviceQuery.isLoading
  const hasError = deviceQuery.isError

  const systemItems = detail
    ? [
        { label: 'Sistema Operativo', value: detail.systemInfo.sistemaOperativo },
        { label: 'Procesador', value: detail.systemInfo.procesador },
        { label: 'Memoria RAM', value: detail.systemInfo.memoriaRam },
        {
          label: 'Almacenamiento',
          value:
            detail.systemInfo.almacenamientoUsoPercent != null
              ? `${detail.systemInfo.almacenamiento} (${detail.systemInfo.almacenamientoUsoPercent}% uso)`
              : detail.systemInfo.almacenamiento,
        },
      ]
    : []

  const networkItems = detail
    ? [
        { label: 'Dirección IP', value: detail.networkInfo.direccionIp },
        { label: 'Dirección MAC', value: detail.networkInfo.direccionMac },
        { label: 'Gateway', value: detail.networkInfo.gateway },
        { label: 'DNS', value: detail.networkInfo.dns },
      ]
    : []

  const handleSaveEdit = (e: React.FormEvent) => {
    e.preventDefault()
    if (!deviceId || !editForm) return
    setEditError(null)
    updateMutation.mutate({
      id: deviceId,
      tipo: editForm.tipo as DeviceTypeValue,
      nombre: editForm.nombre.trim(),
      descripcion: editForm.descripcion.trim() || null,
      ubicacionId: editForm.ubicacionId || null,
      estado: editForm.estado as DeviceStatusValue,
      ip: editForm.ip.trim() || null,
      mac: editForm.mac.trim() || null,
      sistemaOperativo: editForm.sistemaOperativo.trim() || null,
      versionSO: editForm.versionSO.trim() || null,
      fabricante: editForm.fabricante.trim() || null,
      modelo: editForm.modelo.trim() || null,
      serial: editForm.serial.trim() || null,
    })
  }

  if (!open) return null

  return (
    <div
      className="fixed inset-0 z-50 flex items-center justify-center p-4"
      role="dialog"
      aria-modal="true"
      aria-labelledby="device-detail-title"
    >
      <div
        className="absolute inset-0 bg-black/60 backdrop-blur-sm"
        onClick={onClose}
      />
      <div
        className={cn(
          'relative w-full max-w-2xl max-h-[90vh] overflow-hidden rounded-xl border border-white/10 bg-dark-400 shadow-xl',
          'flex flex-col'
        )}
      >
        <div className="flex items-center justify-between border-b border-white/10 px-4 py-3 shrink-0">
          <div className="flex items-center gap-3 min-w-0">
            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-dark-300 border border-white/10 text-gray-400">
              {detail ? DEVICE_TYPE_ICONS[detail.tipo] ?? DEVICE_TYPE_ICONS.OTRO : DEVICE_TYPE_ICONS.OTRO}
            </div>
            <h2
              id="device-detail-title"
              className="text-lg font-semibold text-white truncate"
            >
              {detail?.nombre ?? deviceName}
            </h2>
          </div>
          <div className="flex items-center gap-1 shrink-0">
            {detail && !isEditing && (
              <button
                type="button"
                onClick={() => setIsEditing(true)}
                className="rounded-lg p-2 text-gray-400 hover:bg-white/10 hover:text-primary-400 transition-colors"
                aria-label="Editar dispositivo"
              >
                <Pencil className="w-5 h-5" />
              </button>
            )}
            <button
              type="button"
              onClick={onClose}
              className="rounded-lg p-2 text-gray-400 hover:bg-white/10 hover:text-white transition-colors"
              aria-label="Cerrar"
            >
              <X className="w-5 h-5" />
            </button>
          </div>
        </div>

        <div className="flex-1 overflow-y-auto p-4 space-y-6">
          {isLoading && !editForm && (
            <div className="py-12 text-center text-sm text-gray-500">
              Cargando información del dispositivo...
            </div>
          )}
          {hasError && (
            <div className="rounded-lg bg-red-500/20 border border-red-500/40 px-4 py-3 text-sm text-red-400">
              No se pudo cargar el dispositivo. Intente de nuevo.
            </div>
          )}

          {isEditing && editForm && device && (
            <form onSubmit={handleSaveEdit} className="space-y-4">
              {editError && (
                <div className="rounded-lg bg-red-500/20 border border-red-500/40 px-4 py-2 text-sm text-red-400">
                  {editError}
                </div>
              )}
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Tipo</label>
                <select
                  value={editForm.tipo}
                  onChange={(e) => setEditForm((f) => f && { ...f, tipo: e.target.value })}
                  className={INPUT_CLASS}
                >
                  {DEVICE_TYPE_OPTIONS.map((o) => (
                    <option key={o.value} value={o.value}>{o.label}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Nombre *</label>
                <input
                  type="text"
                  value={editForm.nombre}
                  onChange={(e) => setEditForm((f) => f && { ...f, nombre: e.target.value })}
                  className={INPUT_CLASS}
                  required
                />
              </div>
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Descripción</label>
                <textarea
                  value={editForm.descripcion}
                  onChange={(e) => setEditForm((f) => f && { ...f, descripcion: e.target.value })}
                  className={cn(INPUT_CLASS, 'min-h-[80px] resize-y')}
                  rows={2}
                />
              </div>
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Ubicación</label>
                <select
                  value={editForm.ubicacionId}
                  onChange={(e) => setEditForm((f) => f && { ...f, ubicacionId: e.target.value })}
                  className={INPUT_CLASS}
                >
                  <option value="">Sin ubicación</option>
                  {(locationsQuery.data ?? []).map((loc) => (
                    <option key={loc.id} value={loc.id}>{loc.nombre}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Estado</label>
                <select
                  value={editForm.estado}
                  onChange={(e) => setEditForm((f) => f && { ...f, estado: e.target.value })}
                  className={INPUT_CLASS}
                >
                  {DEVICE_STATUS_OPTIONS.map((o) => (
                    <option key={o.value} value={o.value}>{o.label}</option>
                  ))}
                </select>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">IP</label>
                  <input
                    type="text"
                    value={editForm.ip}
                    onChange={(e) => setEditForm((f) => f && { ...f, ip: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">MAC</label>
                  <input
                    type="text"
                    value={editForm.mac}
                    onChange={(e) => setEditForm((f) => f && { ...f, mac: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">Sistema operativo</label>
                  <input
                    type="text"
                    value={editForm.sistemaOperativo}
                    onChange={(e) => setEditForm((f) => f && { ...f, sistemaOperativo: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">Versión SO</label>
                  <input
                    type="text"
                    value={editForm.versionSO}
                    onChange={(e) => setEditForm((f) => f && { ...f, versionSO: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">Fabricante</label>
                  <input
                    type="text"
                    value={editForm.fabricante}
                    onChange={(e) => setEditForm((f) => f && { ...f, fabricante: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
                <div>
                  <label className="mb-1.5 block text-xs font-medium text-gray-400">Modelo</label>
                  <input
                    type="text"
                    value={editForm.modelo}
                    onChange={(e) => setEditForm((f) => f && { ...f, modelo: e.target.value })}
                    className={INPUT_CLASS}
                  />
                </div>
              </div>
              <div>
                <label className="mb-1.5 block text-xs font-medium text-gray-400">Número de serie</label>
                <input
                  type="text"
                  value={editForm.serial}
                  onChange={(e) => setEditForm((f) => f && { ...f, serial: e.target.value })}
                  className={INPUT_CLASS}
                />
              </div>
              <div className="flex justify-end gap-2 pt-2 border-t border-white/10">
                <button
                  type="button"
                  onClick={() => setIsEditing(false)}
                  className="btn btn-secondary"
                >
                  Cancelar
                </button>
                <button
                  type="submit"
                  disabled={updateMutation.isPending}
                  className="btn btn-primary disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  {updateMutation.isPending ? 'Guardando...' : 'Guardar'}
                </button>
              </div>
            </form>
          )}

          {detail && !isLoading && !isEditing && (
            <>
              <InfoSection title="Información del sistema" items={systemItems} />
              <InfoSection title="Información de red" items={networkItems} />
              <SoftwareList items={detail.software} />
            </>
          )}
        </div>

        {detail && !isEditing && (
          <ActionBar
            deviceId={detail.id}
            onConnect={onConnect}
            onTerminal={onTerminal}
            onFiles={onFiles}
            loading={isLoading}
          />
        )}
      </div>
    </div>
  )
}
