import { useCallback, useEffect, useMemo, useState } from 'react';
import { X, RotateCcw, Clock, CheckCircle2, XCircle, Send, Loader2, ChevronRight } from 'lucide-react';
import { motion, AnimatePresence } from 'motion/react';
import { fetchNotifications, updateNotification } from './api';
import type { NotificationRecord, NotificationStatus, SchedulingSuggestion, CandidateVehicle } from './types';
import Blur from '../../components/Blur';
import SwapPreview from './SwapPreview';

interface Props {
  onClose: () => void;
  onChange?: () => void;
  /** When true, pre-filter to the last 7 days (excluding cancelled). */
  recentOnly?: boolean;
  /** Current suggestions used to enrich records with customer/dept/manager and enable drill-down. */
  suggestions?: SchedulingSuggestion[];
}

const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;

function shortDept(dept: string | null | undefined): string {
  return (dept || '').replace('业务', '');
}

type StatusTab = 'all' | NotificationStatus;

const STATUS_TABS: { key: StatusTab; label: string }[] = [
  { key: 'all', label: '全部' },
  { key: 'sent', label: '待执行' },
  { key: 'executed', label: '已执行' },
  { key: 'cancelled', label: '已取消' },
];

function statusBadge(status: NotificationStatus) {
  if (status === 'sent') return { text: '待执行', icon: <Send size={9} />, cls: 'text-amber-700 bg-amber-50' };
  if (status === 'executed') return { text: '已执行', icon: <CheckCircle2 size={9} />, cls: 'text-emerald-700 bg-emerald-50' };
  return { text: '已取消', icon: <XCircle size={9} />, cls: 'text-slate-500 bg-slate-100' };
}

function fmtDateTime(iso: string): string {
  if (!iso) return '';
  const d = new Date(iso);
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  const hh = String(d.getHours()).padStart(2, '0');
  const mm = String(d.getMinutes()).padStart(2, '0');
  return `${y}-${m}-${day} ${hh}:${mm}`;
}

