'use client'
// src/app/services/page.tsx — 服务管理页面（CRUD + 容器操作）
import { useState, useEffect } from 'react'
import { Plus, RotateCw, Square, ScrollText, X, Save, Trash2, Edit3 } from 'lucide-react'

interface Check { type: string; containerName?: string; url?: string }
interface Service { id: number; name: string; category: string; alert_level: string; checks: Check[]; check_interval: number; enabled: number; current_status: string }

const emptyService = { name: '', category: 'endpoint', alert_level: 'warning', checks: [{ type: 'http', url: '' }] as Check[], check_interval: 30, check_timeout: 10, enabled: 1 }

export default function ServicesPage() {
  const [services, setServices] = useState<Service[]>([])
  const [loading, setLoading] = useState(true)
  const [opLoading, setOpLoading] = useState<number | null>(null)
  const [logs, setLogs] = useState<{ serviceId: number; output: string } | null>(null)
  const [toast, setToast] = useState<{ type: 'ok' | 'err'; msg: string } | null>(null)
  const [editing, setEditing] = useState<Record<string, unknown> | null>(null)
  const [isNew, setIsNew] = useState(false)
  const [saving, setSaving] = useState(false)

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

  async function fetchServices() {
    const res = await fetch('/api/services')
    setServices(await res.json())
    setLoading(false)
  }

  const showToast = (type: 'ok' | 'err', msg: string) => {
    setToast({ type, msg }); setTimeout(() => setToast(null), 3000)
  }

  const hasDocker = (s: Service) => s.checks?.some(c => c.type === 'docker' && c.containerName)

  async function containerAction(s: Service, action: 'restart' | 'stop' | 'start' | 'logs') {
    const confirmMsg = { restart: `确定重启 ${s.name}？`, stop: `确定停止 ${s.name}？`, start: `确定启动 ${s.name}？`, logs: '' }
    if (action !== 'logs' && !confirm(confirmMsg[action])) return
    setOpLoading(s.id)
    try {
      const res = await fetch(`/api/services/${s.id}/ops`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action, lines: 100 }),
      })
      const data = await res.json()
      if (data.success) {
        if (action === 'logs') setLogs({ serviceId: s.id, output: data.output || '(空)' })
        else { showToast('ok', `${s.name} 操作成功`); fetchServices() }
      } else showToast('err', data.error || '操作失败')
    } catch { showToast('err', '网络错误') }
    setOpLoading(null)
  }

  const update = (f: string, v: unknown) => setEditing(prev => prev ? { ...prev, [f]: v } : null)

  const addCheck = () => {
    const checks = (editing?.checks as Check[]) || []
    setEditing(prev => prev ? { ...prev, checks: [...checks, { type: 'http', url: '' }] } : null)
  }
  const updateCheck = (i: number, f: string, v: string) => {
    const checks = [...((editing?.checks as Check[]) || [])]
    if (checks[i]) (checks[i] as unknown as Record<string, string>)[f] = v
    update('checks', checks)
  }
  const removeCheck = (i: number) => {
    const checks = [...((editing?.checks as Check[]) || [])]
    if (checks.length <= 1) return  // 至少保留一条检查方式
    checks.splice(i, 1)
    update('checks', checks)
  }

  async function handleSave() {
    if (!editing?.name) { showToast('err', '请输入服务名称'); return }
    setSaving(true)
    try {
      const url = isNew ? '/api/services' : `/api/services/${editing.id}`
      const method = isNew ? 'POST' : 'PUT'
      const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(editing) })
      if (res.ok) { showToast('ok', isNew ? '服务已添加' : '服务已更新'); setEditing(null); fetchServices() }
      else { const d = await res.json(); showToast('err', d.error || '保存失败') }
    } catch { showToast('err', '网络错误') }
    setSaving(false)
  }

  async function handleDelete(id: number) {
    if (!confirm('确定删除此服务？')) return
    try {
      const res = await fetch(`/api/services/${id}`, { method: 'DELETE' })
      if (res.ok) { showToast('ok', '服务已删除'); fetchServices() }
      else { const d = await res.json(); showToast('err', d.error || '删除失败') }
    } catch { showToast('err', '网络错误') }
  }

  const startNew = () => { setEditing({ ...emptyService }); setIsNew(true) }
  const startEdit = (s: Service) => { setEditing({ ...s }); setIsNew(false) }

  if (loading) return <div className="p-12 text-center text-slate-400">加载中...</div>

  return (
    <div className="space-y-6">
      {toast && (
        <div className={`fixed top-4 right-4 z-50 px-4 py-2 rounded-lg text-sm font-medium shadow-lg ${toast.type === 'ok' ? 'bg-green-600 text-white' : 'bg-red-600 text-white'}`}>
          {toast.msg}
        </div>
      )}

      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-semibold font-[family-name:var(--font-display)]">服务管理</h1>
        <button onClick={startNew} className="flex items-center gap-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-lg px-4 py-2 text-sm font-medium">
          <Plus size={16} /> 添加服务
        </button>
      </div>

      <div className="bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-xl overflow-hidden">
        <table className="w-full text-sm">
          <thead>
            <tr className="bg-slate-50 dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700">
              <th className="text-left px-4 py-3 font-medium text-slate-500">名称</th>
              <th className="text-left px-4 py-3 font-medium text-slate-500">类别</th>
              <th className="text-left px-4 py-3 font-medium text-slate-500">告警级别</th>
              <th className="text-left px-4 py-3 font-medium text-slate-500">检查方式</th>
              <th className="text-left px-4 py-3 font-medium text-slate-500">状态</th>
              <th className="text-center px-4 py-3 font-medium text-slate-500">容器操作</th>
              <th className="text-center px-4 py-3 font-medium text-slate-500">编辑</th>
            </tr>
          </thead>
          <tbody>
            {services.map(s => (
              <tr key={s.id} className="border-b border-slate-100 dark:border-slate-800 hover:bg-slate-50 dark:hover:bg-slate-800/50">
                <td className="px-4 py-3 font-medium">{s.name}</td>
                <td className="px-4 py-3 text-slate-500">{s.category}</td>
                <td className="px-4 py-3">
                  <span className={`px-2 py-0.5 rounded-full text-xs font-medium ${s.alert_level === 'critical' ? 'bg-red-100 text-red-700 dark:bg-red-500/10 dark:text-red-400' : 'bg-green-100 text-green-700 dark:bg-green-500/10 dark:text-green-400'}`}>
                    {s.alert_level}
                  </span>
                </td>
                <td className="px-4 py-3 text-slate-500">{s.checks?.map(c => c.type).join(' + ') || '—'}</td>
                <td className="px-4 py-3">
                  <span className={`inline-flex items-center gap-1.5 ${s.current_status === 'normal' ? 'text-green-600' : s.current_status === 'abnormal' ? 'text-red-600' : 'text-amber-600'}`}>
                    <span className="w-2 h-2 rounded-full bg-current" />
                    {s.current_status === 'normal' ? '正常' : s.current_status === 'abnormal' ? '异常' : '未知'}
                  </span>
                </td>
                <td className="px-4 py-3 text-center">
                  {hasDocker(s) ? (
                    <div className="flex items-center justify-center gap-1">
                      <button onClick={() => containerAction(s, 'restart')} disabled={opLoading === s.id}
                        className="p-1.5 hover:bg-indigo-50 dark:hover:bg-indigo-500/10 rounded text-indigo-500 disabled:opacity-40" title="重启">
                        <RotateCw size={15} className={opLoading === s.id ? 'animate-spin' : ''} />
                      </button>
                      <button onClick={() => containerAction(s, 'stop')} disabled={opLoading === s.id}
                        className="p-1.5 hover:bg-red-50 dark:hover:bg-red-500/10 rounded text-red-500 disabled:opacity-40" title="停止">
                        <Square size={15} />
                      </button>
                      <button onClick={() => containerAction(s, 'logs')} disabled={opLoading === s.id}
                        className="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded text-slate-500 disabled:opacity-40" title="查看日志">
                        <ScrollText size={15} />
                      </button>
                    </div>
                  ) : (
                    <span className="text-xs text-slate-400">—</span>
                  )}
                </td>
                <td className="px-4 py-3 text-center">
                  <button onClick={() => startEdit(s)} className="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded text-slate-400" title="编辑">
                    <Edit3 size={14} />
                  </button>
                  <button onClick={() => handleDelete(s.id)} className="p-1.5 hover:bg-red-50 dark:hover:bg-red-500/10 rounded text-red-400 ml-1" title="删除">
                    <Trash2 size={14} />
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        {services.length === 0 && <p className="p-12 text-center text-slate-400">暂无服务，请添加被监控服务</p>}
      </div>

      {/* 日志查看 Dialog */}
      {logs && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50" onClick={() => setLogs(null)}>
          <div className="bg-white dark:bg-slate-900 rounded-xl p-6 w-full max-w-3xl shadow-xl max-h-[80vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <h2 className="font-semibold">容器日志 — {services.find(s => s.id === logs.serviceId)?.name}</h2>
              <button onClick={() => setLogs(null)} className="text-slate-400 hover:text-slate-600 text-lg">&times;</button>
            </div>
            <pre className="text-xs font-mono text-slate-300 bg-slate-950 rounded-lg p-4 overflow-x-auto whitespace-pre-wrap max-h-96">{logs.output}</pre>
          </div>
        </div>
      )}

      {/* 添加/编辑服务 Dialog */}
      {editing && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
          <div className="bg-white dark:bg-slate-900 rounded-xl p-6 w-full max-w-lg shadow-xl max-h-[90vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between mb-4">
              <h2 className="text-lg font-semibold">{isNew ? '添加服务' : '编辑服务'}</h2>
              <button onClick={() => setEditing(null)} className="p-1 text-slate-400 hover:text-slate-600"><X size={18} /></button>
            </div>
            <div className="space-y-4">
              <div>
                <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">名称 *</label>
                <input value={String(editing.name || '')} onChange={e => update('name', e.target.value)}
                  placeholder="如：Authelia SSO" className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500" />
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">类别</label>
                  <select value={String(editing.category || 'endpoint')} onChange={e => update('category', e.target.value)}
                    className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm">
                    <option value="endpoint">端点</option><option value="container">容器</option><option value="custom">自定义</option>
                  </select>
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">告警级别</label>
                  <select value={String(editing.alert_level || 'warning')} onChange={e => update('alert_level', e.target.value)}
                    className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm">
                    <option value="critical">Critical</option><option value="warning">Warning</option><option value="info">Info</option>
                  </select>
                </div>
              </div>
              <div className="grid grid-cols-2 gap-4">
                <div>
                  <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">检查间隔（秒）</label>
                  <input type="number" value={Number(editing.check_interval) || 30} onChange={e => update('check_interval', Number(e.target.value))}
                    className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm" />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1">超时（秒）</label>
                  <input type="number" value={Number(editing.check_timeout) || 10} onChange={e => update('check_timeout', Number(e.target.value))}
                    className="w-full px-3 py-2 rounded-lg border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-sm" />
                </div>
              </div>
              <div>
                <div className="flex items-center justify-between mb-2">
                  <label className="text-sm font-medium text-slate-700 dark:text-slate-300">检查方式</label>
                  <button onClick={addCheck} className="text-xs text-indigo-600 hover:text-indigo-700">+ 添加检查</button>
                </div>
                {((editing.checks as Check[]) || []).map((c, i) => (
                  <div key={i} className="flex items-center gap-2 mb-2">
                    <select value={c.type} onChange={e => updateCheck(i, 'type', e.target.value)}
                      className="px-2 py-1.5 rounded border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-xs w-20">
                      <option value="http">HTTP</option><option value="docker">Docker</option>
                    </select>
                    {c.type === 'http' ? (
                      <input value={c.url || ''} onChange={e => updateCheck(i, 'url', e.target.value)} placeholder="https://example.com/api/health"
                        className="flex-1 px-2 py-1.5 rounded border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-xs" />
                    ) : (
                      <input value={c.containerName || ''} onChange={e => updateCheck(i, 'containerName', e.target.value)} placeholder="容器名，如 authelia"
                        className="flex-1 px-2 py-1.5 rounded border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-xs" />
                    )}
                    {((editing.checks as Check[]) || []).length > 1 && (
                      <button onClick={() => removeCheck(i)} className="text-red-400 hover:text-red-600 p-1"><X size={14} /></button>
                    )}
                  </div>
                ))}
              </div>
              <div className="flex justify-end gap-3 pt-2">
                <button onClick={() => setEditing(null)} className="px-4 py-2 text-sm border rounded-lg hover:bg-slate-50 dark:hover:bg-slate-800">取消</button>
                <button onClick={handleSave} disabled={saving}
                  className="flex items-center gap-2 px-4 py-2 bg-indigo-600 hover:bg-indigo-700 disabled:bg-indigo-400 text-white rounded-lg text-sm font-medium">
                  <Save size={15} /> {saving ? '保存中...' : '保存'}
                </button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}
