'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { ArrowUpRight, Inbox, RefreshCw } from 'lucide-react';
import { Permission } from '@pac/types';
import { Can } from '@/components/can';
import { useHasPermission } from '@/hooks/use-permission';
import { plansApi } from '@/components/plans/plans-api';
import { PatientPickerRail } from '@/components/plans/patient-picker-rail';
import { IdentityCluster } from '@/components/identity-cluster';
import { isEmbedded } from '@/lib/embed';

/**
 * /plans — 工作台入口解析器(原独立列表页已废除,左栏 patient-picker-rail 取代了它)。
 *
 * 进来直接落到详情工作台,选人规则(纯规则):
 *   ① 我的「进行中」第一个(优先续上手头工作)
 *   ② 没有 → 空工作台
 * ⛔ 没有"② 召回池第一个"那一档了(2026-08-10):池子与分配整个搬去了主管工作台,
 *   这一页只回答「分给我的还有哪些」。
 * 所有旧入口(/ 重定向、各处"返回召回池"链接)自动适配 —— 都会被本页弹回详情。
 */
export default function PlansEntryPage() {
  return (
    <Can perm={Permission.PLAN_VIEW_OWN}>
      <EntryResolver />
    </Can>
  );
}

function EntryResolver() {
  const router = useRouter();
  /// 主管判据:决定**落地默认**(工作台 vs 执行页)与空态文案,⛔ 不再决定"能不能看池子"
  const canDispatch = useHasPermission(Permission.PLAN_DISPATCH);
  const [phase, setPhase] = useState<'resolving' | 'empty'>('resolving');

  useEffect(() => {
    let cancelled = false;
    /**
     * 🔴 **主管落到主管工作台，⛔ 不再滑进某个患者的详情页**（2026-08-07 产品定）。
     *
     * 在此之前主管和客服走**同一条**落地规则：先我的进行中、再召回池第一个 ——
     * 于是他一登录就站在**某一个患者**的详情页上，而他这一屏要做的是
     * "我这周分了多少、拿回来多少、下一批分给谁"。这与 08-04 评审那句
     * 「场景和思路不应该去混」是同一个问题的两面（见 doctrine 里被改写的 T16）。
     *
     * ⚠️ 这只改**落地默认**，⛔ 不是把执行页锁掉：
     *   主管本质也是客服，他从工作台头部的「客服执行页 ↗」照样进得来，
     *   进来之后下面那套规则原样生效（所以它一行都没删）。
     * ⭐ 这里**不存在**"权限还没加载完就抢跑"的问题：`permissions` 来自 **JWT 即时解码**，
     *   而 `AuthGate` 拿到 token 才渲染 children —— 本组件挂载时它一定已经在了。
     *   ⚠️ 别把它和 `clinicIds` 搞混：**那个**才是 `/auth/session` 异步回来的
     *   （工作台的诊所选择器就为此踩过 —— 第一帧锁错诊所，两栏数据对不上却不报错）。
     */
    /**
     * ⚠️ `?exec=1` = **主管明确要来执行页**（工作台头部那个「客服执行页 ↗」带的）。
     *
     * 🔴 不给这个出口，那个链接就是**死的**（2026-08-07 实测）：点它 → `/plans` →
     *   这里又把他弹回 `/supervisor`，肉眼看就是"没反应"。
     *   落地默认要改，但**明确的导航意图不能被默认覆盖**。
     * ⚠️ 读 `window.location.search` 而不是 `useSearchParams()`：后者会让这张静态页
     *   退化成必须包 Suspense 的 CSR bailout，为一个开关不值当。
     */
    const wantsExec =
      typeof window !== 'undefined' && new URLSearchParams(window.location.search).has('exec');
    if (canDispatch && !wantsExec) {
      router.replace('/supervisor');
      return;
    }
    (async () => {
      try {
        // ① 我的进行中(优先级最高的一个)
        const mine = await plansApi.list({ view: 'mine', status: 'assigned', sort: 'priority_desc', page: 1, pageSize: 1 });
        if (cancelled) return;
        if (mine.items[0]) {
          router.replace(`/plans/${mine.items[0].id}`);
          return;
        }
        /**
         * 🔴 这里**曾经有一个「② 召回池第一个(仅主管)」的兜底**,2026-08-10 撤掉。
         *
         * 执行页已经没有召回池了(产品定:池子与分配整个搬去主管工作台),
         * 留着这条兜底就是**唯一一条还能把人滑进池子的路** ——
         * 主管的「我的」一空,系统就自动把他送进池子里某个患者的详情页,
         * 而左栏根本没有那个 tab,他会以为这条单是分给自己的。
         * ⛔ 别加回来:要看池子去工作台的「分一批新的」。
         */
        setPhase('empty');
      } catch {
        if (!cancelled) setPhase('empty');
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [router, canDispatch]);

  if (phase === 'resolving') {
    return (
      <div className="flex h-screen items-center justify-center gap-2 text-sm text-muted-foreground">
        <span className="h-4 w-4 animate-spin rounded-full border-2 border-brand-500 border-t-transparent" />
        正在进入召回工作台…
      </div>
    );
  }

  // ③ 空工作台:左栏可用(调筛选自己找人),右侧整体空态
  return (
    <div className="flex h-screen flex-col overflow-hidden bg-slate-50">
      {/* 空态 header —— 内容只有 PAC 品牌 + 用户三件套,无功能项;嵌入宿主时整体隐藏 */}
      {!isEmbedded() && (
        <header className="flex h-12 flex-none items-center gap-2 border-b bg-white px-4">
          <span className="inline-flex h-7 w-7 items-center justify-center rounded-md bg-brand-600 text-[12px] font-bold text-white">
            PAC
          </span>
          <h1 className="text-[14px] font-semibold text-slate-900">召回工作台</h1>
          <div className="ml-auto flex items-center gap-2">
            <IdentityCluster />
          </div>
        </header>
      )}
      <div className="flex min-h-0 flex-1">
        <PatientPickerRail currentPlanId="" />
        <div className="flex min-w-0 flex-1 flex-col items-center justify-center gap-3 text-center">
          <span className="inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-slate-100 text-slate-400">
            <Inbox className="h-7 w-7" />
          </span>
          <div className="text-[15px] font-medium text-slate-700">
            {canDispatch ? '你名下没有待跟进的任务' : '暂无分配给你的任务'}
          </div>
          {/*
            ⭐ 空态**不许再提「召回池」和「左侧切视图」**(2026-08-10):
              执行页已经没有那两样东西了 —— 提了就是让人去找一个不存在的地方。
            ⚠️ 主管与客服的差别只剩**下一步去哪** :主管去工作台自己分一批,
              客服等派发。⛔ 别再按角色说两套"能看到什么"。
          */}
          <p className="max-w-sm text-[12.5px] leading-relaxed text-slate-500">
            {canDispatch
              ? '这一页只显示分给你自己的任务。要给团队分新的一批,去主管工作台。'
              : '手头的任务都处理完了。新任务由主管统一派发,稍后刷新看看。'}
          </p>
          {/* 主管的空态给一条明确的去路 —— ⛔ 别只说"去工作台"却不给入口 */}
          {canDispatch && (
            <Link
              href="/supervisor"
              className="inline-flex items-center gap-1 text-[12.5px] text-brand-700 hover:underline"
            >
              主管工作台
              <ArrowUpRight className="h-3.5 w-3.5" />
            </Link>
          )}
          <button
            type="button"
            onClick={() => window.location.reload()}
            className="inline-flex items-center gap-1.5 rounded-md border bg-white px-3 py-1.5 text-[12.5px] text-slate-600 hover:bg-slate-50"
          >
            <RefreshCw className="h-3.5 w-3.5" />
            刷新
          </button>
        </div>
      </div>
    </div>
  );
}
