'use client';

import { useEffect, useState } from 'react';
import type { AgentWorkloadResponse } from '@pac/types';
import { assignmentsApi } from '@/components/plans/assignments-api';
import { useAssignmentSyncStore } from '@/stores/assignment-sync-store';
import { cn } from '@/lib/utils';

/// 窗口档位。⚠️ 只给两档:主管要的是"这周怎么样 / 这个月怎么样",更细他也不看
const WINDOWS = [
  { days: 7, label: '近 7 天' },
  { days: 30, label: '近 30 天' },
] as const;

/**
 * 团队现在什么状态 —— 主管工作台右栏。
 *
 * ── 一张表里混着两种时间性，这是最容易读错的地方 ────────────────
 *   · **当前在手** —— 此刻手上还压着多少，与窗口无关；
 *   · **超期 / 完成 / 退回率 / 没动** —— 都在选中的那个窗口里，换窗口一起变。
 * ⚠️ 所以表头第一列写死「**当前**在手」。只写「在手」时实测会被读成"这 7 天分了 62 条"。
 *
 * 🔴 「超期」是**窗口口径**（2026-08-07 实测推翻了"当前超期"）：
 *   到期回收器每 10 分钟扫一遍，过期的单当场被收走 —— "当前还压在手上且已过期"
 *   结构上几乎永远是 0（实测账本 378 条到期回收 vs 当前在手已过期 0 条）。
 *   摆那个数上去，主管会以为团队从不超期。
 *
 * ⚠️ 退回率那行小字是**服务端拼好的**（`rateNote`），⛔ 前端别自己算：
 *   它必须带两个分母（「退回 3 / 已处置 21 = 14.3%，另有 2 条没动」）——
 *   只给百分比会把"没动"藏起来，而那个数本身就是信号。
 */
