'use client';

import Link from 'next/link';
import { use, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { toast } from 'sonner';
import { ChevronLeft } from 'lucide-react';
import { ApiCode, Permission } from '@pac/types';
import { Can } from '@/components/can';
import { Card, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { PlanDetailApp } from '@/components/plan-detail/plan-detail-app';
import { adaptData } from '@/components/plan-detail/adapt-data';
import { usePlanAggregate } from '@/components/plans/use-plan-aggregate';
import { useAuthStore } from '@/stores/auth-store';
import { usePlanSyncStore } from '@/stores/plan-sync-store';

/**
 * /plans/[planId] — Plan 详情(生产版)。
 *
 * 跟 (demo)/plan-detail/:externalId 区别:
 *   - 走 (app) 布局(AuthGate);
 *   - 调 /pac/v1/plans/:id/full(强 zod 不走 demo 路径);
 *   - 同样复用 <PlanDetailApp> + adapt-data(响应 shape 一致)。
 */
export default function PlanDetailRoutePage({ params }: { params: Promise<{ planId: string }> }) {
  const { planId } = use(params);
  return (
    <Can
      perm={Permission.PLAN_VIEW_OWN}
      fallback={
        <main className="container mx-auto max-w-3xl p-8">
          <Card>
            <CardContent className="py-10 text-center text-sm text-muted-foreground">
              需要 PLAN_VIEW_OWN 权限。
            </CardContent>
          </Card>
        </main>
      }
    >
      <PlanDetailLoader planId={planId} />
    </Can>
  );
}

// 模块级缓存上一次 ready 的聚合数据:切患者时 page 会整体重挂(state 全丢),
// 用它做 stale-while-loading —— 旧详情垫底 + 半透明加载罩,消掉整页白闪。
let lastAggregateCache: { planId: string; data: Parameters<typeof adaptData>[0] } | null = null;

function PlanDetailLoader({ planId }: { planId: string }) {
  const { state, refresh } = usePlanAggregate(planId);
  const dictionary = useAuthStore((s) => s.user?.dictionary);
  const router = useRouter();
  if (state.status === 'ready') {
    lastAggregateCache = { planId, data: state.data };
  }
  // 发布"当前工作台患者"(右下角助手按它出场景化开场建议)
  const currentPatientName = state.status === 'ready' ? (state.data.patient.name ?? '') : null;
  const currentPatientId = state.status === 'ready' ? state.data.patient.id : null;
  useEffect(() => {
    if (currentPatientName && currentPatientId) {
      usePlanSyncStore
        .getState()
        .setCurrent({ planId, patientId: currentPatientId, patientName: currentPatientName });
    }
  }, [planId, currentPatientId, currentPatientName]);

  // W4 末:单患者刷新后 plan 可能已被 supersede / abandoned(scenario 不再命中)
  // → /full 接口返回 PLAN_NOT_FOUND → 这里捕获后 toast + 跳列表(避免用户卡在 error 页)
  useEffect(() => {
    if (state.status === 'error' && state.code === ApiCode.PLAN_NOT_FOUND) {
      toast.info('该召回任务已不存在', { description: '可能已完成或被覆盖,返回召回池' });
      router.push('/plans');
    }
  }, [state, router]);

  // supersede 跳转:刷新/重算后 plan 可能升级出新版本(新 id),老 plan URL 仍能查到
  // 冻结快照 → 会显示陈旧数据。后端在 superseded 时回传 currentPlanId(该患者当前活跃版本),
  // 这里 replace 落到最新版,通吃刷新按钮 / 收藏 / 分享 / 任务抽屉等所有老 URL 入口。
  const redirectTo =
    state.status === 'ready' && state.data.currentPlanId !== planId
      ? state.data.currentPlanId
      : null;
  useEffect(() => {
    if (redirectTo) router.replace(`/plans/${redirectTo}`);
  }, [redirectTo, router]);

  if (state.status === 'loading' || state.status === 'idle') {
    // 有上一份详情 → 垫底显示 + 加载罩(切患者不白闪,体感 SPA);首次进入仍是居中提示
    if (lastAggregateCache) {
      return (
        <div className="relative h-full">
          <div className="pointer-events-none h-full opacity-60">
            <PlanDetailApp data={adaptData(lastAggregateCache.data, dictionary)} onRefreshAggregate={refresh} />
          </div>
          <div className="absolute inset-0 z-10 flex items-center justify-center bg-white/30">
            <div className="flex items-center gap-2 rounded-full bg-white px-3 py-1.5 text-[12px] text-slate-500 shadow-md ring-1 ring-slate-200">
              <span className="h-3.5 w-3.5 animate-spin rounded-full border-2 border-brand-500 border-t-transparent" />
              切换中…
            </div>
          </div>
        </div>
      );
    }
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        加载召回任务详情…
      </div>
    );
  }

  if (state.status === 'error') {
    // PLAN_NOT_FOUND 已 useEffect 跳走,这里只渲染过场骨架(避免一闪而过的 error UI 闪烁)
    if (state.code === ApiCode.PLAN_NOT_FOUND) {
      return (
        <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
          召回任务已不存在,返回召回池…
        </div>
      );
    }
    return (
      <main className="container mx-auto max-w-3xl p-8 space-y-3">
        <Button asChild variant="ghost" size="sm">
          <Link href="/plans">
            <ChevronLeft className="h-4 w-4" /> 返回召回池
          </Link>
        </Button>
        <Card>
          <CardContent className="space-y-3 py-10 text-center">
            <div className="text-lg font-semibold text-rose-600">无法加载 plan</div>
            <div className="text-sm text-muted-foreground">
              planId={planId.slice(0, 8)}… · code={state.code ?? '?'} · {state.message}
            </div>
            <Button variant="outline" size="sm" onClick={refresh}>
              重试
            </Button>
          </CardContent>
        </Card>
      </main>
    );
  }

  // supersede 跳转中:不渲染老版快照,显示过场(避免陈旧数据一闪)
  if (redirectTo) {
    return (
      <div className="flex h-full items-center justify-center text-sm text-muted-foreground">
        该任务已更新,正在跳转到最新版本…
      </div>
    );
  }

  // 直接渲染详情;左侧"选患者"固定栏由 plans/layout.tsx 提供(原 TaskDrawer 抽屉已被其取代)
  return (
    <div className="h-full bg-slate-50">
      <PlanDetailApp data={adaptData(state.data, dictionary)} onRefreshAggregate={refresh} />
    </div>
  );
}
