import { useEffect, useState } from 'react'
import { api } from '../api/client'
import { Spinner } from '../components/Spinner'
import { Layout } from '../components/Layout'
import { Modal } from '../components/Modal'

interface KioskDevice {
  id: string
  company_id: string
  name: string
  location: string | null
  status: 'pending' | 'approved' | 'revoked'
  public_key: string | null
  key_algorithm: string
  last_heartbeat_at: string | null
  client_version: string | null
  offline_queue_size: number
  ip_whitelist: string | null
  heartbeat_status: 'online' | 'stale' | 'offline'
  created_at: string
}

interface Me {
  first_name: string
  last_name: string
  role: string
}

const inputClass = 'w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 focus:border-transparent'

function HeartbeatDot({ device }: { device: KioskDevice }) {
  if (device.status === 'revoked') {
    return (
      <span className='flex items-center text-xs text-gray-500 font-medium'>
        <span className='w-2 h-2 rounded-full inline-block mr-1.5 bg-gray-400' />
        Gesperrt
      </span>
    )
  }
  if (device.heartbeat_status === 'online') {
    return (
      <span className='flex items-center text-xs text-green-700 font-medium'>
        <span className='w-2 h-2 rounded-full inline-block mr-1.5 bg-green-500' />
        Online
      </span>
    )
  }
  if (device.heartbeat_status === 'stale') {
    return (
      <span className='flex items-center text-xs text-yellow-700 font-medium'>
        <span className='w-2 h-2 rounded-full inline-block mr-1.5 bg-yellow-400' />
        Veraltet
      </span>
    )
  }
  return (
    <span className='flex items-center text-xs text-red-600 font-medium'>
      <span className='w-2 h-2 rounded-full inline-block mr-1.5 bg-red-500' />
      Offline
    </span>
  )
}

function truncateKey(key: string | null): string {
  if (!key) return '—'
  const trimmed = key.trim()
  return trimmed.length > 40 ? trimmed.slice(0, 40) + '...' : trimmed
}

