'use client';

import { useState, useEffect, useCallback } from 'react';
import { Megaphone, Plus, RefreshCw, Pencil, Trash2, X, BarChart2, Play, Ban } from 'lucide-react';
import { cn } from '@/lib/utils';

type CampaignStatus = 'DRAFT' | 'SCHEDULED' | 'RUNNING' | 'COMPLETED' | 'CANCELLED' | 'FAILED';
type ScheduleType = 'ONCE' | 'RECURRING';

interface Campaign {
  id: string;
  name: string;
  description: string | null;
  status: CampaignStatus;
  notificationId: string | null;
  scheduleType: ScheduleType;
  scheduledAt: string | null;
  cronExpr: string | null;
  timezone: string;
  nextRunAt: string | null;
  lastRunAt: string | null;
  targetCount: number;
  sentCount: number;
  readCount: number;
  createdBy: string | null;
  createdAt: string;
  updatedAt: string;
}

interface CampaignStats {
  targetCount: number;
  sentCount: number;
  readCount: number;
  readRate: number;
  executions: any[];
}

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

const BASE = '/api/proxy/api/v1/notifications/campaigns';

async function listCampaigns(params: { status?: string; limit?: number; offset?: number }) {
  const q = new URLSearchParams();
  if (params.status) q.set('status', params.status);
  if (params.limit != null) q.set('limit', String(params.limit));
  if (params.offset != null) q.set('offset', String(params.offset));
  const res = await fetch(`${BASE}?${q}`, { headers: getAuthHeaders() });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json() as Promise<{ items: Campaign[]; total: number }>;
}

