/**
 * 用户管理页 — 用户列表 + 编辑/绑定合并 Modal。
 *
 * - 用户列表：Ant Design Table，支持角色筛选 + 关键词搜索 + 分页
 * - 编辑 Modal：角色动态下拉 + 人员联动查询 + 拼音搜索 + "无"选项 + 门店选择
 *   （复用审核弹窗的交互模式，角色与绑定互斥，换角色自动清除旧绑定）
 * - 移除用户时二次确认（Modal.confirm）
 * - 数据源：tenantApi GET /users, GET /roles, GET /site-staff, GET /my-sites
 * - 操作：PATCH /users/{id}（角色+门店+绑定合并提交）
 *
 * AI_CHANGELOG
 * - 2026-03-24 | Prompt: 用户管理绑定功能改造 | Direct cause：EditModal+BindModal 分离，BindModal 手动输入 ID 体验差 | Summary：合并为单一弹窗，复用审核弹窗交互模式（角色动态下拉→人员联动→拼音搜索→"无"选项），PATCH 接口同时提交角色+绑定 | Verify：编辑弹窗角色联动人员列表 + 拼音搜索 + 解绑 + 换角色清除旧绑定
 */

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

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

interface UserItem {
  id: number;
  nickname: string | null;
  role: string | null;  // 中文名（显示用）
  roleCode: string | null;  // code（提交用）
  assistantId: number | null;  // 当前绑定的助教 ID
  staffId: number | null;  // 当前绑定的员工 ID
  assistantName: string | null;
  siteName: string | null;
  siteId: number | null;
  status: string; // approved / disabled
}

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

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

interface SiteOption {
  siteId: number;
  siteName: string;
}

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

/* ------------------------------------------------------------------ */
/*  常量                                                               */
/* ------------------------------------------------------------------ */

const ROLE_LABEL: Record<string, string> = {
  coach: "助教",
  staff: "员工",
  head_coach: "教练",
  manager: "管理人员",
};

/* ------------------------------------------------------------------ */
/*  编辑/绑定合并 Modal                                                */
/* ------------------------------------------------------------------ */
// [CHANGE P20260324] intent: 合并 EditModal + BindModal，复用审核弹窗的角色联动+人员下拉交互
// assumptions: 角色与绑定互斥（coach→助教，其他→员工）；换角色自动清除旧绑定
// verify: 编辑弹窗角色联动人员列表 + 拼音搜索 + 解绑 + 换角色清除旧绑定

interface EditBindModalProps {
  open: boolean;
  user: UserItem | null;
  sites: SiteOption[];
  roles: RoleOption[];
  onClose: () => void;
  onSuccess: () => void;
}

const EditBindModal: React.FC<EditBindModalProps> = ({
  open, user, sites, roles, onClose, onSuccess,
}) => {
  const [form] = Form.useForm();
  const [submitting, setSubmitting] = useState(false);
  const [staffCandidates, setStaffCandidates] = useState<StaffCandidate[]>([]);
  const [loadingStaff, setLoadingStaff] = useState(false);

  // 打开弹窗时初始化表单 + 加载当前角色对应的人员列表
  useEffect(() => {
    if (!open || !user) {
      setStaffCandidates([]);
      return;
    }
    form.setFieldsValue({
      role: user.roleCode ?? undefined,
      siteId: user.siteId ?? undefined,
      staffBinding: "none",
    });

    // 如果用户已有角色和门店，加载对应人员列表并回显当前绑定
    if (user.roleCode && user.siteId) {
      loadStaffForRole(user.roleCode, user.siteId).then(() => {
        // 回显当前绑定状态
        if (user.assistantId) {
          form.setFieldValue("staffBinding", `assistant:${user.assistantId}`);
        } else if (user.staffId) {
          form.setFieldValue("staffBinding", `staff:${user.staffId}`);
        }
      });
    }
  }, [open, user, form]);

  // 按角色+门店查询人员候选列表
  const loadStaffForRole = useCallback((roleCode: string, siteId: number): Promise<void> => {
    setLoadingStaff(true);
    setStaffCandidates([]);

    return tenantApi
      .get<StaffCandidate[]>("/site-staff", {
        params: { role: roleCode, site_id: siteId },
      })
      .then((res) => setStaffCandidates(res.data))
      .catch(() => setStaffCandidates([]))
      .finally(() => setLoadingStaff(false));
  }, []);

  // 角色变化时联动查询人员列表
  const handleRoleChange = useCallback(
    (roleCode: string) => {
      // 清除旧绑定
      form.setFieldValue("staffBinding", "none");
      setStaffCandidates([]);

      const siteId = form.getFieldValue("siteId");
      if (!siteId) return;

      loadStaffForRole(roleCode, siteId);
    },
    [form, loadStaffForRole],
  );

  // 门店变化时也需要重新加载人员列表
  const handleSiteChange = useCallback(
    (siteId: number) => {
      form.setFieldValue("staffBinding", "none");
      setStaffCandidates([]);

      const roleCode = form.getFieldValue("role");
      if (!roleCode) return;

      loadStaffForRole(roleCode, siteId);
    },
    [form, loadStaffForRole],
  );

  const handleOk = async () => {
    if (!user) return;
    try {
      const values = await form.validateFields();
      setSubmitting(true);

      // 从 staffBinding 解析 assistantId / staffId
      let assistantId: number | null = null;
      let staffId: number | null = null;
      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.patch(`/users/${user.id}`, {
        role: values.role || undefined,
        siteId: values.siteId || undefined,
        assistantId,
        staffId,
      });
      message.success("更新成功");
      onSuccess();
    } catch (err) {
      const axiosErr = err as AxiosError<{ message?: string }>;
      if (axiosErr.response?.status === 403) {
        message.error("目标门店不在管辖范围内");
      } else if (axiosErr.response?.data?.message) {
        message.error(axiosErr.response.data.message);
      }
    } finally {
      setSubmitting(false);
    }
  };

  // 人员下拉选项：格式 "身份/等级 - 姓名 - 手机号 - 入职日期 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}`,
      };
    }),
  ];

  const siteOptions = sites.map((s) => ({
    label: s.siteName,
    value: s.siteId,
  }));

  return (
    <Modal
      title={`编辑用户 — ${user?.nickname ?? ""}`}
      open={open}
      onCancel={onClose}
      onOk={handleOk}
      confirmLoading={submitting}
      okText="保存"
      destroyOnClose
      width={560}
    >
      <Form form={form} layout="vertical">
        <Form.Item name="siteId" label="所属门店">
          <Select
            placeholder="选择门店"
            options={siteOptions}
            onChange={handleSiteChange}
          />
        </Form.Item>
        <Form.Item name="role" label="角色" rules={[{ required: true, message: "请选择角色" }]}>
          <Select placeholder="选择角色" onChange={handleRoleChange}>
            {roles.map((r) => (
              <Select.Option key={r.code} value={r.code}>{r.name}</Select.Option>
            ))}
          </Select>
        </Form.Item>
        <Form.Item name="staffBinding" label="关联人员">
          <Select
            showSearch
            loading={loadingStaff}
            placeholder={loadingStaff ? "加载中..." : "选择关联人员"}
            options={staffOptions}
            filterOption={pinyinFilterOption}
          />
        </Form.Item>
      </Form>
    </Modal>
  );
};

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