export function KioskDevicesPage() {
  const [me, setMe]           = useState<Me | null>(null)
  const [devices, setDevices] = useState<KioskDevice[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError]     = useState<string | null>(null)
  const [activeTab, setActiveTab] = useState<'pending' | 'active'>('pending')

  // Create modal
  const [showCreate, setShowCreate]       = useState(false)
  const [createName, setCreateName]       = useState('')
  const [createLocation, setCreateLocation] = useState('')
  const [createPublicKey, setCreatePublicKey] = useState('')
  const [createIpWhitelist, setCreateIpWhitelist] = useState('')
  const [createLoading, setCreateLoading] = useState(false)
  const [createError, setCreateError]     = useState<string | null>(null)

  // Edit modal
  const [editDevice, setEditDevice]       = useState<KioskDevice | null>(null)
  const [editName, setEditName]           = useState('')
  const [editLocation, setEditLocation]   = useState('')
  const [editIpWhitelist, setEditIpWhitelist] = useState('')
  const [editLoading, setEditLoading]     = useState(false)
  const [editError, setEditError]         = useState<string | null>(null)

  async function load() {
    try {
      const [meData, devicesData] = await Promise.all([
        api.get<Me>('/auth/me'),
        api.get<KioskDevice[]>('/kiosk/devices'),
      ])
      setMe(meData)
      setDevices(devicesData)
    } catch (e: unknown) {
      setError(e instanceof Error ? e.message : 'Fehler beim Laden')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
    const interval = setInterval(load, 30000)
    return () => clearInterval(interval)
  }, [])

  async function handleCreate() {
    setCreateError(null)
    if (!createName.trim()) { setCreateError('Name ist erforderlich.'); return }
    if (!createPublicKey.trim()) { setCreateError('Public Key ist erforderlich.'); return }
    setCreateLoading(true)
    try {
      await api.post<KioskDevice>('/kiosk/devices', {
        name: createName.trim(),
        location: createLocation.trim() || null,
        public_key: createPublicKey.trim(),
        ip_whitelist: createIpWhitelist.trim() || null,
      })
      setShowCreate(false)
      setCreateName('')
      setCreateLocation('')
      setCreatePublicKey('')
      setCreateIpWhitelist('')
      setActiveTab('pending')
      load()
    } catch (e: unknown) {
      setCreateError(e instanceof Error ? e.message : 'Fehler beim Erstellen')
    } finally {
      setCreateLoading(false)
    }
  }

  async function handleApprove(device: KioskDevice) {
    try {
      await api.post(`/kiosk/devices/${device.id}/approve`, {})
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Freigeben')
    }
  }

  async function handleRevoke(device: KioskDevice) {
    if (!confirm(`Gerät „${device.name}" wirklich sperren?`)) return
    try {
      await api.post(`/kiosk/devices/${device.id}/revoke`, {})
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Sperren')
    }
  }

  async function handleDelete(device: KioskDevice) {
    if (!confirm(`Gerät „${device.name}" wirklich löschen?`)) return
    try {
      await api.del(`/kiosk/devices/${device.id}`)
      load()
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Fehler beim Löschen')
    }
  }

  async function handleEdit() {
    if (!editDevice) return
    setEditError(null)
    if (!editName.trim()) { setEditError('Name ist erforderlich.'); return }
    setEditLoading(true)
    try {
      await api.patch(`/kiosk/devices/${editDevice.id}`, {
        name: editName.trim(),
        location: editLocation.trim() || null,
        ip_whitelist: editIpWhitelist.trim() || null,
      })
      setEditDevice(null)
      load()
    } catch (e: unknown) {
      setEditError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setEditLoading(false)
    }
  }

  function openEdit(device: KioskDevice) {
    setEditDevice(device)
    setEditName(device.name)
    setEditLocation(device.location ?? '')
    setEditIpWhitelist(device.ip_whitelist ?? '')
    setEditError(null)
  }

  function formatDate(iso: string | null) {
    if (!iso) return '—'
    return new Date(iso).toLocaleString('de-DE', { dateStyle: 'short', timeStyle: 'short' })
  }

  function openCreate() {
    setCreateName('')
    setCreateLocation('')
    setCreatePublicKey('')
    setCreateIpWhitelist('')
    setCreateError(null)
    setShowCreate(true)
  }

  if (loading) return <div className='min-h-screen bg-gray-50 flex items-center justify-center'><Spinner /></div>
  if (error)   return <div className='min-h-screen bg-gray-50 flex items-center justify-center'><p className='text-red-600'>{error}</p></div>

  const pendingDevices  = devices.filter(d => d.status === 'pending')
  const activeDevices   = devices.filter(d => d.status === 'approved' || d.status === 'revoked')

  return (
    <Layout userRole={me?.role ?? ''} userName={`${me?.first_name} ${me?.last_name}`}>
      <div className='space-y-6'>

        {/* Header */}
        <div className='flex items-center justify-between'>
          <div>
            <h1 className='text-xl font-bold text-gray-800'>Kiosk-Geräte</h1>
            <p className='text-sm text-gray-500 mt-0.5'>{devices.length} {devices.length === 1 ? 'Gerät' : 'Geräte'} registriert</p>
          </div>
          <button
            onClick={openCreate}
            className='px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-700 transition-colors'
          >
            + Gerät hinzufügen
          </button>
        </div>

        {/* Info-Banner */}
        <div className='bg-blue-50 border border-blue-200 rounded-xl px-4 py-3 text-sm text-blue-800'>
          <span className='mr-1'>🔐</span>
          Kiosk-Geräte authentifizieren sich per Ed25519-Signatur.
          Jedes Gerät benötigt ein eigenes Ed25519-Schlüsselpaar.
          Der Public Key wird bei der Registrierung hinterlegt.
        </div>

        {/* Tabs */}
        <div className='border-b border-gray-200'>
          <nav className='flex gap-6' aria-label='Tabs'>
            <button
              onClick={() => setActiveTab('pending')}
              className={`pb-3 text-sm font-medium transition-colors ${
                activeTab === 'pending'
                  ? 'border-b-2 border-blue-600 text-blue-600'
                  : 'text-gray-500 hover:text-gray-700'
              }`}
            >
              Wartet auf Freigabe
              {pendingDevices.length > 0 && (
                <span className='ml-2 inline-flex items-center justify-center w-5 h-5 rounded-full bg-orange-100 text-orange-700 text-xs font-bold'>
                  {pendingDevices.length}
                </span>
              )}
            </button>
            <button
              onClick={() => setActiveTab('active')}
              className={`pb-3 text-sm font-medium transition-colors ${
                activeTab === 'active'
                  ? 'border-b-2 border-blue-600 text-blue-600'
                  : 'text-gray-500 hover:text-gray-700'
              }`}
            >
              Aktive Geräte
            </button>
          </nav>
        </div>

        {/* Tab: Wartet auf Freigabe */}
        {activeTab === 'pending' && (
          <div className='bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden'>
            <div className='overflow-x-auto'>
              <table className='w-full text-sm'>
                <thead className='bg-gray-50 text-gray-500 text-xs uppercase'>
                  <tr>
                    {['Name', 'Standort', 'Public Key', 'Angelegt', ''].map(h => (
                      <th key={h} className='px-4 py-3 text-left font-medium'>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody className='divide-y divide-gray-100'>
                  {pendingDevices.map(d => (
                    <tr key={d.id} className='hover:bg-gray-50 transition-colors'>
                      <td className='px-4 py-3 font-medium text-gray-800'>{d.name}</td>
                      <td className='px-4 py-3 text-gray-500'>{d.location ?? '—'}</td>
                      <td className='px-4 py-3 text-gray-400 font-mono text-xs'>{truncateKey(d.public_key)}</td>
                      <td className='px-4 py-3 text-gray-500'>{formatDate(d.created_at)}</td>
                      <td className='px-4 py-3'>
                        <div className='flex gap-3 justify-end'>
                          <button
                            onClick={() => handleApprove(d)}
                            className='text-xs text-green-700 font-medium hover:underline'
                          >
                            ✓ Freigeben
                          </button>
                          <button
                            onClick={() => handleDelete(d)}
                            className='text-xs text-red-500 hover:underline'
                          >
                            ✗ Ablehnen
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {pendingDevices.length === 0 && (
                    <tr>
                      <td colSpan={5} className='px-4 py-12 text-center text-gray-400'>
                        Keine Geräte warten auf Freigabe.
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>
        )}

        {/* Tab: Aktive Geräte */}
        {activeTab === 'active' && (
          <div className='bg-white rounded-xl border border-gray-100 shadow-sm overflow-hidden'>
            <div className='overflow-x-auto'>
              <table className='w-full text-sm'>
                <thead className='bg-gray-50 text-gray-500 text-xs uppercase'>
                  <tr>
                    {['Name', 'Standort', 'Status', 'Letzter Heartbeat', 'Client-Version', 'Offline-Queue', ''].map(h => (
                      <th key={h} className='px-4 py-3 text-left font-medium'>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody className='divide-y divide-gray-100'>
                  {activeDevices.map(d => (
                    <tr key={d.id} className='hover:bg-gray-50 transition-colors'>
                      <td className='px-4 py-3 font-medium text-gray-800'>{d.name}</td>
                      <td className='px-4 py-3 text-gray-500'>{d.location ?? '—'}</td>
                      <td className='px-4 py-3'>
                        <HeartbeatDot device={d} />
                      </td>
                      <td className='px-4 py-3 text-gray-500'>{formatDate(d.last_heartbeat_at)}</td>
                      <td className='px-4 py-3 text-gray-500'>{d.client_version ?? '—'}</td>
                      <td className='px-4 py-3 text-gray-500'>
                        {d.offline_queue_size > 0
                          ? <span className='text-orange-600 font-medium'>{d.offline_queue_size}</span>
                          : '0'
                        }
                      </td>
                      <td className='px-4 py-3'>
                        <div className='flex gap-3 justify-end'>
                          <button onClick={() => openEdit(d)} className='text-xs text-blue-600 hover:underline'>Bearbeiten</button>
                          {d.status === 'approved' && (
                            <button onClick={() => handleRevoke(d)} className='text-xs text-yellow-600 hover:underline'>Sperren</button>
                          )}
                          <button onClick={() => handleDelete(d)} className='text-xs text-red-500 hover:underline'>Löschen</button>
                        </div>
                      </td>
                    </tr>
                  ))}
                  {activeDevices.length === 0 && (
                    <tr>
                      <td colSpan={7} className='px-4 py-12 text-center text-gray-400'>
                        Noch keine aktiven Geräte vorhanden.
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </div>

      {/* Gerät erstellen Modal */}
      {showCreate && (
        <Modal title='Neues Kiosk-Gerät' onClose={() => setShowCreate(false)}>
          <div className='space-y-3'>
            <div className='bg-blue-50 border border-blue-200 rounded-lg px-3 py-2 text-xs text-blue-800'>
              Das Gerät erscheint nach dem Anlegen im Tab „Wartet auf Freigabe". Ein Admin muss es freigeben.
            </div>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Name *</span>
              <input
                value={createName}
                onChange={e => setCreateName(e.target.value)}
                className={inputClass}
                placeholder='z.B. Eingang Büro'
                autoFocus
              />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Standort</span>
              <input
                value={createLocation}
                onChange={e => setCreateLocation(e.target.value)}
                className={inputClass}
                placeholder='z.B. Erdgeschoss, Halle A'
              />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Public Key *</span>
              <textarea
                value={createPublicKey}
                onChange={e => setCreatePublicKey(e.target.value)}
                rows={4}
                className={inputClass + ' resize-none font-mono text-xs'}
                placeholder='ssh-ed25519 AAAA...'
              />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>IP-Whitelist (optional)</span>
              <input
                value={createIpWhitelist}
                onChange={e => setCreateIpWhitelist(e.target.value)}
                className={inputClass}
                placeholder='10.0.0.0/24,192.168.1.0/24'
              />
            </label>
            {createError && <p className='text-sm text-red-600 bg-red-50 border border-red-200 rounded px-3 py-2'>{createError}</p>}
            <div className='flex justify-end gap-2 pt-2'>
              <button onClick={() => setShowCreate(false)} className='px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50'>Abbrechen</button>
              <button onClick={handleCreate} disabled={createLoading} className='px-4 py-2 text-sm font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50'>
                {createLoading ? 'Erstelle…' : 'Erstellen'}
              </button>
            </div>
          </div>
        </Modal>
      )}

      {/* Bearbeiten Modal */}
      {editDevice && (
        <Modal title={`Gerät bearbeiten – ${editDevice.name}`} onClose={() => setEditDevice(null)}>
          <div className='space-y-3'>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Name *</span>
              <input
                value={editName}
                onChange={e => setEditName(e.target.value)}
                className={inputClass}
                autoFocus
              />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>Standort</span>
              <input
                value={editLocation}
                onChange={e => setEditLocation(e.target.value)}
                className={inputClass}
                placeholder='z.B. Erdgeschoss, Halle A'
              />
            </label>
            <label className='block'>
              <span className='text-xs font-medium text-gray-700'>IP-Whitelist (optional)</span>
              <input
                value={editIpWhitelist}
                onChange={e => setEditIpWhitelist(e.target.value)}
                className={inputClass}
                placeholder='10.0.0.0/24,192.168.1.0/24'
              />
            </label>
            {editError && <p className='text-sm text-red-600 bg-red-50 border border-red-200 rounded px-3 py-2'>{editError}</p>}
            <div className='flex justify-end gap-2 pt-2'>
              <button onClick={() => setEditDevice(null)} className='px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50'>Abbrechen</button>
              <button onClick={handleEdit} disabled={editLoading} className='px-4 py-2 text-sm font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50'>
                {editLoading ? 'Speichere…' : 'Speichern'}
              </button>
            </div>
          </div>
        </Modal>
      )}
    </Layout>
  )
}
