/**
 * 用户审核页 — 申请列表 + 审核操作 Modal。
 *
 * - 申请列表：Ant Design Table，支持状态筛选 + 店铺筛选 + 分页
 * - 审核 Modal：角色动态下拉 + 人员联动查询 + 手机号自动匹配 + "无"选项
 * - 数据源：tenantApi GET /applications, GET /roles, GET /site-staff, GET /my-sites
 * - 操作：POST /applications/{id}/approve, POST /applications/{id}/reject
 * - 非 pending 状态不显示审核按钮
 *
 * AI_CHANGELOG
 * - 2026-03-23 17:00:00 | Prompt: P20260323-164500（审核弹窗改造）| Direct cause：角色硬编码+无人员联动 | Summary：ReviewModal 角色下拉动态化（GET /roles）、人员列表联动（GET /site-staff）、手机号自动匹配、"无"选项、staffBinding 格式 source:id、修复中文引号+filterOption 类型 | Verify：tenant-admin 审核弹窗功能完整 + Vite HMR 无报错
 * - 2026-03-23 19:30:00 | Prompt: P20260323-190000（手机号不显示+自动匹配优化）| Direct cause：弹窗手机号显示 `-`；身份标签显示数字 | Summary：弹窗打开时并行查 coach/staff 自动匹配手机号→自动选角色+人员；staffOptions label 加"入职日期"前缀 | Verify：Playwright 验证自动选中"员工"+"店长 - 厉超 - 13810502304 - 入职日期 2025-12-23"
 * - 2026-03-24 | Prompt: 审核弹窗头像昵称+排版优化 | Direct cause：信息区纯文本平铺，无头像展示 | Summary：新增 avatarUrl 字段（后端 SQL+Schema+前端 interface）；信息区改为 Avatar+Descriptions 卡片布局 | Verify：审核弹窗显示头像+信息分行
 */

import React, { useState, useEffect, useCallback } from "react";
import { Table, Select, Button, Modal, Form, Input, Radio, Space, Tag, message, Avatar, Descriptions } from "antd";
import type { ColumnsType, TablePaginationConfig } from "antd/es/table";
import { UserOutlined } from "@ant-design/icons";
import { tenantApi } from "@/services/api";
import type { AxiosError } from "axios";
import { pinyinFilterOption } from "@/utils/pinyinMatch";

/* ------------------------------------------------------------------ */
/*  类型定义                                                           */
/* ------------------------------------------------------------------ */

interface ApplicationItem {
  id: number;
  userId: number;
  nickname: string | null;
  avatarUrl: string | null;
  phone: string | null;
  siteCode: string | null;
  appliedRoleText: string | null;
  employeeNumber: string | null;
  createdAt: string | null;
  status: string;
}

interface MatchSuggestion {
  assistantId: number | null;
  staffId: number | null;
  name: string;
  number: string | null;
  sourceTable: string;
}

interface RoleOption {
  id: number;
  code: string;
  name: string;
  description: string | null;
}

interface StaffCandidate {
  id: number;
  identityLabel: string | null;
  name: string;
  mobile: string | null;
  entryTime: string | null;
  source: string; // "assistant" | "staff"
}

interface SiteOption {
  siteId: number;
  siteName: string;
  siteCode: string | null;
}

interface PaginatedResponse<T> {
  items: T[];
  total: number;
  page: number;
  pageSize: number;
}

/* ------------------------------------------------------------------ */
/*  状态筛选选项                                                       */
/* ------------------------------------------------------------------ */

const STATUS_OPTIONS = [
  { label: "全部", value: "" },
  { label: "待审核", value: "pending" },
  { label: "已通过", value: "approved" },
  { label: "已拒绝", value: "rejected" },
];

const STATUS_TAG_MAP: Record<string, { color: string; text: string }> = {
  pending: { color: "orange", text: "待审核" },
  approved: { color: "green", text: "已通过" },
  rejected: { color: "red", text: "已拒绝" },
};


/* ------------------------------------------------------------------ */
/*  审核 Modal 组件                                                    */
/* ------------------------------------------------------------------ */

interface ReviewModalProps {
  open: boolean;
  application: ApplicationItem | null;
  onClose: () => void;
  onSuccess: () => void;
}

