'use client';

import { useEffect, useState } from 'react';
import { toast } from 'sonner';
import type { MockUser, UserRole } from '@pac/types';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { useAuthStore } from '@/stores/auth-store';
import { getMockUsers, mockLogin } from '@/lib/auth-api';
import { cn } from '@/lib/utils';

/**
 * MockLoginDialog — 试部署 / 演示用快速登录(只在 dev 启用)
 *
 * 主路径(有客服名册时):选「角色(权限)」+「具体客服」→ 以该客服真实身份 + 选定 RBAC 权限登录。
 *   - 客服名册来自 GET /auth/mock-users(派生自回访表 · 近 12 月在岗)。
 *   - 两种 role 解耦:客服是"人 + 职能"(都是一线 staff);这里的角色选择是 PAC **权限视角**(staff/leader/admin)。
 *
 * 降级路径(名册拉不到 / mock 关闭):回退到通用网格(2 brand × 3 role 预制身份),保证永远能登录。
 *
 * 不可关闭(open=true 强制保持):未鉴权用户**必须选一个身份**才能进列表页。
 *
 * 集团模型(2026-06):ruier/ruitai 是**品牌(source_unit)**,同属一个集团租户 `ruier-grp`。
 *   登录发的 slug 仍叫 `tenant`(后端 mock API 历史字段名),后端 MOCK_PRESETS 映射为
 *   { tenantId: 'ruier-grp', sourceUnit: '瑞尔'|'瑞泰', clinics, role }。
 *   正式 SSO 对外契约(host_id + group_id + user + org_scope)待 host 接入时实现。
 */

// 品牌 slug(= source_unit);同属集团 ruier-grp。API 字段名仍叫 tenant(后端契约,未改)。
type BrandSlug = 'ruier' | 'ruitai';

const TENANTS: { slug: BrandSlug; nameZh: string; tone: string }[] = [
  { slug: 'ruier', nameZh: '瑞尔', tone: 'border-teal-200 bg-teal-50/40' },
  { slug: 'ruitai', nameZh: '瑞泰', tone: 'border-sky-200 bg-sky-50/40' },
];

const ROLES: { key: UserRole; nameZh: string; desc: string }[] = [
  { key: 'staff', nameZh: '员工', desc: '执行 / 认领 · 工作台默认只看自己名下' },
  { key: 'leader', nameZh: '主管', desc: '可指派 / 回收 · 能看团队全部任务' },
  { key: 'admin', nameZh: '管理员', desc: '全部功能 · 含后台管理' },
];

// 降级网格的演示人名(需与后端 auth.service.MOCK_NAMES 一致)— 话术自报家门会用到
const MOCK_NAMES: Record<BrandSlug, Record<UserRole, string>> = {
  ruier: { staff: '小王', leader: '李莉', admin: '张敏' },
  ruitai: { staff: '小陈', leader: '周琳', admin: '刘洋' },
};

function roleNameZh(role: UserRole): string {
  return ROLES.find((r) => r.key === role)?.nameZh ?? role;
}