async function createCampaign(dto: any) {
  const res = await fetch(BASE, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(dto) });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function updateCampaign(id: string, dto: any) {
  const res = await fetch(`${BASE}/${id}`, { method: 'PUT', headers: getAuthHeaders(), body: JSON.stringify(dto) });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function scheduleCampaign(id: string, dto: { scheduledAt?: string; cronExpr?: string; timezone?: string }) {
  const res = await fetch(`${BASE}/${id}/schedule`, { method: 'POST', headers: getAuthHeaders(), body: JSON.stringify(dto) });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function cancelCampaign(id: string) {
  const res = await fetch(`${BASE}/${id}/cancel`, { method: 'POST', headers: getAuthHeaders() });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

async function deleteCampaign(id: string) {
  const res = await fetch(`${BASE}/${id}`, { method: 'DELETE', headers: getAuthHeaders() });
  if (!res.ok) throw new Error(`${res.status}`);
}

async function getCampaignStats(id: string): Promise<CampaignStats> {
  const res = await fetch(`${BASE}/${id}/stats`, { headers: getAuthHeaders() });
  if (!res.ok) throw new Error(`${res.status}`);
  return res.json();
}

/* ---------- Status badge ---------- */

const STATUS_STYLE: Record<CampaignStatus, string> = {
  DRAFT: 'bg-gray-100 text-gray-600',
  SCHEDULED: 'bg-blue-100 text-blue-700',
  RUNNING: 'bg-yellow-100 text-yellow-700',
  COMPLETED: 'bg-green-100 text-green-700',
  CANCELLED: 'bg-gray-100 text-gray-500',
  FAILED: 'bg-red-100 text-red-700',
};
const STATUS_LABEL: Record<CampaignStatus, string> = {
  DRAFT: '草稿', SCHEDULED: '已排期', RUNNING: '执行中',
  COMPLETED: '已完成', CANCELLED: '已取消', FAILED: '失败',
};

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

function StatsModal({ campaignId, name, onClose }: { campaignId: string; name: string; onClose: () => void }) {
  const [stats, setStats] = useState<CampaignStats | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    getCampaignStats(campaignId)
      .then(setStats)
      .catch(console.error)
      .finally(() => setLoading(false));
  }, [campaignId]);

  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-lg 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">{name} — 数据统计</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">
          {loading ? (
            <p className="text-center text-muted-foreground">加载中…</p>
          ) : stats ? (
            <div className="space-y-4">
              <div className="grid grid-cols-3 gap-4">
                {[
                  { label: '目标人数', value: stats.targetCount },
                  { label: '已发送', value: stats.sentCount },
                  { label: '已阅读', value: stats.readCount },
                ].map((item) => (
                  <div key={item.label} className="bg-muted/50 rounded-lg p-3 text-center">
                    <p className="text-2xl font-bold">{item.value.toLocaleString()}</p>
                    <p className="text-xs text-muted-foreground mt-1">{item.label}</p>
                  </div>
                ))}
              </div>
              <div className="bg-muted/50 rounded-lg p-3 text-center">
                <p className="text-2xl font-bold text-primary">{stats.readRate}%</p>
                <p className="text-xs text-muted-foreground mt-1">阅读率</p>
              </div>
              {stats.executions.length > 0 && (
                <div>
                  <p className="text-xs font-medium mb-2 text-muted-foreground">最近执行记录</p>
                  <div className="space-y-1 max-h-40 overflow-y-auto">
                    {stats.executions.map((ex: any, i: number) => (
                      <div key={i} className="flex items-center justify-between text-xs px-2 py-1 bg-muted/30 rounded">
                        <span>{new Date(ex.started_at).toLocaleString('zh-CN', { dateStyle: 'short', timeStyle: 'short' })}</span>
                        <span className={ex.status === 'COMPLETED' ? 'text-green-600' : ex.status === 'FAILED' ? 'text-red-600' : 'text-yellow-600'}>
                          {ex.status}
                        </span>
                        <span>{ex.sent_count} 发送</span>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          ) : (
            <p className="text-muted-foreground text-center">暂无数据</p>
          )}
        </div>
      </div>
    </div>
  );
}

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

function CampaignModal({
  initial,
  onSave,
  onClose,
}: {
  initial?: Campaign;
  onSave: (dto: any, id?: string) => Promise<void>;
  onClose: () => void;
}) {
  const [name, setName] = useState(initial?.name ?? '');
  const [description, setDescription] = useState(initial?.description ?? '');
  const [notificationId, setNotificationId] = useState(initial?.notificationId ?? '');
  const [scheduleType, setScheduleType] = useState<ScheduleType>(initial?.scheduleType ?? 'ONCE');
  const [scheduledAt, setScheduledAt] = useState(
    initial?.scheduledAt ? initial.scheduledAt.slice(0, 16) : '',
  );
  const [cronExpr, setCronExpr] = useState(initial?.cronExpr ?? '');
  const [timezone, setTimezone] = useState(initial?.timezone ?? 'Asia/Shanghai');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  const handleSubmit = async () => {
    if (!name.trim()) { setError('活动名称不能为空'); return; }
    setSaving(true); setError('');
    try {
      await onSave({
        name: name.trim(),
        description: description.trim() || undefined,
        notificationId: notificationId.trim() || undefined,
        scheduleType,
        scheduledAt: scheduleType === 'ONCE' && scheduledAt ? new Date(scheduledAt).toISOString() : null,
        cronExpr: scheduleType === 'RECURRING' ? cronExpr.trim() : null,
        timezone,
      }, initial?.id);
      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-lg rounded-xl shadow-xl border flex flex-col max-h-[90vh]">
        <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="flex-1 overflow-y-auto px-6 py-4 space-y-4">
          {error && <p className="text-sm text-red-500">{error}</p>}

          <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)} maxLength={200} />
          </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)} />
          </div>

          <div>
            <label className="block text-xs font-medium mb-1">关联通知模板 ID（可选）</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={notificationId} onChange={(e) => setNotificationId(e.target.value)}
              placeholder="notification UUID" />
          </div>

          <div>
            <label className="block text-xs font-medium mb-1">调度类型</label>
            <div className="flex gap-4">
              {(['ONCE', 'RECURRING'] as ScheduleType[]).map((t) => (
                <label key={t} className="flex items-center gap-2 cursor-pointer text-sm">
                  <input type="radio" value={t} checked={scheduleType === t} onChange={() => setScheduleType(t)} />
                  {t === 'ONCE' ? '单次执行' : '循环执行（Cron）'}
                </label>
              ))}
            </div>
          </div>

          {scheduleType === 'ONCE' && (
            <div>
              <label className="block text-xs font-medium mb-1">执行时间</label>
              <input type="datetime-local" className="w-full rounded-md border bg-background px-3 py-2 text-sm"
                value={scheduledAt} onChange={(e) => setScheduledAt(e.target.value)} />
            </div>
          )}

          {scheduleType === 'RECURRING' && (
            <div>
              <label className="block text-xs font-medium mb-1">Cron 表达式</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={cronExpr} onChange={(e) => setCronExpr(e.target.value)}
                placeholder="0 9 * * 1 (每周一 09:00)" />
            </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={timezone} onChange={(e) => setTimezone(e.target.value)}
              placeholder="Asia/Shanghai" />
          </div>
        </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 ---------- */

const STATUS_OPTIONS: CampaignStatus[] = ['DRAFT', 'SCHEDULED', 'RUNNING', 'COMPLETED', 'CANCELLED', 'FAILED'];

export default function CampaignsPage() {
  const [items, setItems] = useState<Campaign[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [filterStatus, setFilterStatus] = useState('');
  const [offset, setOffset] = useState(0);
  const limit = 20;
  const [modal, setModal] = useState<{ mode: 'create' } | { mode: 'edit'; item: Campaign } | null>(null);
  const [statsId, setStatsId] = useState<string | null>(null);
  const [deleting, setDeleting] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const result = await listCampaigns({ status: filterStatus || undefined, limit, offset });
      setItems(result.items);
      setTotal(result.total);
    } catch (e) { console.error(e); }
    finally { setLoading(false); }
  }, [filterStatus, offset]);

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

  const handleSave = async (dto: any, id?: string) => {
    if (id) {
      await updateCampaign(id, dto);
    } else {
      const campaign = await createCampaign(dto);
      // Auto-schedule if scheduledAt provided
      if (dto.scheduledAt || dto.cronExpr) {
        await scheduleCampaign(campaign.id, { scheduledAt: dto.scheduledAt, cronExpr: dto.cronExpr, timezone: dto.timezone });
      }
    }
    await load();
  };

  const handleSchedule = async (item: Campaign) => {
    if (!item.scheduledAt && !item.cronExpr) {
      alert('请先设置执行时间或 Cron 表达式');
      return;
    }
    await scheduleCampaign(item.id, {
      scheduledAt: item.scheduledAt ?? undefined,
      cronExpr: item.cronExpr ?? undefined,
      timezone: item.timezone,
    });
    await load();
  };

  const handleCancel = async (item: Campaign) => {
    if (!confirm(`确认取消活动「${item.name}」？`)) return;
    await cancelCampaign(item.id);
    await load();
  };

  const handleDelete = async (item: Campaign) => {
    if (!confirm(`确认删除活动「${item.name}」？`)) return;
    setDeleting(item.id);
    try { await deleteCampaign(item.id); await load(); }
    finally { setDeleting(null); }
  };

  const statsItem = items.find((i) => i.id === statsId);

  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">
          <Megaphone 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">
          <select className="rounded-md border bg-background px-3 py-1.5 text-sm"
            value={filterStatus} onChange={(e) => { setFilterStatus(e.target.value); setOffset(0); }}>
            <option value="">全部状态</option>
            {STATUS_OPTIONS.map((s) => <option key={s} value={s}>{STATUS_LABEL[s]}</option>)}
          </select>
          <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 w-48">活动名称</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 && items.length === 0 && (
              <tr><td colSpan={6} className="text-center py-12 text-muted-foreground">加载中…</td></tr>
            )}
            {!loading && items.length === 0 && (
              <tr><td colSpan={6} className="text-center py-12 text-muted-foreground">暂无活动</td></tr>
            )}
            {items.map((item) => (
              <tr key={item.id} className="hover:bg-muted/30 transition-colors">
                <td className="px-4 py-3 font-medium max-w-[12rem] truncate" title={item.name}>{item.name}</td>
                <td className="px-4 py-3">
                  <span className={cn('px-2 py-0.5 rounded text-xs font-medium', STATUS_STYLE[item.status])}>
                    {STATUS_LABEL[item.status]}
                  </span>
                </td>
                <td className="px-4 py-3 text-xs text-muted-foreground">
                  {item.scheduleType === 'ONCE' ? '单次' : `循环: ${item.cronExpr ?? '—'}`}
                </td>
                <td className="px-4 py-3 text-xs text-muted-foreground">
                  {item.nextRunAt ? new Date(item.nextRunAt).toLocaleString('zh-CN', { dateStyle: 'short', timeStyle: 'short' }) : '—'}
                </td>
                <td className="px-4 py-3 text-xs text-muted-foreground">
                  {item.sentCount} / {item.readCount}
                </td>
                <td className="px-4 py-3">
                  <div className="flex items-center justify-end gap-1">
                    {/* Stats */}
                    <button onClick={() => setStatsId(item.id)}
                      className="p-1.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors" title="查看数据">
                      <BarChart2 className="h-4 w-4" />
                    </button>
                    {/* Schedule (DRAFT only) */}
                    {item.status === 'DRAFT' && (
                      <button onClick={() => handleSchedule(item)}
                        className="p-1.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors" title="排期">
                        <Play className="h-4 w-4 text-blue-600" />
                      </button>
                    )}
                    {/* Cancel (SCHEDULED only) */}
                    {item.status === 'SCHEDULED' && (
                      <button onClick={() => handleCancel(item)}
                        className="p-1.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors" title="取消">
                        <Ban className="h-4 w-4 text-orange-500" />
                      </button>
                    )}
                    {/* Edit */}
                    {['DRAFT', 'SCHEDULED'].includes(item.status) && (
                      <button onClick={() => setModal({ mode: 'edit', item })}
                        className="p-1.5 rounded hover:bg-accent text-muted-foreground hover:text-foreground transition-colors">
                        <Pencil className="h-4 w-4" />
                      </button>
                    )}
                    {/* Delete */}
                    <button onClick={() => handleDelete(item)} disabled={deleting === item.id}
                      className="p-1.5 rounded hover:bg-red-50 text-muted-foreground hover:text-red-600 transition-colors disabled:opacity-50">
                      <Trash2 className="h-4 w-4" />
                    </button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {total > limit && (
        <div className="flex items-center justify-between mt-4 text-sm text-muted-foreground">
          <span>共 {total} 条</span>
          <div className="flex gap-2">
            <button disabled={offset === 0} onClick={() => setOffset(Math.max(0, offset - limit))}
              className="px-3 py-1.5 rounded border hover:bg-accent disabled:opacity-40 transition-colors">上一页</button>
            <button disabled={offset + limit >= total} onClick={() => setOffset(offset + limit)}
              className="px-3 py-1.5 rounded border hover:bg-accent disabled:opacity-40 transition-colors">下一页</button>
          </div>
        </div>
      )}

      {modal && (
        <CampaignModal
          initial={modal.mode === 'edit' ? modal.item : undefined}
          onSave={handleSave}
          onClose={() => setModal(null)}
        />
      )}

      {statsId && statsItem && (
        <StatsModal campaignId={statsId} name={statsItem.name} onClose={() => setStatsId(null)} />
      )}
    </div>
  );
}