const UserManagement: React.FC = () => {
  const [data, setData] = useState<UserItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [roleFilter, setRoleFilter] = useState("");
  const [keyword, setKeyword] = useState("");
  const [loading, setLoading] = useState(false);
  const [roles, setRoles] = useState<RoleOption[]>([]);
  const [sites, setSites] = useState<SiteOption[]>([]);

  // Modal 状态（合并为单一弹窗）
  const [editOpen, setEditOpen] = useState(false);
  const [editUser, setEditUser] = useState<UserItem | null>(null);

  // 加载角色列表（一次性）
  useEffect(() => {
    tenantApi.get<RoleOption[]>("/roles")
      .then((res) => setRoles(res.data))
      .catch(() => setRoles([]));
  }, []);

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

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string | number> = { page, page_size: pageSize };
      if (roleFilter) params.role = roleFilter;
      if (keyword.trim()) params.keyword = keyword.trim();

      const res = await tenantApi.get<PaginatedResponse<UserItem>>("/users", { params });
      setData(res.data.items);
      setTotal(res.data.total);
    } catch {
      message.error("获取用户列表失败");
    } finally {
      setLoading(false);
    }
  }, [page, pageSize, roleFilter, keyword]);

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

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

  const handleSearch = (value: string) => {
    setKeyword(value);
    setPage(1);
  };

  const openEdit = (record: UserItem) => {
    setEditUser(record);
    setEditOpen(true);
  };

  // CHANGE 2026-03-23 | 移除用户：从店铺关系中删除，替代原来的"禁用"
  const handleRemove = (record: UserItem) => {
    Modal.confirm({
      title: "确认移除",
      content: `确定要将用户「${record.nickname ?? record.id}」从店铺中移除吗？移除后该用户需重新申请才能使用小程序。`,
      okText: "确认移除",
      okButtonProps: { danger: true },
      cancelText: "取消",
      onOk: async () => {
        try {
          await tenantApi.delete(`/users/${record.id}`);
          message.success("用户已移除");
          fetchData();
        } catch (err) {
          const axiosErr = err as AxiosError<{ message?: string }>;
          message.error(axiosErr.response?.data?.message ?? "移除失败");
        }
      },
    });
  };

  const handleModalSuccess = () => {
    setEditOpen(false);
    setEditUser(null);
    fetchData();
  };

  const columns: ColumnsType<UserItem> = [
    {
      title: "姓名",
      dataIndex: "nickname",
      key: "nickname",
      render: (v) => v ?? "-",
    },
    {
      title: "角色",
      dataIndex: "role",
      key: "role",
      render: (v: string | null, record: UserItem) => v || (record.roleCode ? (ROLE_LABEL[record.roleCode] ?? record.roleCode) : "-"),
    },
    {
      title: "关联助教",
      dataIndex: "assistantName",
      key: "assistantName",
      render: (v) => v ?? "-",
    },
    {
      title: "所属门店",
      dataIndex: "siteName",
      key: "siteName",
      render: (v, record) => v ?? (record.siteId ? `门店 ${record.siteId}` : "-"),
    },
    {
      title: "操作",
      key: "action",
      render: (_, record) => (
        <Space>
          <Button type="link" onClick={() => openEdit(record)}>编辑</Button>
          <Button type="link" danger onClick={() => handleRemove(record)}>移除</Button>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <div style={{ marginBottom: 16, display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
        <span>角色筛选：</span>
        <Select
          value={roleFilter}
          onChange={(v) => { setRoleFilter(v); setPage(1); }}
          options={[
            { label: "全部角色", value: "" },
            ...roles.map((r) => ({ label: r.name, value: r.code })),
          ]}
          style={{ width: 140 }}
        />
        <Input.Search
          placeholder="搜索姓名/手机号"
          allowClear
          onSearch={handleSearch}
          style={{ width: 240 }}
        />
      </div>

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

      <EditBindModal
        open={editOpen}
        user={editUser}
        sites={sites}
        roles={roles}
        onClose={() => { setEditOpen(false); setEditUser(null); }}
        onSuccess={handleModalSuccess}
      />
    </div>
  );
};

export default UserManagement;