const ReviewModal: React.FC<ReviewModalProps> = ({ open, application, onClose, onSuccess }) => {
  const [, setSuggestions] = useState<MatchSuggestion[]>([]);
  const [, setLoadingSuggestions] = useState(false);
  const [action, setAction] = useState<"approve" | "reject">("approve");
  const [submitting, setSubmitting] = useState(false);
  const [approveForm] = Form.useForm();
  const [rejectForm] = Form.useForm();

  // 动态角色列表
  const [roles, setRoles] = useState<RoleOption[]>([]);
  const [loadingRoles, setLoadingRoles] = useState(false);

  // 人员候选列表
  const [staffCandidates, setStaffCandidates] = useState<StaffCandidate[]>([]);
  const [loadingStaff, setLoadingStaff] = useState(false);

  // [CHANGE P20260323-164500] intent: 角色下拉从 /api/tenant/roles 动态获取，不硬编码
  // 加载角色列表（打开弹窗时）
  useEffect(() => {
    if (!open) return;
    setLoadingRoles(true);
    tenantApi
      .get<RoleOption[]>("/roles")
      .then((res) => setRoles(res.data))
      .catch(() => setRoles([]))
      .finally(() => setLoadingRoles(false));
  }, [open]);

  // 打开时重置状态 + 自动匹配手机号
  useEffect(() => {
    if (!open || !application) {
      setSuggestions([]);
      setStaffCandidates([]);
      setAction("approve");
      approveForm.resetFields();
      rejectForm.resetFields();
      return;
    }
    // 仍然加载旧的 match-suggestions（兼容）
    setLoadingSuggestions(true);
    tenantApi
      .get<MatchSuggestion[]>(`/applications/${application.id}/match-suggestions`)
      .then((res) => setSuggestions(res.data))
      .catch(() => setSuggestions([]))
      .finally(() => setLoadingSuggestions(false));

    // 自动匹配：如果有手机号和球房编号，并行查 coach 和 staff 人员列表
    if (application.phone && application.siteCode && roles.length > 0) {
      setLoadingStaff(true);
      const coachReq = tenantApi
        .get<StaffCandidate[]>("/site-staff", {
          params: { role: "coach", site_code: application.siteCode },
        })
        .catch(() => ({ data: [] as StaffCandidate[] }));
      const staffReq = tenantApi
        .get<StaffCandidate[]>("/site-staff", {
          params: { role: "staff", site_code: application.siteCode },
        })
        .catch(() => ({ data: [] as StaffCandidate[] }));

      Promise.all([coachReq, staffReq])
        .then(([coachRes, staffRes]) => {
          const phone = application.phone!;
          // 优先匹配助教表
          const coachMatch = coachRes.data.find((c) => c.mobile === phone);
          if (coachMatch) {
            setStaffCandidates(coachRes.data);
            approveForm.setFieldsValue({
              role: "coach",
              staffBinding: `${coachMatch.source}:${coachMatch.id}`,
            });
            return;
          }
          // 其次匹配员工表
          const staffMatch = staffRes.data.find((c) => c.mobile === phone);
          if (staffMatch) {
            setStaffCandidates(staffRes.data);
            approveForm.setFieldsValue({
              role: "staff",
              staffBinding: `${staffMatch.source}:${staffMatch.id}`,
            });
            return;
          }
          // 都没匹配到，不自动选择
        })
        .finally(() => setLoadingStaff(false));
    }
  }, [open, application, approveForm, rejectForm, roles]);

  // [CHANGE P20260323-164500] intent: 角色变化时联动查询人员列表（coach→助教表，其他→员工表）
  // assumptions: staffBinding 格式 "source:id"（如 "assistant:123"）或 "none"
  // 角色变化时查询人员列表
  const handleRoleChange = useCallback(
    (roleCode: string) => {
      if (!application?.siteCode) {
        setStaffCandidates([]);
        approveForm.setFieldValue("staffBinding", "none");
        return;
      }

      setLoadingStaff(true);
      setStaffCandidates([]);
      approveForm.setFieldValue("staffBinding", undefined);

      tenantApi
        .get<StaffCandidate[]>("/site-staff", {
          params: { role: roleCode, site_code: application.siteCode },
        })
        .then((res) => {
          const candidates = res.data;
          setStaffCandidates(candidates);

          // 自动匹配：如果有人的手机号与申请者一致，自动选中
          if (application.phone) {
            const matchIdx = candidates.findIndex(
              (c) => c.mobile === application.phone
            );
            if (matchIdx >= 0) {
              const matched = candidates[matchIdx];
              approveForm.setFieldValue(
                "staffBinding",
                `${matched.source}:${matched.id}`
              );
            } else {
              approveForm.setFieldValue("staffBinding", "none");
            }
          } else {
            approveForm.setFieldValue("staffBinding", "none");
          }
        })
        .catch(() => {
          setStaffCandidates([]);
          approveForm.setFieldValue("staffBinding", "none");
        })
        .finally(() => setLoadingStaff(false));
    },
    [application, approveForm]
  );

  const handleApprove = async () => {
    if (!application) return;
    try {
      const values = await approveForm.validateFields();
      setSubmitting(true);

      // 从 staffBinding 解析 assistantId / staffId
      let assistantId: number | undefined;
      let staffId: number | undefined;
      if (values.staffBinding && values.staffBinding !== "none") {
        const [source, idStr] = values.staffBinding.split(":");
        const id = parseInt(idStr, 10);
        if (source === "assistant") {
          assistantId = id;
        } else {
          staffId = id;
        }
      }

      await tenantApi.post(`/applications/${application.id}/approve`, {
        role: values.role,
        assistantId,
        staffId,
      });
      message.success("审核通过成功");
      onSuccess();
    } catch (err) {
      const axiosErr = err as AxiosError<{ message?: string }>;
      if (axiosErr.response?.status === 409) {
        message.error("该申请已被处理");
      } else if (axiosErr.response?.data?.message) {
        message.error(axiosErr.response.data.message);
      }
    } finally {
      setSubmitting(false);
    }
  };

  const handleReject = async () => {
    if (!application) return;
    try {
      const values = await rejectForm.validateFields();
      setSubmitting(true);
      await tenantApi.post(`/applications/${application.id}/reject`, {
        reason: values.reason,
      });
      message.success("已拒绝该申请");
      onSuccess();
    } catch (err) {
      const axiosErr = err as AxiosError<{ message?: string }>;
      if (axiosErr.response?.status === 409) {
        message.error("该申请已被处理");
      } else if (axiosErr.response?.data?.message) {
        message.error(axiosErr.response.data.message);
      }
    } finally {
      setSubmitting(false);
    }
  };

  const handleOk = () => {
    if (action === "approve") {
      handleApprove();
    } else {
      handleReject();
    }
  };

  // 人员下拉选项：格式 "身份/等级 - 姓名 - 手机号 - 入职日期 YYYY-MM-DD"
  const staffOptions = [
    { label: "无（不关联）", value: "none" },
    ...staffCandidates.map((c) => {
      const parts = [
        c.identityLabel ?? "-",
        c.name,
        c.mobile ?? "-",
        c.entryTime ? `入职日期 ${c.entryTime.slice(0, 10)}` : "-",
      ];
      return {
        label: parts.join(" - "),
        value: `${c.source}:${c.id}`,
      };
    }),
  ];

  return (
    <Modal
      title={`审核申请 — ${application?.nickname ?? "未知用户"}`}
      open={open}
      onCancel={onClose}
      onOk={handleOk}
      confirmLoading={submitting}
      okText={action === "approve" ? "通过" : "拒绝"}
      okButtonProps={{ danger: action === "reject" }}
      destroyOnClose
      width={560}
    >
      <div style={{ display: "flex", gap: 16, marginBottom: 20 }}>
        <Avatar
          size={64}
          icon={<UserOutlined />}
          src={
            application?.avatarUrl
              ? `/api/xcx/avatar/${application.userId}`
              : undefined
          }
          style={
            application?.avatarUrl
              ? undefined
              : { backgroundColor: "#e8e8e8", color: "#999" }
          }
        />
        <Descriptions column={1} size="small" style={{ flex: 1 }}>
          <Descriptions.Item label="昵称">
            {application?.nickname ?? "-"}
          </Descriptions.Item>
          <Descriptions.Item label="手机号">
            {application?.phone ?? "-"}
          </Descriptions.Item>
          <Descriptions.Item label="球房编号">
            {application?.siteCode ?? "-"}
          </Descriptions.Item>
          <Descriptions.Item label="申请角色">
            {application?.appliedRoleText ?? "-"}
          </Descriptions.Item>
          <Descriptions.Item label="员工编号">
            {application?.employeeNumber ?? "-"}
          </Descriptions.Item>
        </Descriptions>
      </div>

      <Radio.Group
        value={action}
        onChange={(e) => setAction(e.target.value)}
        style={{ marginBottom: 16 }}
      >
        <Radio.Button value="approve">通过</Radio.Button>
        <Radio.Button value="reject">拒绝</Radio.Button>
      </Radio.Group>

      {action === "approve" ? (
        <Form form={approveForm} layout="vertical">
          <Form.Item
            name="role"
            label="分配角色"
            rules={[{ required: true, message: "请选择角色" }]}
          >
            <Select
              placeholder={loadingRoles ? "加载中..." : "选择角色"}
              loading={loadingRoles}
              disabled={loadingRoles || loadingStaff}
              onChange={handleRoleChange}
              options={roles.map((r) => ({
                label: r.name,
                value: r.code,
              }))}
            />
          </Form.Item>
          <Form.Item
            name="staffBinding"
            label="关联助教/员工"
            rules={[{ required: true, message: '请选择关联人员（或选择"无"）' }]}
          >
            <Select
              placeholder={loadingStaff ? "加载中..." : "请先选择角色"}
              loading={loadingStaff}
              disabled={loadingRoles || loadingStaff}
              options={staffOptions}
              showSearch
              filterOption={pinyinFilterOption}
              notFoundContent={loadingStaff ? "加载中..." : "无匹配人员"}
            />
          </Form.Item>
        </Form>
      ) : (
        <Form form={rejectForm} layout="vertical">
          <Form.Item
            name="reason"
            label="拒绝原因"
            rules={[{ required: true, message: "请填写拒绝原因" }]}
          >
            <Input.TextArea rows={3} placeholder="请输入拒绝原因" maxLength={500} showCount />
          </Form.Item>
        </Form>
      )}
    </Modal>
  );
};