export function MockLoginDialog({ open }: { open: boolean }) {
  const setTokens = useAuthStore((s) => s.setTokens);
  const [busy, setBusy] = useState<string | null>(null);
  const [csUsers, setCsUsers] = useState<MockUser[]>([]);
  const [role, setRole] = useState<UserRole>('staff'); // 登录用的 RBAC 权限(默认员工)
  const [tenantFilter, setTenantFilter] = useState<'all' | BrandSlug>('all');
  const [query, setQuery] = useState('');

  useEffect(() => {
    getMockUsers()
      .then((r) => setCsUsers(r.users))
      .catch(() => {}); // mock 关闭 / 无文件 → 空 → 走降级网格
  }, []);

  const applyTokens = (r: { accessToken: string; refreshToken: string; expiresIn: number }) =>
    setTokens({ accessToken: r.accessToken, refreshToken: r.refreshToken, expiresIn: r.expiresIn });

  // 主路径:以具体客服真实身份 + 选定角色登录
  const pickCs = async (cs: MockUser) => {
    const key = `cs:${cs.tenant}:${cs.externalId}`;
    if (busy) return;
    setBusy(key);
    try {
      const r = await mockLogin({ tenant: cs.tenant, role, userExternalId: cs.externalId });
      applyTokens(r);
      // 登录成功不弹 toast —— applyTokens 后直接进入应用,页面切换本身即反馈
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error('登录失败', { description: msg.slice(0, 120) });
      setBusy(null);
    }
  };

  // 降级路径:通用预制身份(无名册时)= 品牌级(整个 tenant 品牌全部诊所)
  const pickGeneric = async (tenant: BrandSlug, roleKey: UserRole) => {
    const key = `${tenant}:${roleKey}`;
    if (busy) return;
    setBusy(key);
    try {
      const r = await mockLogin({ tenant, role: roleKey });
      applyTokens(r);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error('登录失败', { description: msg.slice(0, 120) });
      setBusy(null);
    }
  };

  // 集团级登录:看全部品牌全部诊所(sourceUnits=[] 不限)— 验证数据权限最上一层
  const pickGroup = async (roleKey: UserRole) => {
    const key = `group:${roleKey}`;
    if (busy) return;
    setBusy(key);
    try {
      const r = await mockLogin({ tenant: 'ruier', role: roleKey, orgLevel: 'group' });
      applyTokens(r);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error('登录失败', { description: msg.slice(0, 120) });
      setBusy(null);
    }
  };

  const q = query.trim();
  const filteredCs = csUsers
    .filter((u) => (tenantFilter === 'all' ? true : u.tenant === tenantFilter))
    .filter((u) => (q ? u.name.includes(q) : true))
    .slice(0, 80);

  return (
    <Dialog open={open}>
      <DialogContent
        onEscapeKeyDown={(e) => e.preventDefault()}
        onPointerDownOutside={(e) => e.preventDefault()}
        className="max-w-2xl [&>button[aria-label='Close']]:hidden"
      >
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <span className="inline-flex h-7 w-7 items-center justify-center rounded-md bg-teal-600 text-[12px] font-bold text-white">
              PAC
            </span>
            <span>快速登录</span>
            <span className="rounded-md bg-amber-100 px-1.5 py-0.5 text-[10.5px] font-medium text-amber-700">
              模拟身份 · 试部署
            </span>
          </DialogTitle>
          <DialogDescription className="text-[12px]">
            生产环境会接宿主 SSO,这里是<strong>开发 / 试部署</strong>的快速通道。
            <br />
            <span className="text-slate-500">
              两件事分开选:<strong>① 角色</strong>=能做什么操作(功能权限);
              <strong>② 选谁 / 哪级</strong>=能看哪些诊所品牌(数据权限,跟角色无关)。
            </span>
          </DialogDescription>
        </DialogHeader>

        {csUsers.length > 0 ? (
          <div className="grid gap-3 pt-1">
            {/* ① 登录权限(角色)*/}
            <div>
              <div className="mb-1.5 text-[12px] font-medium text-slate-600">
                ① 角色 · 能做什么(功能权限)
              </div>
              <div className="grid grid-cols-3 gap-2">
                {ROLES.map((r) => (
                  <button
                    key={r.key}
                    type="button"
                    onClick={() => setRole(r.key)}
                    className={cn(
                      'flex flex-col items-start gap-0.5 rounded-md border px-2.5 py-1.5 text-left transition-all',
                      role === r.key
                        ? 'border-teal-400 bg-teal-50/60 ring-1 ring-teal-200'
                        : 'border-slate-100 hover:border-teal-300',
                    )}
                  >
                    <span className="text-[12.5px] font-semibold text-slate-800">{r.nameZh}</span>
                    <span className="text-[10px] leading-tight text-slate-500">{r.desc}</span>
                  </button>
                ))}
              </div>
              {/* 数据范围·集团级:全部品牌全部诊所(sourceUnits=[] 不限);角色沿用①所选 */}
              <button
                type="button"
                onClick={() => pickGroup(role)}
                disabled={!!busy}
                className="mt-2 w-full rounded-md border border-dashed border-amber-300 bg-amber-50/40 px-2.5 py-1.5 text-left text-[11.5px] text-amber-800 transition-colors hover:border-amber-400 disabled:opacity-50"
              >
                数据范围 · <strong>集团级</strong> —— 看<strong>全部品牌全部诊所</strong>(跨品牌,最上一层)。角色沿用上方「{roleNameZh(role)}」。
              </button>
            </div>

            {/* ② 选客服 */}
            <div className="rounded-lg border border-slate-100 p-3">
              <div className="mb-2 flex items-center justify-between">
                <div className="text-[12px] font-medium text-slate-600">
                  ② 数据范围 · 选客服 = <strong>该客服的诊所</strong>(诊所级)+ 上方「{roleNameZh(role)}」角色
                </div>
                <span className="text-[10.5px] text-slate-500">{csUsers.length} 位在岗 · 近 12 月</span>
              </div>

              <div className="mb-2 flex items-center gap-1.5">
                {([
                  { k: 'all', n: '全部' },
                  { k: 'ruier', n: '瑞尔' },
                  { k: 'ruitai', n: '瑞泰' },
                ] as const).map((t) => (
                  <button
                    key={t.k}
                    type="button"
                    onClick={() => setTenantFilter(t.k)}
                    className={cn(
                      'rounded-full border px-2.5 py-0.5 text-[11px] transition-colors',
                      tenantFilter === t.k
                        ? 'border-teal-400 bg-teal-50 text-teal-700'
                        : 'border-slate-100 text-slate-500 hover:border-teal-300',
                    )}
                  >
                    {t.n}
                  </button>
                ))}
                <input
                  value={query}
                  onChange={(e) => setQuery(e.target.value)}
                  placeholder="搜客服姓名…"
                  className="ml-auto w-40 rounded-md border border-slate-100 px-2.5 py-1 text-[12px] outline-none focus:border-teal-400"
                />
              </div>

              <div className="max-h-56 space-y-1 overflow-y-auto pr-0.5">
                {filteredCs.map((cs) => {
                  const key = `cs:${cs.tenant}:${cs.externalId}`;
                  const loading = busy === key;
                  const tName = cs.tenant === 'ruier' ? '瑞尔' : '瑞泰';
                  const clinics = cs.clinics.map((c) => c.name).join(' / ');
                  return (
                    <button
                      key={key}
                      type="button"
                      disabled={!!busy}
                      onClick={() => pickCs(cs)}
                      className={cn(
                        'flex w-full items-center justify-between gap-2 rounded-md border px-2.5 py-1.5 text-left transition-all',
                        loading
                          ? 'border-teal-400 ring-2 ring-teal-200'
                          : 'border-slate-100 hover:border-teal-400 hover:bg-teal-50/40',
                        busy && !loading && 'opacity-50',
                      )}
                    >
                      <span className="flex shrink-0 items-center gap-1.5">
                        <span className="text-[12.5px] font-semibold text-slate-800">
                          {loading ? '登录中…' : cs.name}
                        </span>
                        <span className="text-[10.5px] text-slate-500">{tName}</span>
                      </span>
                      <span className="truncate text-[10.5px] text-slate-400">{clinics}</span>
                    </button>
                  );
                })}
                {filteredCs.length === 0 && (
                  <div className="px-1 py-2 text-[11px] text-slate-400">无匹配客服</div>
                )}
              </div>
            </div>
          </div>
        ) : (
          // 降级:无客服名册 → 通用网格(保证可登录)
          <div className="grid gap-3 pt-2">
            {TENANTS.map((t) => (
              <div key={t.slug} className={cn('rounded-lg border p-3', t.tone)}>
                <div className="mb-2 flex items-center gap-2 text-[13px] font-semibold text-slate-800">
                  <span>{t.nameZh}</span>
                  <span className="text-[10.5px] font-normal text-slate-500">
                    {t.slug === 'ruier'
                      ? '3 家诊所(杭州大厦/高德 · 北京朝阳)'
                      : '2 家诊所(通善学前街 · 上海世纪公园)'}
                  </span>
                </div>
                <div className="grid gap-2 sm:grid-cols-3">
                  {ROLES.map((r) => {
                    const key = `${t.slug}:${r.key}`;
                    const loading = busy === key;
                    return (
                      <button
                        key={key}
                        type="button"
                        onClick={() => pickGeneric(t.slug, r.key)}
                        disabled={!!busy}
                        className={cn(
                          'group flex flex-col items-start gap-1 rounded-md border bg-white px-3 py-2 text-left transition-all',
                          loading
                            ? 'border-teal-400 ring-2 ring-teal-200'
                            : 'border-slate-100 hover:border-teal-400 hover:bg-teal-50/40',
                          busy && !loading && 'opacity-50',
                        )}
                      >
                        <div className="text-[12.5px] font-semibold text-slate-800">
                          {loading ? '登录中…' : `${r.nameZh} · ${MOCK_NAMES[t.slug][r.key]}`}
                        </div>
                        <div className="text-[10.5px] leading-tight text-slate-500">{r.desc}</div>
                      </button>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>
        )}

        <p className="pt-1 text-[10.5px] leading-relaxed text-slate-400">
          提示:登录后 token 写入浏览器 localStorage(2h 有效 · 自动 refresh),
          清浏览器数据或换浏览器会重新弹此对话框。
        </p>
      </DialogContent>
    </Dialog>
  );
}
