'use client';

import { useEffect, useMemo, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';
import { ListChecks, CheckCircle2 } from 'lucide-react';
import type { PlanListItem } from '@pac/types';
import { cn } from '@/lib/utils';
import { useAuthStore } from '@/stores/auth-store';
import { useMyTasks } from '@/components/plans/use-my-tasks';

// 跟列表页 KPI 卡同款配色
const KPI_TONE: Record<string, string> = {
  amber: 'bg-amber-50 text-amber-700 ring-amber-200',
  emerald: 'bg-emerald-50 text-emerald-700 ring-emerald-200',
};

type Filter = 'active' | 'done' | 'all';

const FILTERS: { v: Filter; label: string }[] = [
  { v: 'active', label: '进行中' },
  { v: 'done', label: '已结案' },
  { v: 'all', label: '全部' },
];

const isDone = (s: string) => s === 'completed' || s === 'abandoned';

/**
 * 详情页左侧"我的任务"沉浸抽屉 —— hover 触发条滑出,可固定(pin)。
 * 服务端分页 + 触底加载更多(useMyTasks);筛选/搜索客户端在已加载项上做。
 * 点任务 → 跳到对应 /plans/{id},不离开详情沉浸流。
 */
export function TaskDrawer({ currentPlanId }: { currentPlanId: string }) {
  const router = useRouter();
  const clinicDict = useAuthStore((s) => s.user?.dictionary?.clinics);
  const { items, total, loading, hasMore, loadMore } = useMyTasks();

  const [hover, setHover] = useState(false);
  const [pinned, setPinned] = useState(false);
  const [search, setSearch] = useState('');
  const [filter, setFilter] = useState<Filter>('active');
  const open = hover || pinned;

  // 统计(已加载项)
  const stats = useMemo(() => {
    const pending = items.filter((p) => p.status === 'assigned').length;
    const closed = items.filter((p) => isDone(p.status)).length;
    return { pending, closed, total };
  }, [items, total]);

  // 客户端筛选 + 搜索 + 当前任务置顶
  const visible = useMemo(() => {
    let arr = items;
    if (filter === 'active') arr = arr.filter((p) => p.status === 'assigned');
    else if (filter === 'done') arr = arr.filter((p) => isDone(p.status));
    if (search.trim()) {
      const q = search.trim().toLowerCase();
      arr = arr.filter(
        (p) =>
          (p.patient.name ?? p.patient.nameMasked ?? '').toLowerCase().includes(q) ||
          (p.patient.phoneMasked ?? '').includes(q) ||
          p.patient.externalId.toLowerCase().includes(q),
      );
    }
    return [...arr].sort((a, b) => {
      if (a.id === currentPlanId) return -1;
      if (b.id === currentPlanId) return 1;
      return b.priorityScore - a.priorityScore;
    });
  }, [items, filter, search, currentPlanId]);

  // 触底加载哨兵
  const sentinelRef = useRef<HTMLDivElement | null>(null);
  useEffect(() => {
    if (!open || !sentinelRef.current) return;
    const el = sentinelRef.current;
    const io = new IntersectionObserver(
      (entries) => {
        if (entries[0]?.isIntersecting) loadMore();
      },
      { root: el.closest('[data-scroll]'), rootMargin: '120px' },
    );
    io.observe(el);
    return () => io.disconnect();
  }, [open, loadMore, visible.length]);

  return (
    <>
      {/* 隐式 hover 触发条 — 左边缘全高。移动端(<md)无 hover,直接隐藏 */}
      <div className="hidden md:block fixed left-0 top-0 bottom-0 w-3 z-40" onMouseEnter={() => setHover(true)}>
        {!open && (
          <div className="absolute left-0 top-1/2 -translate-y-1/2 flex flex-col items-center gap-1">
            <span className="block w-1 h-12 bg-teal-500/40 rounded-r-full hover:bg-teal-600 transition-colors" />
            <span className="text-[9px] text-slate-400 -rotate-90 origin-center mt-4 whitespace-nowrap tracking-widest pointer-events-none">
              我的任务
            </span>
          </div>
        )}
      </div>

      <aside
        className={cn(
          'fixed left-0 top-0 bottom-0 w-[320px] bg-white border-r border-slate-100 shadow-xl z-50',
          'transition-transform duration-200 ease-out flex flex-col',
          open ? 'translate-x-0' : '-translate-x-full',
        )}
        onMouseEnter={() => setHover(true)}
        onMouseLeave={() => setHover(false)}
      >
        {/* Header */}
        <header className="flex-none px-3 pt-3 pb-2 border-b border-slate-100">
          <div className="flex items-center justify-between gap-2 mb-2.5">
            <div className="flex items-center gap-2 min-w-0">
              <span className="inline-flex items-center justify-center w-7 h-7 rounded-md bg-teal-50 text-teal-700 ring-1 ring-teal-200 flex-none">
                <svg viewBox="0 0 24 24" className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M9 11l3 3L22 4 M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
                </svg>
              </span>
              <div className="min-w-0">
                <div className="text-[13px] font-semibold text-slate-900 leading-tight">我的任务</div>
                <div className="text-[10px] text-slate-500 tabular-nums">共 {total} 个</div>
              </div>
            </div>
            <button
              onClick={() => setPinned((v) => !v)}
              title={pinned ? '取消固定' : '固定打开'}
              className={cn(
                'w-6 h-6 rounded inline-flex items-center justify-center transition-colors flex-none',
                pinned ? 'bg-teal-600 text-white' : 'text-slate-400 hover:bg-slate-100 hover:text-slate-700',
              )}
            >
              <svg viewBox="0 0 24 24" className={cn('w-3.5 h-3.5 transition-transform', pinned && 'rotate-45')} fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M12 17v5M5 3h14l-2 7H7L5 3zM7 10l-1.5 4h13L17 10" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </button>
          </div>
          {/* KPI 卡(沿用列表页 KpiCard 样式,聚焦"我的")*/}
          <div className="grid grid-cols-2 gap-1.5">
            <KpiMini tone="amber" icon={<ListChecks className="h-4 w-4" />} label="我的进行中" value={stats.pending} />
            <KpiMini tone="emerald" icon={<CheckCircle2 className="h-4 w-4" />} label="我已结案" value={stats.closed} />
          </div>
        </header>

        {/* 搜索 + 筛选 */}
        <div className="flex-none px-3 pt-2.5 pb-2 border-b border-slate-100 space-y-2">
          <div className="relative">
            <svg viewBox="0 0 24 24" className="absolute left-2 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-slate-400" fill="none" stroke="currentColor" strokeWidth="2">
              <circle cx="11" cy="11" r="7" />
              <path d="m21 21-4.3-4.3" strokeLinecap="round" />
            </svg>
            <input
              type="search"
              placeholder="搜索 姓名 / 手机 / ID(已加载项)"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full pl-7 pr-2.5 py-1.5 rounded-md border border-slate-100 bg-slate-50 text-[12px] text-slate-800 focus:outline-none focus:ring-2 focus:ring-teal-200 focus:border-teal-300 focus:bg-white transition-all"
            />
          </div>
          <div className="grid grid-cols-3 gap-1">
            {FILTERS.map((t) => {
              const count =
                t.v === 'active' ? stats.pending : t.v === 'done' ? stats.closed : items.length;
              return (
                <button
                  key={t.v}
                  onClick={() => setFilter(t.v)}
                  className={cn(
                    'px-1 py-1 rounded inline-flex items-center justify-center gap-1 text-[11px] transition-colors',
                    filter === t.v ? 'bg-teal-600 text-white font-semibold' : 'bg-slate-100 text-slate-600 hover:bg-slate-200',
                  )}
                >
                  <span>{t.label}</span>
                  <span className="tabular-nums opacity-80">{count}</span>
                </button>
              );
            })}
          </div>
        </div>

        {/* 列表 + 触底分页 */}
        <div data-scroll className="flex-1 overflow-y-auto p-2">
          {visible.length === 0 && !loading ? (
            <p className="text-center text-[11px] text-slate-400 py-8">未找到任务</p>
          ) : (
            <ul className="space-y-1.5">
              {visible.map((p) => (
                <TaskRow
                  key={p.id}
                  item={p}
                  active={p.id === currentPlanId}
                  clinicName={p.targetClinicId ? clinicDict?.[p.targetClinicId] ?? null : null}
                  onSelect={() => {
                    setHover(false);
                    if (p.id !== currentPlanId) router.push(`/plans/${p.id}`);
                  }}
                />
              ))}
            </ul>
          )}
          {/* 触底哨兵 */}
          <div ref={sentinelRef} className="h-6 flex items-center justify-center">
            {loading && <span className="text-[10.5px] text-slate-400">加载中…</span>}
            {!hasMore && items.length > 0 && !loading && (
              <span className="text-[10px] text-slate-300">没有更多了</span>
            )}
          </div>
        </div>
      </aside>
    </>
  );
}

/** 抽屉版 KPI 卡 —— 复刻列表页 KpiCard 视觉(icon 环 + label + 大数字),窄栏适配 */
function KpiMini({
  tone,
  icon,
  label,
  value,
}: {
  tone: keyof typeof KPI_TONE;
  icon: React.ReactNode;
  label: string;
  value: number;
}) {
  const T = KPI_TONE[tone] ?? '';
  return (
    <div className="flex items-center gap-2 rounded-lg border border-slate-100 bg-white px-2 py-1.5">
      <span className={cn('inline-flex h-7 w-7 flex-none items-center justify-center rounded-lg ring-1 ring-inset', T)}>
        {icon}
      </span>
      <div className="min-w-0">
        <div className="text-[10px] leading-tight text-slate-500">{label}</div>
        <div className={cn('text-[18px] font-bold leading-none nums mt-0.5', T.split(' ')[1] ?? '')}>{value}</div>
      </div>
    </div>
  );
}

function TaskRow({
  item,
  active,
  clinicName,
  onSelect,
}: {
  item: PlanListItem;
  active: boolean;
  clinicName: string | null;
  onSelect: () => void;
}) {
  const name = item.patient.name ?? item.patient.nameMasked ?? item.patient.externalId;
  const done = isDone(item.status);
  return (
    <li>
      <button
        onClick={onSelect}
        className={cn(
          'w-full text-left rounded-md border px-2.5 py-2 transition-colors',
          active
            ? 'border-teal-400 bg-teal-50/60 ring-1 ring-teal-100'
            : 'border-slate-100 bg-white hover:border-slate-300 hover:bg-slate-50',
          done && 'opacity-70',
        )}
      >
        <div className="flex items-center justify-between gap-2">
          <span className="truncate text-[12.5px] font-semibold text-slate-900">{name}</span>
          <span
            className={cn(
              'flex-none text-[10px] tabular-nums font-semibold px-1.5 py-0.5 rounded',
              item.priorityScore >= 80 ? 'bg-rose-100 text-rose-700' : item.priorityScore >= 60 ? 'bg-amber-100 text-amber-700' : 'bg-slate-100 text-slate-600',
            )}
          >
            {item.priorityScore}
          </span>
        </div>
        <div className="mt-0.5 flex items-center gap-1.5 text-[10.5px] text-slate-500 min-w-0">
          <span className="truncate">{item.scenarioLabel}</span>
          {clinicName && (
            <>
              <span className="text-slate-300">·</span>
              <span className="truncate">{clinicName}</span>
            </>
          )}
        </div>
        {active && <div className="mt-1 text-[10px] text-teal-700 font-medium">● 当前查看</div>}
      </button>
    </li>
  );
}