/* ------------------------------------------------------------------ */
/*  主页面组件                                                         */
/* ------------------------------------------------------------------ */

const UserApproval: React.FC = () => {
  const [data, setData] = useState<ApplicationItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [statusFilter, setStatusFilter] = useState("");
  const [siteFilter, setSiteFilter] = useState<number | undefined>(undefined);
  const [sites, setSites] = useState<SiteOption[]>([]);
  const [loading, setLoading] = useState(false);

  // 审核 Modal 状态
  const [reviewOpen, setReviewOpen] = useState(false);
  const [reviewApp, setReviewApp] = useState<ApplicationItem | null>(null);

  // 加载管辖店铺列表
  useEffect(() => {
    tenantApi
      .get<SiteOption[]>("/my-sites")
      .then((res) => setSites(res.data))
      .catch(() => {});
  }, []);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string | number> = { page, page_size: pageSize };
      if (statusFilter) params.status = statusFilter;
      if (siteFilter !== undefined) params.site_id = siteFilter;

      const res = await tenantApi.get<PaginatedResponse<ApplicationItem>>("/applications", {
        params,
      });
      setData(res.data.items);
      setTotal(res.data.total);
    } catch {
      message.error("获取申请列表失败");
    } finally {
      setLoading(false);
    }
  }, [page, pageSize, statusFilter, siteFilter]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const handleTableChange = (pagination: TablePaginationConfig) => {
    setPage(pagination.current ?? 1);
    setPageSize(pagination.pageSize ?? 20);
  };

  const openReview = (record: ApplicationItem) => {
    setReviewApp(record);
    setReviewOpen(true);
  };

  const handleReviewSuccess = () => {
    setReviewOpen(false);
    setReviewApp(null);
    fetchData();
  };

  const columns: ColumnsType<ApplicationItem> = [
    { title: "昵称", dataIndex: "nickname", key: "nickname", render: (v) => v ?? "-" },
    { title: "手机号", dataIndex: "phone", key: "phone", render: (v) => v ?? "-" },
    { title: "球房编号", dataIndex: "siteCode", key: "siteCode", render: (v) => v ?? "-" },
    { title: "申请角色", dataIndex: "appliedRoleText", key: "appliedRoleText", render: (v) => v ?? "-" },
    { title: "员工编号", dataIndex: "employeeNumber", key: "employeeNumber", render: (v) => v ?? "-" },
    { title: "申请时间", dataIndex: "createdAt", key: "createdAt", render: (v) => v ?? "-" },
    {
      title: "状态",
      dataIndex: "status",
      key: "status",
      render: (status: string) => {
        const tag = STATUS_TAG_MAP[status];
        return tag ? <Tag color={tag.color}>{tag.text}</Tag> : status;
      },
    },
    {
      title: "操作",
      key: "action",
      render: (_, record) =>
        record.status === "pending" ? (
          <Button type="link" onClick={() => openReview(record)}>
            审核
          </Button>
        ) : null,
    },
  ];

  return (
    <div>
      <div style={{ marginBottom: 16, display: "flex", alignItems: "center", gap: 12 }}>
        <span>状态筛选：</span>
        <Select
          value={statusFilter}
          onChange={(v) => {
            setStatusFilter(v);
            setPage(1);
          }}
          options={STATUS_OPTIONS}
          style={{ width: 140 }}
        />
        <span>店铺筛选：</span>
        <Select
          value={siteFilter}
          onChange={(v) => {
            setSiteFilter(v);
            setPage(1);
          }}
          allowClear
          placeholder="全部店铺"
          style={{ width: 200 }}
          options={sites.map((s) => ({
            label: `${s.siteName}${s.siteCode ? ` (${s.siteCode})` : ""}`,
            value: s.siteId,
          }))}
        />
      </div>

      <Table<ApplicationItem>
        rowKey="id"
        columns={columns}
        dataSource={data}
        loading={loading}
        pagination={{
          current: page,
          pageSize,
          total,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 条`,
        }}
        onChange={handleTableChange}
      />

      <ReviewModal
        open={reviewOpen}
        application={reviewApp}
        onClose={() => {
          setReviewOpen(false);
          setReviewApp(null);
        }}
        onSuccess={handleReviewSuccess}
      />
    </div>
  );
};

export default UserApproval;
