'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 强制保持):未鉴权用户**必须选一个身份**才能进列表页。
 */

type TenantSlug = 'ruier' | 'ruitai';

const TENANTS: { slug: TenantSlug; 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<TenantSlug, 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' | TenantSlug>('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);
      const tName = cs.tenant === 'ruier' ? '瑞尔' : '瑞泰';
      toast.success(`已登录:${cs.name} · ${tName} · ${roleNameZh(role)}`, {
        description: cs.clinics.map((c) => c.name).join(' / ') || '(模拟身份)',
      });
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      toast.error('登录失败', { description: msg.slice(0, 120) });
      setBusy(null);
    }
  };

  // 降级路径:通用预制身份(无名册时)
  const pickGeneric = async (tenant: TenantSlug, roleKey: UserRole) => {
    const key = `${tenant}:${roleKey}`;
    if (busy) return;
    setBusy(key);
    try {
      const r = await mockLogin({ tenant, role: roleKey });
      applyTokens(r);
      const tName = TENANTS.find((t) => t.slug === tenant)?.nameZh ?? tenant;
      toast.success(`已登录:${tName} · ${roleNameZh(roleKey)}`, {
        description: '(模拟身份,真生产环境会接宿主 SSO)',
      });
    } 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>的快速通道。请选一个身份进入工作台:
          </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-200 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>
            </div>

            {/* ② 选客服 */}
            <div className="rounded-lg border border-slate-200 p-3">
              <div className="mb-2 flex items-center justify-between">
                <div className="text-[12px] font-medium text-slate-600">
                  ② 选客服 — 以其真实身份 + 上面的「{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-200 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-200 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-200 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-200 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>
  );
}