export default function NotificationHistory({ onClose, onChange, recentOnly = false, suggestions }: Props) {
  const [records, setRecords] = useState<NotificationRecord[]>([]);
  const [loading, setLoading] = useState(false);
  const [tab, setTab] = useState<StatusTab>('all');
  const [recent7d, setRecent7d] = useState(recentOnly);
  const [mutatingId, setMutatingId] = useState<number | null>(null);
  const [executeTarget, setExecuteTarget] = useState<NotificationRecord | null>(null);
  const [afterMileageInput, setAfterMileageInput] = useState('');
  const [notesInput, setNotesInput] = useState('');
  const [drillTarget, setDrillTarget] = useState<{ suggestion: SchedulingSuggestion; candidate: CandidateVehicle } | null>(null);

  const suggestionById = useMemo(() => {
    const map = new Map<string, SchedulingSuggestion>();
    for (const s of suggestions ?? []) map.set(s.id, s);
    return map;
  }, [suggestions]);

  const visibleRecords = recent7d
    ? records.filter(r => {
        const t = Date.parse(r.createdAt);
        return Number.isFinite(t) && Date.now() - t <= SEVEN_DAYS_MS;
      })
    : records;

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const resp = await fetchNotifications(tab === 'all' ? undefined : tab);
      setRecords(resp.records);
    } finally {
      setLoading(false);
    }
  }, [tab]);

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

  const handleExecuteClick = (rec: NotificationRecord) => {
    setExecuteTarget(rec);
    setAfterMileageInput('');
    setNotesInput('');
  };

  const handleExecuteConfirm = async () => {
    if (!executeTarget) return;
    setMutatingId(executeTarget.id);
    try {
      const body: { status: NotificationStatus; notes?: string; afterMileage?: number } = { status: 'executed' };
      if (notesInput.trim()) body.notes = notesInput.trim();
      const parsed = Number(afterMileageInput);
      if (Number.isFinite(parsed) && parsed > 0) body.afterMileage = parsed;
      await updateNotification(executeTarget.id, body);
      setExecuteTarget(null);
      await load();
      onChange?.();
    } finally {
      setMutatingId(null);
    }
  };

  const handleCancel = async (rec: NotificationRecord) => {
    if (!confirm(`确定取消 ${rec.currentPlate} → ${rec.candidatePlate} 的干预？`)) return;
    setMutatingId(rec.id);
    try {
      await updateNotification(rec.id, { status: 'cancelled' });
      await load();
      onChange?.();
    } finally {
      setMutatingId(null);
    }
  };

  return (
    <div className="fixed inset-0 bg-black/50 backdrop-blur-sm z-[60] flex items-end sm:items-center justify-center" onClick={onClose}>
      <motion.div
        initial={{ y: 40, opacity: 0 }}
        animate={{ y: 0, opacity: 1 }}
        onClick={e => e.stopPropagation()}
        className="bg-white rounded-t-2xl sm:rounded-2xl shadow-2xl w-full sm:max-w-xl overflow-hidden flex flex-col max-h-[85vh] sm:mx-4"
      >
        {/* Header */}
        <div className="bg-slate-800 px-4 py-3 flex items-center justify-between flex-shrink-0">
          <div className="flex items-center gap-2">
            <Clock size={16} className="text-white" />
            <span className="text-white font-bold text-sm">调度记录</span>
          </div>
          <div className="flex items-center gap-1">
            <button onClick={load} disabled={loading} className="text-slate-300 hover:text-white p-1 cursor-pointer">
              <RotateCcw size={14} className={loading ? 'animate-spin' : ''} />
            </button>
            <button onClick={onClose} className="text-slate-300 hover:text-white p-1 cursor-pointer">
              <X size={18} />
            </button>
          </div>
        </div>

        {/* Status tabs */}
        <div className="border-b border-slate-100 px-4 py-2 flex gap-1.5 flex-shrink-0 flex-wrap items-center">
          {STATUS_TABS.map(t => (
            <button
              key={t.key}
              onClick={() => setTab(t.key)}
              className={`text-[11px] px-3 py-1 rounded-full font-medium cursor-pointer transition-colors ${
                tab === t.key ? 'bg-slate-800 text-white' : 'bg-slate-100 text-slate-500 hover:bg-slate-200'
              }`}
            >
              {t.label}
            </button>
          ))}
          <div className="ml-auto">
            <button
              onClick={() => setRecent7d(v => !v)}
              className={`text-[11px] px-3 py-1 rounded-full font-medium cursor-pointer transition-colors ${
                recent7d ? 'bg-emerald-600 text-white' : 'bg-slate-100 text-slate-500 hover:bg-slate-200'
              }`}
              title="仅看最近 7 天"
            >
              近 7 天
            </button>
          </div>
        </div>

        {/* Body */}
        <div className="flex-1 overflow-y-auto">
          {loading && records.length === 0 ? (
            <div className="py-16 text-center text-slate-400 text-xs flex items-center justify-center gap-2">
              <Loader2 size={14} className="animate-spin" /> 加载中
            </div>
          ) : visibleRecords.length === 0 ? (
            <div className="py-16 text-center text-slate-400">
              <Clock className="w-8 h-8 text-slate-200 mx-auto mb-2" />
              <p className="text-sm">{recent7d ? '最近 7 天暂无干预记录' : '暂无记录'}</p>
            </div>
          ) : (
            <div className="divide-y divide-slate-50">
              {visibleRecords.map(rec => {
                const badge = statusBadge(rec.status);
                const busy = mutatingId === rec.id;
                const suggestion = suggestionById.get(rec.suggestionId);
                const candidate = suggestion?.candidates.find(c => c.plateNumber === rec.candidatePlate) ?? null;
                const canDrill = !!suggestion && !!candidate;
                const v = suggestion?.currentVehicle;

                const handleRowClick = () => {
                  if (canDrill && suggestion && candidate) setDrillTarget({ suggestion, candidate });
                };

                return (
                  <div
                    key={rec.id}
                    onClick={handleRowClick}
                    className={`px-4 py-3 transition-colors ${canDrill ? 'cursor-pointer hover:bg-slate-50/60 active:bg-slate-100' : ''}`}
                  >
                    <div className="flex items-center justify-between gap-2 mb-1">
                      <div className="flex items-center gap-1.5 text-xs min-w-0">
                        <span className="font-mono font-bold text-slate-900"><Blur>{rec.currentPlate}</Blur></span>
                        <span className="text-slate-400">→</span>
                        <span className="font-mono font-bold text-blue-700"><Blur>{rec.candidatePlate}</Blur></span>
                      </div>
                      <div className="flex items-center gap-1.5 flex-shrink-0">
                        <span className={`text-[9px] font-bold px-1.5 py-0.5 rounded flex items-center gap-0.5 ${badge.cls}`}>
                          {badge.icon} {badge.text}
                        </span>
                        {canDrill && <ChevronRight size={12} className="text-slate-300" />}
                      </div>
                    </div>
                    {v && (
                      <div className="flex items-center gap-1.5 text-[10px] text-slate-500 mb-0.5 truncate">
                        {v.department && <span className="font-medium">{shortDept(v.department)}</span>}
                        {v.manager && <span>{v.manager}</span>}
                        <span className="text-slate-400 truncate"><Blur>{v.customer || '-'}</Blur></span>
                      </div>
                    )}
                    <div className="flex items-center gap-3 text-[10px] text-slate-400">
                      {rec.operatorName && <span>操作人 {rec.operatorName}</span>}
                      <span>{fmtDateTime(rec.createdAt)}</span>
                      {rec.status === 'executed' && rec.executedAt && (
                        <span className="text-emerald-500">执行 {fmtDateTime(rec.executedAt)}</span>
                      )}
                    </div>
                    {rec.notes && (
                      <div className="mt-1 text-[10px] text-slate-500 bg-slate-50 rounded px-2 py-1">{rec.notes}</div>
                    )}
                    {rec.status === 'sent' && (
                      <div className="mt-2 flex items-center gap-2" onClick={e => e.stopPropagation()}>
                        <button
                          onClick={() => handleExecuteClick(rec)}
                          disabled={busy}
                          className="text-[10px] font-bold text-white bg-emerald-600 hover:bg-emerald-500 disabled:opacity-50 px-2.5 py-1 rounded cursor-pointer transition-colors flex items-center gap-1"
                        >
                          <CheckCircle2 size={10} /> 标记已执行
                        </button>
                        <button
                          onClick={() => handleCancel(rec)}
                          disabled={busy}
                          className="text-[10px] font-medium text-slate-500 hover:text-rose-600 disabled:opacity-50 px-2 py-1 rounded cursor-pointer transition-colors"
                        >
                          取消
                        </button>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </motion.div>

      {/* Execute confirmation modal */}
      <AnimatePresence>
        {executeTarget && (
          <div
            className="fixed inset-0 bg-black/50 backdrop-blur-sm z-[80] flex items-end sm:items-center justify-center"
            onClick={() => mutatingId === null && setExecuteTarget(null)}
          >
            <motion.div
              initial={{ y: 40, opacity: 0 }}
              animate={{ y: 0, opacity: 1 }}
              exit={{ y: 40, opacity: 0 }}
              onClick={e => e.stopPropagation()}
              className="bg-white rounded-t-2xl sm:rounded-2xl shadow-2xl w-full sm:max-w-sm overflow-hidden flex flex-col sm:mx-4"
            >
              <div className="bg-emerald-600 px-4 py-3 flex items-center justify-between">
                <span className="text-white font-bold text-sm">确认已执行</span>
                <button
                  onClick={() => mutatingId === null && setExecuteTarget(null)}
                  disabled={mutatingId !== null}
                  className="text-emerald-100 hover:text-white p-1 cursor-pointer disabled:opacity-50"
                >
                  <X size={16} />
                </button>
              </div>
              <div className="px-4 py-4 space-y-3">
                <div className="text-xs text-slate-500">
                  <span className="font-mono font-bold text-slate-900"><Blur>{executeTarget.currentPlate}</Blur></span>
                  <span className="mx-1.5">→</span>
                  <span className="font-mono font-bold text-blue-700"><Blur>{executeTarget.candidatePlate}</Blur></span>
                </div>
                <div>
                  <label className="text-[10px] text-slate-400 uppercase font-bold block mb-1">执行后里程 (km, 可选)</label>
                  <input
                    type="number"
                    inputMode="numeric"
                    value={afterMileageInput}
                    onChange={e => setAfterMileageInput(e.target.value)}
                    placeholder="例如 45230"
                    className="w-full px-3 py-2 text-xs bg-slate-50 rounded-lg border border-slate-200 outline-none focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-400 transition-all"
                  />
                </div>
                <div>
                  <label className="text-[10px] text-slate-400 uppercase font-bold block mb-1">备注 (可选)</label>
                  <textarea
                    value={notesInput}
                    onChange={e => setNotesInput(e.target.value)}
                    rows={2}
                    placeholder="例如：司机已到位，交接完成"
                    className="w-full px-3 py-2 text-xs bg-slate-50 rounded-lg border border-slate-200 outline-none focus:ring-2 focus:ring-emerald-500/20 focus:border-emerald-400 transition-all resize-none"
                  />
                </div>
              </div>
              <div className="border-t border-slate-100 px-4 py-3 flex gap-2">
                <button
                  onClick={() => setExecuteTarget(null)}
                  disabled={mutatingId !== null}
                  className="flex-1 py-2 text-xs font-bold text-slate-500 bg-slate-50 hover:bg-slate-100 rounded-lg cursor-pointer disabled:opacity-50 transition-colors"
                >
                  取消
                </button>
                <button
                  onClick={handleExecuteConfirm}
                  disabled={mutatingId !== null}
                  className="flex-1 py-2 text-xs font-bold text-white bg-emerald-600 hover:bg-emerald-500 rounded-lg cursor-pointer disabled:opacity-50 transition-colors"
                >
                  {mutatingId !== null ? '保存中...' : '确认'}
                </button>
              </div>
            </motion.div>
          </div>
        )}
      </AnimatePresence>

      {/* Drill-down: replacement plan */}
      {drillTarget && (
        <SwapPreview
          suggestion={drillTarget.suggestion}
          candidate={drillTarget.candidate}
          onClose={() => setDrillTarget(null)}
          onSuccess={() => { load(); onChange?.(); }}
        />
      )}
    </div>
  );
}
