'use client';

import { useState } from 'react';
import { Permission } from '@pac/types';
import { cn } from '@/lib/utils';
import { useHasPermission } from '@/hooks/use-permission';
import { usePlanSyncStore } from '@/stores/plan-sync-store';
import { AssistantFab } from './assistant-fab';
import { AssistantChat } from './assistant-chat';

/**
 * AssistantWidget — 详情页右下角吸附助手(与 /assistant 同一能力,复用 AssistantChat)。
 *
 * 收起 = 右下角圆形悬浮钮;展开 = 400×~75vh 吸附小窗。
 * 关键:收起用 CSS 隐藏而非卸载 → 对话/工具步骤/听写状态全保留;
 * 挂在 plans/layout(路由段之上)→ 切患者对话也不丢。
 * 权限同 /assistant 页(AGENT_INVOKE),无权限不渲染。
 */
export function AssistantWidget() {
  const allowed = useHasPermission(Permission.AGENT_INVOKE);
  const [open, setOpen] = useState(false);
  const [maximized, setMaximized] = useState(false); // 最大化:居中放大窗
  // 窗口落点 + 尺寸:打开瞬间按"钮的当前位置"计算(拖钮的意义所在),并夹紧在视窗内
  const [winRect, setWinRect] = useState<{ x: number; y: number; w: number; h: number } | null>(null);

  const openAt = (fab: DOMRect) => {
    const W = Math.min(400, window.innerWidth - 16);
    const H = Math.min(620, Math.round(window.innerHeight * 0.78));
    // 水平:钮在屏幕右半 → 窗口右缘对齐钮右缘;左半 → 左缘对齐
    let x = fab.left + fab.width / 2 > window.innerWidth / 2 ? fab.right - W : fab.left;
    // 垂直:优先弹在钮上方,放不下弹下方
    let y = fab.top - H - 8;
    if (y < 8) y = fab.bottom + 8;
    x = Math.min(Math.max(x, 8), window.innerWidth - W - 8);
    y = Math.min(Math.max(y, 8), window.innerHeight - H - 8);
    setWinRect({ x, y, w: W, h: H });
    setOpen(true);
  };
  // 场景化开场建议(规则,非 AI):有当前患者 → 围绕该患者;否则兜底通用
  const current = usePlanSyncStore((s) => s.current);
  const examples = current?.patientName
    ? [
        `${current.patientName}为什么被召回?帮我捋一下关键事实`,
        `查一下${current.patientName}的画像和潜在治疗`,
        `这通电话怎么开口比较好?给我两句开场`,
        '今日推荐:挑几个该优先跟进的患者,并说明理由',
      ]
    : ['今日推荐:挑几个该优先跟进的患者,并说明理由', '现在召回池里优先级最高的是谁?'];

  if (!allowed) return null;

  return (
    <>
      {/* 吸附窗:常驻挂载,关着时 invisible(状态不丢) */}
      <div
        style={maximized ? undefined : winRect ? { left: winRect.x, top: winRect.y } : undefined}
        className={cn(
          'fixed z-[60] flex flex-col overflow-hidden rounded-xl border border-slate-100 shadow-2xl',
          'transition-[opacity,transform] duration-150',
          maximized
            ? 'inset-3' // 最大化:填满窗口(留 12px 边距),不写死宽高,随窗口自适应
            : cn(!winRect && 'bottom-4 right-4', 'h-[620px] max-h-[78vh] w-[400px] max-w-[calc(100vw-2rem)]'),
          open ? 'translate-y-0 opacity-100' : 'pointer-events-none invisible translate-y-2 opacity-0',
        )}
      >
        <AssistantChat
          variant="widget"
          onClose={() => {
            setOpen(false);
            setMaximized(false); // 收起时还原尺寸,下次打开仍是小窗
          }}
          onToggleMaximize={() => setMaximized((m) => !m)}
          maximized={maximized}
          examples={examples}
        />
      </div>
      {/* 助手入口(静态版):固定右下角,点击开/关助手窗;只在 AI 思考/说话、成约、切患者时原地反馈。
          完整桌宠(漫游/物理/狩猎)保留在 /pet-lab 演示页,不进工作区(老板反馈"做得太过")。 */}
      <AssistantFab open={open} onToggle={(r) => (open ? setOpen(false) : openAt(r))} />
    </>
  );
}
