'use client';

import { useState } from 'react';
import { Loader2 } from 'lucide-react';
import { RELEASE_REASON_META, releaseReasonsForForm, type ReleaseReason } from '@pac/types';
import {
  AlertDialog,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib/utils';

/**
 * 退回原因弹窗 —— 客服点「退回」时必须选一个原因(T7)。
 *
 * ═══ 为什么这个弹窗必须存在 ═══════════════════════════════════
 * T7:「退回是**正常路径**不是异常。退回率与原因分布是**主管调整分配策略的输入** ——
 * 这是『必须填原因』的目的,不要当成无谓摩擦砍掉。」
 *
 * 🔴 2026-08-03 走查发现:**这个弹窗此前根本不存在**。
 *   `plansApi.recycle` 早就支持传 releaseReason、枚举齐了、聚合报表(releaseReasons 分布)
 *   也写了 —— 唯一的调用点却是 `plansApi.recycle(planId)`,一个参数都不传。
 *   于是那张分布报表永远拿到 null:主管只知道"退了 12 条",不知道该改什么
 *   (是派多了?时限太紧?还是压根不该派给他?)—— 而这三种的下一步动作完全不同。
 *
 * ⚠️ 每个原因都带一句 `desc`:「不是我的客户」和「该由其他角色跟」光看标题分不出,
 *   分不出就会随手点第一个,那比不填还糟(假数据比没数据难发现)。
 * ⚠️ `other` 必须写说明 —— 服务端也拦(见 plan.service.recycle),
 *   ⛔ 这类必填只做前端等于没做:换个客户端就绕过去了。
 */
export function ReleaseReasonDialog({
  open,
  patientName,
  submitting,
  onCancel,
  onConfirm,
}: {
  open: boolean;
  /** 弹窗标题里点名是谁,避免连点几行后不知道正在退哪一个 */
  patientName: string;
  submitting?: boolean;
  onCancel: () => void;
  onConfirm: (reason: ReleaseReason, note?: string) => void;
}) {
  const [reason, setReason] = useState<ReleaseReason | null>(null);
  const [note, setNote] = useState('');

  const needNote = reason != null && RELEASE_REASON_META[reason].needNote === true;
  const canSubmit = reason != null && (!needNote || note.trim().length > 0) && !submitting;

  const close = () => {
    setReason(null);
    setNote('');
    onCancel();
  };

  return (
    <AlertDialog open={open} onOpenChange={(o) => !o && close()}>
      <AlertDialogContent className="max-w-md">
        <AlertDialogHeader>
          <AlertDialogTitle className="text-[15px]">
            退回「{patientName || '这位患者'}」
          </AlertDialogTitle>
        </AlertDialogHeader>

        <div className="max-h-[46vh] space-y-1 overflow-y-auto py-1">
          {/*
            ⚠️ 走 releaseReasonsForForm() 而不是 Object.keys —— META 里留着 5 个**历史值**
              (不是我的客户 / 这段时间不在 / 时限太紧 / 最近刚联系过 / 其他),
              它们只为翻译库里的老数据而存在,⛔ 不能出现在选项里。
              直接 Object.keys 会把它们一起渲染出来,而且不报错。
          */}
          {releaseReasonsForForm().map((r) => {
            const m = RELEASE_REASON_META[r];
            const on = reason === r;
            return (
              <button
                key={r}
                type="button"
                onClick={() => setReason(r)}
                className={cn(
                  'flex w-full flex-col items-start gap-0.5 rounded-md border px-2.5 py-1.5 text-left transition-colors',
                  on
                    ? 'border-brand-400 bg-brand-50/70'
                    : 'bg-white hover:border-brand-200 hover:bg-brand-50/30',
                )}
              >
                <span
                  className={cn(
                    'text-[13px]',
                    on ? 'font-medium text-brand-800' : 'text-slate-700',
                  )}
                >
                  {m.labelZh}
                </span>
                {/* ⚠️ desc 不能省:「不是我的客户」vs「该由其他角色跟」光看标题分不出,
                    分不出就会随手点第一个 —— 假数据比没数据难发现 */}
                <span className="text-[11px] leading-snug text-slate-400">{m.desc}</span>
              </button>
            );
          })}
        </div>

        {needNote && (
          <div className="space-y-1">
            <textarea
              autoFocus
              rows={2}
              value={note}
              onChange={(e) => setNote(e.target.value)}
              placeholder="写清楚具体情况(必填)"
              className="w-full resize-none rounded-md border px-2 py-1.5 text-[12.5px] outline-none placeholder:text-slate-300 focus:border-brand-400"
            />
          </div>
        )}

        <AlertDialogFooter>
          <AlertDialogCancel disabled={submitting}>取消</AlertDialogCancel>
          <Button
            disabled={!canSubmit}
            onClick={() => reason && onConfirm(reason, note.trim() || undefined)}
            className="gap-1.5"
          >
            {submitting && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
            确认退回
          </Button>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}
