'use client';

import { useState, useEffect, useCallback } from 'react';
import { Radio, Plus, RefreshCw, Pencil, Trash2, X, Shield } from 'lucide-react';
import { cn } from '@/lib/utils';

interface NotificationChannel {
  channelKey: string;
  name: string;
  description: string | null;
  isMandatory: boolean;
  isEnabled: boolean;
  createdAt: string;
  updatedAt: string;
}

function getAuthHeaders(): HeadersInit {
  const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
  return { Authorization: `Bearer ${token ?? ''}`, 'Content-Type': 'application/json' };
}

async function listChannels(): Promise<NotificationChannel[]> {
  const res = await fetch('/api/proxy/api/v1/notifications/channels', { headers: getAuthHeaders() });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function createChannel(dto: { channelKey: string; name: string; description?: string; isMandatory?: boolean }) {
  const res = await fetch('/api/proxy/api/v1/notifications/channels', {
    method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(dto),
  });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function updateChannel(key: string, dto: { name?: string; description?: string; isMandatory?: boolean; isEnabled?: boolean }) {
  const res = await fetch(`/api/proxy/api/v1/notifications/channels/${key}`, {
    method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(dto),
  });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function deleteChannel(key: string) {
  const res = await fetch(`/api/proxy/api/v1/notifications/channels/${key}`, {
    method: 'DELETE', headers: getAuthHeaders(),
  });
  if (!res.ok) throw new Error(`${res.status}`);
}

/* ---------- Modal ---------- */

function ChannelModal({
  initial,
  onSave,
  onClose,
}: {
  initial?: NotificationChannel;
  onSave: (data: any, key?: string) => Promise<void>;
  onClose: () => void;
}) {
  const [channelKey, setChannelKey] = useState(initial?.channelKey ?? '');
  const [name, setName] = useState(initial?.name ?? '');
  const [description, setDescription] = useState(initial?.description ?? '');
  const [isMandatory, setIsMandatory] = useState(initial?.isMandatory ?? false);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  const handleSubmit = async () => {
    if (!name.trim()) { setError('名称不能为空'); return; }
    if (!initial && !channelKey.match(/^[a-z0-9_]+$/)) {
      setError('频道 key 只能包含小写字母、数字和下划线');
      return;
    }
    setSaving(true); setError('');
    try {
      await onSave(
        { channelKey, name: name.trim(), description: description.trim() || undefined, isMandatory },
        initial?.channelKey,
      );
      onClose();
    } catch (e: any) {
      setError(e.message ?? '保存失败');
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
      <div className="bg-card w-full max-w-md rounded-xl shadow-xl border flex flex-col">
        <div className="flex items-center justify-between px-6 py-4 border-b">
          <h2 className="text-base font-semibold">{initial ? '编辑频道' : '新建频道'}</h2>
          <button onClick={onClose} className="text-muted-foreground hover:text-foreground"><X className="h-4 w-4" /></button>
        </div>
        <div className="px-6 py-4 space-y-4">
          {error && <p className="text-sm text-red-500">{error}</p>}
          {!initial && (
            <div>
              <label className="block text-xs font-medium mb-1">频道 Key *</label>
              <input
                className="w-full rounded-md border bg-background px-3 py-2 text-sm font-mono outline-none focus:ring-1 focus:ring-primary"
                value={channelKey}
                onChange={(e) => setChannelKey(e.target.value.toLowerCase())}
                placeholder="如: marketing, billing"
                maxLength={50}
              />
              <p className="text-xs text-muted-foreground mt-1">只能包含小写字母、数字和下划线，创建后不可更改</p>
            </div>
          )}
          <div>
            <label className="block text-xs font-medium mb-1">显示名称 *</label>
            <input
              className="w-full rounded-md border bg-background px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-primary"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="如: 营销推广"
              maxLength={100}
            />
          </div>
          <div>
            <label className="block text-xs font-medium mb-1">描述（可选）</label>
            <textarea
              className="w-full rounded-md border bg-background px-3 py-2 text-sm outline-none focus:ring-1 focus:ring-primary resize-none"
              rows={2}
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="该频道的用途说明"
            />
          </div>
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="checkbox"
              checked={isMandatory}
              onChange={(e) => setIsMandatory(e.target.checked)}
              className="rounded"
            />
            <span className="text-sm font-medium">强制频道（用户无法关闭）</span>
          </label>
          <p className="text-xs text-muted-foreground -mt-2">适用于安全告警、重要系统通知等必要信息。</p>
        </div>
        <div className="flex justify-end gap-2 px-6 py-4 border-t">
          <button onClick={onClose} className="px-4 py-2 text-sm rounded-md border hover:bg-accent transition-colors">取消</button>
          <button
            onClick={handleSubmit}
            disabled={saving}
            className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50"
          >
            {saving ? '保存中…' : '保存'}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ---------- Main page ---------- */

export default function NotificationChannelsPage() {
  const [channels, setChannels] = useState<NotificationChannel[]>([]);
  const [loading, setLoading] = useState(false);
  const [modal, setModal] = useState<{ mode: 'create' } | { mode: 'edit'; ch: NotificationChannel } | null>(null);
  const [deleting, setDeleting] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try { setChannels(await listChannels()); }
    catch (e) { console.error(e); }
    finally { setLoading(false); }
  }, []);

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

  const handleSave = async (data: any, key?: string) => {
    if (key) {
      await updateChannel(key, data);
    } else {
      await createChannel(data);
    }
    await load();
  };

  const handleDelete = async (ch: NotificationChannel) => {
    if (ch.isMandatory) { alert('强制频道不可删除'); return; }
    if (!confirm(`确认删除频道「${ch.name}」？`)) return;
    setDeleting(ch.channelKey);
    try { await deleteChannel(ch.channelKey); await load(); }
    finally { setDeleting(null); }
  };

  const handleToggleEnabled = async (ch: NotificationChannel) => {
    await updateChannel(ch.channelKey, { isEnabled: !ch.isEnabled });
    await load();
  };

  return (
    <div className="flex-1 flex flex-col min-h-0 p-6">
      <div className="flex items-center justify-between mb-6">
        <div className="flex items-center gap-2">
          <Radio className="h-5 w-5 text-primary" />
          <h1 className="text-xl font-semibold">通知频道管理</h1>
          <span className="text-xs text-muted-foreground ml-1">（用户可按频道订阅/取消通知）</span>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={load} disabled={loading}
            className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-md border hover:bg-accent transition-colors"
          >
            <RefreshCw className={cn('h-3.5 w-3.5', loading && 'animate-spin')} />刷新
          </button>
          <button
            onClick={() => setModal({ mode: 'create' })}
            className="flex items-center gap-1.5 px-3 py-1.5 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors"
          >
            <Plus className="h-3.5 w-3.5" />新建频道
          </button>
        </div>
      </div>

      <div className="flex-1 min-h-0 overflow-auto rounded-lg border bg-card">
        <table className="w-full text-sm">
          <thead className="bg-muted/50 sticky top-0">
            <tr>
              <th className="text-left px-4 py-3 font-medium text-muted-foreground">Key</th>
              <th className="text-left px-4 py-3 font-medium text-muted-foreground">名称</th>
              <th className="text-left px-4 py-3 font-medium text-muted-foreground">描述</th>
              <th className="text-left px-4 py-3 font-medium text-muted-foreground">类型</th>
              <th className="text-left px-4 py-3 font-medium text-muted-foreground">状态</th>
              <th className="text-right px-4 py-3 font-medium text-muted-foreground">操作</th>
            </tr>
          </thead>
          <tbody className="divide-y">
            {loading && channels.length === 0 && (
              <tr><td colSpan={6} className="text-center py-12 text-muted-foreground">加载中…</td></tr>
            )}
            {!loading && channels.length === 0 && (
              <tr><td colSpan={6} className="text-center py-12 text-muted-foreground">暂无频道</td></tr>
            )}
            {channels.map((ch) => (
              <tr key={ch.channelKey} className="hover:bg-muted/30 transition-colors">
                <td className="px-4 py-3 font-mono text-xs text-muted-foreground">{ch.channelKey}</td>
                <td className="px-4 py-3 font-medium">{ch.name}</td>
                <td className="px-4 py-3 text-xs text-muted-foreground max-w-xs truncate">{ch.description ?? '—'}</td>
                <td className="px-4 py-3">
                  {ch.isMandatory ? (
                    <span className="flex items-center gap-1 text-xs text-amber-700 bg-amber-50 px-2 py-0.5 rounded font-medium w-fit">
                      <Shield className="h-3 w-3" />强制
                    </span>
                  ) : (
                    <span className="text-xs text-muted-foreground bg-muted px-2 py-0.5 rounded">可选</span>
                  )}
                </td>
                <td className="px-4 py-3">
                  <button
                    onClick={() => handleToggleEnabled(ch)}
                    className={cn(
                      'px-2 py-0.5 rounded text-xs font-medium cursor-pointer transition-colors',
                      ch.isEnabled ? 'bg-green-100 text-green-700 hover:bg-green-200' : 'bg-gray-100 text-gray-500 hover:bg-gray-200',
                    )}
                  >
                    {ch.isEnabled ? '已启用' : '已禁用'}
                  </button>
                </td>
                <td className="px-4 py-3">
                  <div className="flex items-center justify-end gap-1">
                    <button
                      onClick={() => setModal({ mode: 'edit', ch })}
                      className="p-1.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors"
                    >
                      <Pencil className="h-4 w-4" />
                    </button>
                    <button
                      onClick={() => handleDelete(ch)}
                      disabled={!!deleting || ch.isMandatory}
                      className="p-1.5 rounded hover:bg-red-50 text-muted-foreground hover:text-red-600 transition-colors disabled:opacity-30"
                      title={ch.isMandatory ? '强制频道不可删除' : '删除'}
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {modal && (
        <ChannelModal
          initial={modal.mode === 'edit' ? modal.ch : undefined}
          onSave={handleSave}
          onClose={() => setModal(null)}
        />
      )}
    </div>
  );
}