export function TeamStatus({ clinicId }: { clinicId: string | null }) {
  const [days, setDays] = useState<number>(7);
  const [data, setData] = useState<AgentWorkloadResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  /// ⭐ 助手那边确认/撤销后跟着重拉 —— 每个人的在手/分到/退回率分母都变了(见 assignment-sync-store)
  const syncSeq = useAssignmentSyncStore((s) => s.seq);
  useEffect(() => {
    if (!clinicId) return;
    let alive = true;
    setLoading(true);
    setError(null);
    assignmentsApi
      .workload(clinicId, days)
      .then((r) => alive && setData(r))
      .catch((e) => alive && setError(e instanceof Error ? e.message : '加载失败'))
      .finally(() => alive && setLoading(false));
    return () => {
      alive = false;
    };
  }, [clinicId, days, syncSeq]);

  const rows = data?.agents ?? [];
  const inHandTotal = rows.reduce((s, a) => s + a.inHand, 0);
  /**
   * 「超期最多」的判据。
   * 🔴 **并列第一时一个都不标**(2026-08-07 实测:17 位客服全是 23 条,结果每一行都挂着
   *   「超期最多」—— 标一片等于没标,而且看着像系统坏了)。
   *   只有**唯一的最高**且确实高过第二名时才标 —— 那才是"这个人要单独看一眼"的信号。
   */
  const sorted = [...rows].map((a) => a.overdue).sort((x, y) => y - x);
  const top = sorted[0] ?? 0;
  const flagOverdue = top > 0 && top > (sorted[1] ?? 0) ? top : null;

  return (
    <div className="flex min-h-0 w-full flex-col overflow-hidden rounded-lg border border-slate-100 bg-white">
      <div className="flex flex-none flex-wrap items-center gap-x-2.5 gap-y-1 border-b border-slate-50 px-3.5 py-2.5">
        <span className="text-[13.5px] font-semibold text-slate-900">团队现在什么状态</span>
        <span className="nums text-[11px] text-slate-400">
          {rows.length} 位在岗 · 在手 {inHandTotal} 条
        </span>
        <span className="ml-auto inline-flex rounded-lg bg-slate-100 p-0.5">
          {WINDOWS.map((w) => (
            <button
              key={w.days}
              type="button"
              onClick={() => setDays(w.days)}
              className={cn(
                'nums rounded-md px-2.5 py-1 text-[11.5px] transition-colors',
                days === w.days
                  ? 'bg-white text-slate-900 shadow-sm'
                  : 'text-slate-500 hover:text-slate-700',
              )}
            >
              {w.label}
            </button>
          ))}
        </span>
      </div>

      <div className="min-h-0 flex-1 overflow-auto">
        {error ? (
          <p className="px-3.5 py-6 text-center text-[12px] text-rose-600">{error}</p>
        ) : loading && rows.length === 0 ? (
          <div className="space-y-2 p-3.5">
            {Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="h-6 animate-pulse rounded bg-slate-100" />
            ))}
          </div>
        ) : rows.length === 0 ? (
          <p className="px-3.5 py-8 text-center text-[12px] text-slate-400">
            {clinicId ? '这个诊所近 12 个月没有回访记录，名册是空的' : '请先选择诊所'}
          </p>
        ) : (
          <table className="w-full border-collapse text-[12.5px] text-slate-700">
            <thead>
              <tr className="sticky top-0 z-10 bg-slate-50 shadow-[inset_0_-1px_0_#E2E8F0]">
                <th className="px-3.5 py-1.5 text-left text-[11px] font-medium text-slate-500">
                  客服
                </th>
                {/* 🔴 「当前」两个字不能省 —— 它是这一列与右边四列的唯一区分 */}
                <th className="whitespace-nowrap px-2.5 py-1.5 text-right text-[11px] font-medium text-slate-500">
                  当前在手
                </th>
                <th className="whitespace-nowrap px-2.5 py-1.5 text-right text-[11px] font-medium text-slate-500">
                  超期
                </th>
                <th className="whitespace-nowrap px-2.5 py-1.5 text-right text-[11px] font-medium text-slate-500">
                  完成
                </th>
                <th className="whitespace-nowrap px-3.5 py-1.5 text-right text-[11px] font-medium text-slate-500">
                  退回率
                </th>
              </tr>
            </thead>
            <tbody>
              {rows.map((a) => {
                const worst = flagOverdue != null && a.overdue === flagOverdue;
                return (
                  <tr key={a.userId} className="border-t border-slate-50">
                    <td className="whitespace-nowrap px-3.5 py-2">
                      <span className="font-medium text-slate-900">{a.name ?? a.userId}</span>
                      {worst && (
                        <span className="ml-1.5 text-[10.5px] text-amber-700">超期最多</span>
                      )}
                    </td>
                    <td className="nums px-2.5 py-2 text-right">{a.inHand}</td>
                    {/*
                      🔴 **超期 > 0 就上琥珀**（2026-08-07 产品问「需不需要颜色」）。
                        在此之前「完成」是绿的、「超期」是黑的 —— 好事有色、坏事没色，
                        一行扫过去眼睛只被绿色勾住，而主管要找的恰恰是超期那一列。
                      ⚠️ 语义色与「没动」同一支琥珀（两者都是"到期没人动"的同一件事，
                        只是一个按批次看、一个按人看）。⛔ 别另挑一个颜色。
                      ⚠️ 0 用 slate-300 压下去 —— 那是好消息，不该占视觉带宽。
                      ⚠️ 「超期最多」那位加粗再强调一档；并列第一时谁都不加粗（见上）。
                    */}
                    <td
                      className={cn(
                        'nums px-2.5 py-2 text-right',
                        a.overdue === 0
                          ? 'text-slate-300'
                          : worst
                            ? 'font-semibold text-amber-700'
                            : 'text-amber-700',
                      )}
                    >
                      {a.overdue}
                    </td>
                    <td className="nums px-2.5 py-2 text-right text-emerald-700">{a.done}</td>
                    <td className="px-3.5 py-2 text-right">
                      {/* ⚠️ 百分比与两个分母**分两行**：一行塞不下，而分母不能省 */}
                      <div className="nums text-slate-900">
                        {a.handled ? `${((a.released / a.handled) * 100).toFixed(1)}%` : '—'}
                      </div>
                      <div className="nums text-[10.5px] leading-snug text-slate-400">
                        {a.rateNote}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
        {/*
          ⛔ 这里原来铺了一段服务端口径说明（「只有『当前在手』是此刻的状态；超期/完成/退回/
            没动都在近 N 天这一个窗口里…」）—— 2026-08-07 产品要求去掉：一屏表格下面挂
            三行小字，主管扫的时候只当噪音。
          ⚠️ 那个区分**没有丢**：表头第一列写死「**当前**在手」，其余四列在窗口切换器
            （近 7 天 / 近 30 天）正下方 —— 位置本身就说明了它们跟着窗口走。
          ⚠️ 服务端的 `note` 仍然照常返回（助手要照抄它），⛔ 别顺手把后端那段也删了。
        */}
      </div>
    </div>
  );
}
