import { useEffect, useState } from 'react'
import { apiRequest, nodeAddProcess } from '../api/client'
import { Play, Square, RotateCw, Trash2, Loader2, Plus } from 'lucide-react'

interface Pm2Process {
  id: number
  name: string
  status: string
  pid: number | null
  uptime: number
  restarts: number
  memory: number
  cpu: number
}

function formatUptime(ms: number): string {
  if (!ms || ms < 0) return '-'
  const s = Math.floor(ms / 1000)
  if (s < 60) return `${s}s`
  const m = Math.floor(s / 60)
  if (m < 60) return `${m}m`
  const h = Math.floor(m / 60)
  return `${h}h`
}

function formatMemory(bytes: number): string {
  if (!bytes) return '-'
  return (bytes / 1024 / 1024).toFixed(1) + ' MB'
}

export function NodePage() {
  const [processes, setProcesses] = useState<Pm2Process[]>([])
  const [nodeVersion, setNodeVersion] = useState<string | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [actionId, setActionId] = useState<number | null>(null)
  const [showAdd, setShowAdd] = useState(false)
  const [addScript, setAddScript] = useState('')
  const [addName, setAddName] = useState('')
  const [adding, setAdding] = useState(false)

  const load = () => {
    setLoading(true)
    Promise.all([
      apiRequest<{ processes: Pm2Process[]; error?: string }>('/node/processes'),
      apiRequest<{ version: string | null; error?: string }>('/node/version'),
    ])
      .then(([procData, verData]) => {
        setProcesses(procData.processes || [])
        setNodeVersion(verData.version || null)
        setError(procData.error || verData.error || '')
      })
      .catch((err) => setError(err.message))
      .finally(() => setLoading(false))
  }

  useEffect(() => {
    load()
  }, [])

  const handleStart = (id: number) => {
    setActionId(id)
    apiRequest<{ status: boolean }>(`/node/${id}/start`, { method: 'POST' })
      .then(load)
      .catch((err) => setError(err.message))
      .finally(() => setActionId(null))
  }

  const handleStop = (id: number) => {
    setActionId(id)
    apiRequest<{ status: boolean }>(`/node/${id}/stop`, { method: 'POST' })
      .then(load)
      .catch((err) => setError(err.message))
      .finally(() => setActionId(null))
  }

  const handleRestart = (id: number) => {
    setActionId(id)
    apiRequest<{ status: boolean }>(`/node/${id}/restart`, { method: 'POST' })
      .then(load)
      .catch((err) => setError(err.message))
      .finally(() => setActionId(null))
  }

  const handleAdd = (e: React.FormEvent) => {
    e.preventDefault()
    if (!addScript.trim()) return
    setAdding(true)
    nodeAddProcess(addScript.trim(), addName.trim() || undefined)
      .then(() => {
        setShowAdd(false)
        setAddScript('')
        setAddName('')
        load()
      })
      .catch((err) => setError(err.message))
      .finally(() => setAdding(false))
  }

  const handleDelete = (id: number, name: string) => {
    if (!confirm(`Delete PM2 process "${name}"?`)) return
    setActionId(id)
    apiRequest<{ status: boolean }>(`/node/${id}`, { method: 'DELETE' })
      .then(load)
      .catch((err) => setError(err.message))
      .finally(() => setActionId(null))
  }

  const isOnline = (status: string) =>
    status?.toLowerCase() === 'online' || status?.toLowerCase() === 'launching'

  if (loading) return <div className="text-gray-500">Loading...</div>

  return (
    <div>
      <div className="flex justify-between items-center mb-4">
        <h1 className="text-2xl font-bold text-gray-800 dark:text-white">Node.js</h1>
        <div className="flex items-center gap-2">
          {nodeVersion && (
            <span className="text-sm text-gray-600 dark:text-gray-400">
              Node: {nodeVersion}
            </span>
          )}
          <button
            onClick={() => setShowAdd(true)}
            className="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg"
          >
            <Plus className="w-4 h-4" />
            Add Process
          </button>
          <button
            onClick={load}
            className="flex items-center gap-2 px-4 py-2 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 rounded-lg"
          >
            <RotateCw className="w-4 h-4" />
            Refresh
          </button>
        </div>
      </div>

      {showAdd && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl p-6 w-full max-w-md">
            <h2 className="text-xl font-bold mb-4 text-gray-800 dark:text-white">Add PM2 Process</h2>
            <form onSubmit={handleAdd} className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Script path</label>
                <input
                  value={addScript}
                  onChange={(e) => setAddScript(e.target.value)}
                  placeholder="/www/wwwroot/app.js"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                  required
                />
              </div>
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Name (optional)</label>
                <input
                  value={addName}
                  onChange={(e) => setAddName(e.target.value)}
                  placeholder="myapp"
                  className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700"
                />
              </div>
              <div className="flex gap-2 justify-end">
                <button type="button" onClick={() => setShowAdd(false)} className="px-4 py-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
                  Cancel
                </button>
                <button type="submit" disabled={adding} className="px-4 py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50">
                  {adding ? 'Starting...' : 'Start'}
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      {error && (
        <div className="mb-4 p-3 rounded-lg bg-amber-50 dark:bg-amber-900/20 text-amber-800 dark:text-amber-200">
          {error}
        </div>
      )}

      <div className="mb-4 p-3 rounded-lg bg-gray-100 dark:bg-gray-700/50 text-sm text-gray-600 dark:text-gray-400">
        PM2 process manager. Install with: <code className="font-mono">npm install -g pm2</code>
      </div>

      <div className="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
          <thead className="bg-gray-50 dark:bg-gray-700">
            <tr>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">
                Name
              </th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">
                Status
              </th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">
                PID
              </th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">
                Uptime
              </th>
              <th className="px-4 py-2 text-left text-sm font-medium text-gray-700 dark:text-gray-300">
                Memory
              </th>
              <th className="px-4 py-2 text-right text-sm font-medium text-gray-700 dark:text-gray-300">
                Actions
              </th>
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 dark:divide-gray-700">
            {processes.length === 0 ? (
              <tr>
                <td colSpan={6} className="px-4 py-8 text-center text-gray-500">
                  No PM2 processes. Click &quot;Add Process&quot; or run <code className="font-mono">pm2 start app.js</code>.
                </td>
              </tr>
            ) : (
              processes.map((p) => (
                <tr key={p.id} className="hover:bg-gray-50 dark:hover:bg-gray-700/30">
                  <td className="px-4 py-2 font-mono text-gray-900 dark:text-white">{p.name}</td>
                  <td className="px-4 py-2">
                    <span
                      className={`text-sm ${
                        isOnline(p.status)
                          ? 'text-green-600 dark:text-green-400'
                          : 'text-gray-500 dark:text-gray-400'
                      }`}
                    >
                      {p.status}
                    </span>
                  </td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">{p.pid || '-'}</td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">
                    {formatUptime(p.uptime)}
                  </td>
                  <td className="px-4 py-2 text-gray-600 dark:text-gray-400">
                    {formatMemory(p.memory)}
                  </td>
                  <td className="px-4 py-2 text-right">
                    <span className="flex gap-1 justify-end">
                      {isOnline(p.status) ? (
                        <>
                          <button
                            onClick={() => handleRestart(p.id)}
                            disabled={actionId === p.id}
                            className="p-2 text-amber-600 hover:bg-amber-50 dark:hover:bg-amber-900/20 rounded disabled:opacity-50"
                            title="Restart"
                          >
                            {actionId === p.id ? (
                              <Loader2 className="w-4 h-4 animate-spin" />
                            ) : (
                              <RotateCw className="w-4 h-4" />
                            )}
                          </button>
                          <button
                            onClick={() => handleStop(p.id)}
                            disabled={actionId === p.id}
                            className="p-2 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded disabled:opacity-50"
                            title="Stop"
                          >
                            <Square className="w-4 h-4" />
                          </button>
                        </>
                      ) : (
                        <button
                          onClick={() => handleStart(p.id)}
                          disabled={actionId === p.id}
                          className="p-2 text-green-600 hover:bg-green-50 dark:hover:bg-green-900/20 rounded disabled:opacity-50"
                          title="Start"
                        >
                          {actionId === p.id ? (
                            <Loader2 className="w-4 h-4 animate-spin" />
                          ) : (
                            <Play className="w-4 h-4" />
                          )}
                        </button>
                      )}
                      <button
                        onClick={() => handleDelete(p.id, p.name)}
                        disabled={actionId === p.id}
                        className="p-2 text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-700 rounded disabled:opacity-50"
                        title="Delete"
                      >
                        <Trash2 className="w-4 h-4" />
                      </button>
                    </span>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
    </div>
  )
}
