import {
  Avatar,
  Button,
  Card,
  Col,
  Drawer,
  Form,
  Input,
  Modal,
  Popconfirm,
  Row,
  Select,
  Space,
  Switch,
  Tag,
  Tooltip,
  TreeSelect,
  Typography,
  Upload,
  message
} from "antd";
import type { DefaultOptionType } from "antd/es/select";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import {
  ApartmentOutlined,
  DeleteOutlined,
  EditOutlined,
  KeyOutlined,
  MinusCircleOutlined,
  PlusOutlined,
  QuestionCircleOutlined,
  SearchOutlined,
  ShopOutlined,
  UploadOutlined,
  UserOutlined
} from "@ant-design/icons";
import {
  createUser,
  deleteUser,
  getUserDetail,
  listOrgs,
  listRoles,
  listTenants,
  listUserRoles,
  listUsers,
  resetUserPassword,
  updateUser,
  uploadPlatformAsset
} from "@/api";
import {fetchPublicPasswordPolicy, type PasswordPolicyPublic} from "@/api/auth";
import { useDict } from "@/hooks/useDict";
import { usePermission } from "@/hooks/usePermission";
import PageContainer from "@/components/shared/PageContainer";
import DataListPanel from "@/components/shared/DataListPanel";
import AppPagination from "@/components/shared/AppPagination";
import ListTable from "@/components/shared/ListTable/ListTable";
import SectionCard from "@/components/shared/SectionCard";
import { LOGIN_NAME_PATTERN, sanitizeLoginName } from "@/utils/loginName";
import {buildPasswordPolicyValidator, buildPolicyHints} from "@/utils/password";
import type { SysOrg, SysRole, SysTenant, SysUser } from "@/types";
import "./index.less";

const { Title, Text } = Typography;

type OrgTreeNode = { value: number; title: string; children: OrgTreeNode[] };

type Membership = { tenantId?: number; orgId?: number; orgName?: string; orgPath?: string; orgFullName?: string };
type ResetPasswordValues = { newPassword: string; confirmPassword: string };

const getMembershipOrgName = (membership: Membership) => {
  return membership.orgFullName || membership.orgPath || membership.orgName || "";
};

function buildOrgTree(list: SysOrg[]): OrgTreeNode[] {
  const map = new Map<number, OrgTreeNode>();
  const roots: OrgTreeNode[] = [];

  list.forEach((item) => {
    map.set(item.id, { value: item.id, title: item.orgName, children: [] });
  });

  map.forEach((node, id) => {
    const item = list.find((org) => org.id === id);
    if (item?.parentId && map.has(item.parentId)) {
      map.get(item.parentId)!.children.push(node);
    } else {
      roots.push(node);
    }
  });

  return roots;
}

function MembershipOrgSelect({ fieldProps, name, tenantId }: { fieldProps: any; name: number; tenantId?: number }) {
  const { t } = useTranslation();
  const [orgs, setOrgs] = useState<OrgTreeNode[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!tenantId) {
      setOrgs([]);
      return;
    }

    setLoading(true);
    listOrgs(tenantId)
      .then((data) => setOrgs(buildOrgTree(data || [])))
      .finally(() => setLoading(false));
  }, [tenantId]);

  return (
    <Form.Item {...fieldProps} label={t("users.orgNode")} name={[name, "orgId"]}>
      <TreeSelect placeholder={t("usersExt.selectDepartment")} allowClear treeData={orgs} loading={loading} disabled={!tenantId} />
    </Form.Item>
  );
}

export default function Users() {
  const { t } = useTranslation();
  const { can } = usePermission();
  const { items: statusDict } = useDict("sys_common_status");
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [avatarUploading, setAvatarUploading] = useState(false);
  const [data, setData] = useState<SysUser[]>([]);
  const [roles, setRoles] = useState<SysRole[]>([]);
  const [tenants, setTenants] = useState<SysTenant[]>([]);
  const [orgs, setOrgs] = useState<SysOrg[]>([]);
  const [current, setCurrent] = useState(1);
  const [pageSize, setPageSize] = useState(10);
  const [searchText, setSearchText] = useState("");

  const handleSearch = () => {
    setCurrent(1);
  };

  const handleResetSearch = () => {
    setSearchText("");
    setFilterTenantId(undefined);
    setCurrent(1);
  };
  const [filterTenantId, setFilterTenantId] = useState<number | undefined>(undefined);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editing, setEditing] = useState<SysUser | null>(null);
  const [roleSelectOpen, setRoleSelectOpen] = useState(false);
  const [form] = Form.useForm();
  const [resetPasswordOpen, setResetPasswordOpen] = useState(false);
  const [resetPasswordLoading, setResetPasswordLoading] = useState(false);
  const [resetPasswordTarget, setResetPasswordTarget] = useState<SysUser | null>(null);
  const [passwordPolicy, setPasswordPolicy] = useState<PasswordPolicyPublic | null>(null);
  const [resetPasswordForm] = Form.useForm<ResetPasswordValues>();

  const isPlatformMode = useMemo(() => {
    const profileStr = sessionStorage.getItem("userProfile");
    if (!profileStr) return false;
    const profile = JSON.parse(profileStr);
    return !!profile.isPlatformAdmin;
  }, []);

  const activeTenantId = useMemo(() => Number(localStorage.getItem("activeTenantId") || 0), []);
  const selectedTenantId = Form.useWatch("tenantId", form);
  const memberships = (Form.useWatch("memberships", form) || []) as Membership[];
  const passwordValue = Form.useWatch("password", form);

  const tenantMap = useMemo(() => {
    const map: Record<number, string> = {};
    tenants.forEach((tenant) => {
      map[tenant.id] = tenant.tenantName;
    });
    return map;
  }, [tenants]);

  const roleOptions = useMemo<DefaultOptionType[]>(() => {
    if (!isPlatformMode) {
      return roles.map((role) => ({ label: role.roleName, value: role.roleId }));
    }

    const selectedTenantIds = new Set(memberships.map((membership) => membership?.tenantId).filter(Boolean));
    return roles
      .filter((role: any) => role.tenantId != null && selectedTenantIds.has(role.tenantId))
      .map((role: any) => {
        const tenantId = role.tenantId ?? 0;
        const tenantName = tenantMap[tenantId] || `Tenant:${tenantId}`;
        return {
          label: (
            <div style={{ display: "flex", justifyContent: "space-between", width: "100%" }}>
              <span>{role.roleName}</span>
              <span style={{ color: "#bfbfbf", fontSize: "11px", marginLeft: 8 }}>[{tenantName}]</span>
            </div>
          ),
          value: role.roleId,
          searchText: `${role.roleName} ${tenantName}`
        };
      });
  }, [isPlatformMode, roles, memberships, tenantMap]);

  const loadBaseData = async () => {
    try {
      const promises: Promise<any>[] = [listRoles()];
      if (isPlatformMode) {
        promises.push(listTenants({ current: 1, size: 1000 }));
      }
      const [rolesList, tenantsResponse] = await Promise.all(promises);
      setRoles(rolesList || []);
      if (isPlatformMode && tenantsResponse) {
        setTenants(tenantsResponse.records || []);
      }
    } catch {
    }
  };

  const loadUsersData = async () => {
    setLoading(true);
    try {
      const usersList = await listUsers({ tenantId: filterTenantId });
      setData(usersList || []);
    } finally {
      setLoading(false);
    }
  };

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

  useEffect(() => {
    void (async () => {
      try {
        setPasswordPolicy(await fetchPublicPasswordPolicy());
      } catch {
        setPasswordPolicy(null);
      }
    })();
  }, []);

  const policyHints = useMemo(() => buildPolicyHints(passwordPolicy), [passwordPolicy]);

  useEffect(() => {
    loadUsersData();
  }, [filterTenantId]);

  useEffect(() => {
    const fetchOrgs = async () => {
      const targetId = isPlatformMode ? selectedTenantId : activeTenantId;
      if (targetId) {
        const list = await listOrgs(targetId);
        setOrgs(list || []);
      } else {
        setOrgs([]);
      }
    };
    fetchOrgs();
  }, [selectedTenantId, isPlatformMode, activeTenantId]);

  const orgTreeData = useMemo(() => buildOrgTree(orgs), [orgs]);

  const filteredData = useMemo(() => {
    if (!searchText) return data;
    const lower = searchText.toLowerCase();
    return data.filter(
      (user) =>
        user.username.toLowerCase().includes(lower) ||
        user.displayName.toLowerCase().includes(lower) ||
        (user.email && user.email.toLowerCase().includes(lower))
    );
  }, [data, searchText]);

  const openCreate = () => {
    setEditing(null);
    setRoleSelectOpen(false);
    form.resetFields();
    form.setFieldsValue({
      status: 1,
      roleIds: [],
      isPlatformAdmin: false,
      tenantId: isPlatformMode ? undefined : activeTenantId,
      memberships: isPlatformMode ? [] : [{ tenantId: activeTenantId }]
    });
    setDrawerOpen(true);
  };

  const openEdit = async (record: SysUser) => {
    setEditing(record);
    setRoleSelectOpen(false);
    try {
      const detail = await getUserDetail(record.userId);
      const roleIds = await listUserRoles(record.userId);
      form.setFieldsValue({
        ...detail,
        roleIds: roleIds || [],
        tenantId: (detail as any).tenantId || detail.memberships?.[0]?.tenantId,
        orgId: (detail as any).orgId || detail.memberships?.[0]?.orgId,
        memberships: detail.memberships || []
      });
      setDrawerOpen(true);
    } catch {
    }
  };

  const handleDelete = async (id: number) => {
    await deleteUser(id);
    message.success(t("common.success"));
    loadUsersData();
  };

  const handleAvatarUpload = async (file: File) => {
    try {
      setAvatarUploading(true);
      const url = await uploadPlatformAsset(file);
      form.setFieldValue("avatarUrl", url);
      message.success(t("common.success"));
    } catch (error) {
      message.error(error instanceof Error ? error.message : t("common.error"));
      return Upload.LIST_IGNORE;
    } finally {
      setAvatarUploading(false);
    }
    return false;
  };

  const submit = async () => {
    const values = await form.validateFields();
    setSaving(true);
    try {
      const userPayload: Partial<SysUser> = {
        username: values.username,
        displayName: values.displayName,
        email: values.email,
        phone: values.phone,
        avatarUrl: values.avatarUrl,
        status: values.status,
        isPlatformAdmin: values.isPlatformAdmin,
        roleIds: values.roleIds || []
      };

      if (!isPlatformMode) {
        userPayload.memberships = [{ tenantId: activeTenantId, orgId: values.orgId } as any];
      } else {
        userPayload.memberships = values.memberships || [];
      }

      if (editing) {
        await updateUser(editing.userId, userPayload);
      } else {
        if (values.password) {
          userPayload.password = values.password;
        }
        await createUser(userPayload);
      }

      message.success(t("common.success"));
      setDrawerOpen(false);
      loadUsersData();
    } finally {
      setSaving(false);
    }
  };

  const openResetPassword = (record: SysUser) => {
    setResetPasswordTarget(record);
    resetPasswordForm.resetFields();
    setResetPasswordOpen(true);
  };

  const submitResetPassword = async () => {
    if (!resetPasswordTarget) {
      return;
    }
    const values = await resetPasswordForm.validateFields();
    setResetPasswordLoading(true);
    try {
      await resetUserPassword(resetPasswordTarget.userId, {newPassword: values.newPassword});
      message.success("密码已重置");
      setResetPasswordOpen(false);
      setResetPasswordTarget(null);
      resetPasswordForm.resetFields();
    } finally {
      setResetPasswordLoading(false);
    }
  };

  const columns: any[] = [
    {
      title: t("users.userInfo"),
      key: "user",
      render: (_: any, record: SysUser) => (
        <Space>
          <Avatar className="user-avatar-placeholder" size={40} src={record.avatarUrl || undefined} icon={record.avatarUrl ? undefined : <UserOutlined />} />
          <div>
            <Space size={4}>
              <div className="user-display-name">{record.displayName}</div>
              {record.isPlatformAdmin && <Tag color="gold" style={{ fontSize: 10 }}>{t("users.platformAdmin")}</Tag>}
            </Space>
            <div className="user-username tabular-nums">@{record.username}</div>
          </div>
        </Space>
      )
    },
    ...(isPlatformMode
      ? [{
        title: t("users.tenant"),
        key: "tenant",
        width: 260,
        render: (_: any, record: SysUser) => {
          if (record.memberships && record.memberships.length > 0) {
            const tenantNames = Array.from(
              new Set(
                record.memberships
                  .map((membership: Membership) => tenantMap[membership.tenantId || 0] || (membership.tenantId ? `Tenant ${membership.tenantId}` : ""))
                  .filter(Boolean)
              )
            );
            return (
              <div className="user-affiliation-list">
                {tenantNames.map((name, index) => (
                  <Tooltip key={`${name}-${index}`} title={name}>
                    <span className="user-affiliation-tag user-affiliation-tag--tenant">
                      <ShopOutlined aria-hidden="true" />
                      <span className="user-affiliation-tag__text">{name}</span>
                    </span>
                  </Tooltip>
                ))}
              </div>
            );
          }
          return <Text type="secondary">{t("usersExt.noTenant")}</Text>;
        }
      }]
      : []),
    {
      title: t("users.orgNode"),
      key: "org",
      width: 340,
      render: (_: any, record: SysUser) => {
        if (record.memberships && record.memberships.length > 0) {
          const orgNames = Array.from(
            new Set(record.memberships.map((membership: Membership) => getMembershipOrgName(membership).trim()).filter(Boolean))
          );
          if (orgNames.length > 0) {
            return (
              <div className="user-affiliation-list">
                {orgNames.map((name: string, index: number) => (
                  <Tooltip key={`${name}-${index}`} title={name}>
                    <span className="user-affiliation-tag user-affiliation-tag--org">
                      <ApartmentOutlined aria-hidden="true" />
                      <span className="user-affiliation-tag__text">{name}</span>
                    </span>
                  </Tooltip>
                ))}
              </div>
            );
          }
        }
        return <Text type="secondary">-</Text>;
      }
    },
    {
      title: t("users.roles"),
      key: "roles",
      render: (_: any, record: SysUser) => (
        <Space wrap size={[0, 4]}>
          {record.roles && record.roles.length > 0 ? record.roles.map((role) => <Tag key={role.roleId} color="cyan">{role.roleName}</Tag>) : <Text type="secondary">{t("usersExt.noRoles")}</Text>}
        </Space>
      )
    },
    {
      title: t("common.status"),
      dataIndex: "status",
      width: 80,
      render: (status: number) => {
        const item = statusDict.find((dictItem) => dictItem.itemValue === String(status));
        return <Tag color={status === 1 ? "green" : "red"} className="m-0">{item ? item.itemLabel : status === 1 ? t("usersExt.enabled") : t("usersExt.disabled")}</Tag>;
      }
    },
    {
      title: t("common.action"),
      key: "action",
      width: 200,
      fixed: "right" as const,
      render: (_: any, record: SysUser) => (
        <Space>
          {can("sys:user:update") && <Button type="text" icon={<EditOutlined aria-hidden="true" />} onClick={() => openEdit(record)} aria-label={t("common.edit")} />}
          {can("sys:user:update") && (
            <Tooltip title="重置密码">
              <Button type="text" icon={<KeyOutlined aria-hidden="true"/>} onClick={() => openResetPassword(record)}
                      aria-label="重置密码"/>
            </Tooltip>
          )}
          {can("sys:user:delete") && record.userId !== 1 && <Popconfirm title={t("usersExt.deleteConfirm")} okText={t("common.confirm")} cancelText={t("common.cancel")} onConfirm={() => handleDelete(record.userId)}><Button type="text" danger icon={<DeleteOutlined aria-hidden="true" />} aria-label={t("common.delete")} /></Popconfirm>}
        </Space>
      )
    }
  ];

  return (
    <PageContainer title={null} className="users-page">
      <SectionCard
        title={t("users.title")}
        description={t("users.subtitle")}
      >
        <DataListPanel
          leftActions={
            can("sys:user:create") ? (
              <Button type="primary" icon={<PlusOutlined aria-hidden="true" />} onClick={openCreate}>
                {t("common.create")}
              </Button>
            ) : null
          }
          rightActions={
            <Space size={8} wrap>
              {isPlatformMode &&
                <Select placeholder={t("users.tenantFilter")} style={{width: 200}} allowClear value={filterTenantId}
                        onChange={setFilterTenantId}
                        options={tenants.map((tenant) => ({label: tenant.tenantName, value: tenant.id}))}
                        suffixIcon={<ShopOutlined aria-hidden="true"/>}/>}
              <Input placeholder={t("users.searchPlaceholder")} prefix={<SearchOutlined aria-hidden="true"/>}
                     className="users-search-input" style={{width: 300}} value={searchText} onChange={(event) => {
                setSearchText(event.target.value);
                setCurrent(1);
              }} allowClear aria-label={t("common.search")}/>
              <Button type="primary" icon={<SearchOutlined aria-hidden="true"/>}
                      onClick={handleSearch}>{t("common.search")}</Button>
              <Button onClick={handleResetSearch}>{t("common.reset")}</Button>
            </Space>
          }
          footer={
            <AppPagination
              current={current}
              pageSize={pageSize}
              total={filteredData.length}
              onChange={(page, size) => {
                setCurrent(page);
                setPageSize(size);
              }}
            />
          }
        >
          <ListTable
            rowKey="userId"
            columns={columns}
            dataSource={filteredData.slice((current - 1) * pageSize, current * pageSize)}
            loading={loading}
            scroll={{ y: "100%" }}
            pagination={false}
          />
        </DataListPanel>
      </SectionCard>

      <Drawer title={<div className="user-drawer-title"><UserOutlined aria-hidden="true"/><span>{editing ? t("users.drawerTitleEdit") : t("users.drawerTitleCreate")}</span>
      </div>} open={drawerOpen} onClose={() => setDrawerOpen(false)} width={520} destroyOnClose
              footer={<div className="app-page__drawer-footer"><Button
                onClick={() => setDrawerOpen(false)}>{t("common.cancel")}</Button><Button type="primary"
                                                                                          loading={saving}
                                                                                          onClick={submit}>{t("common.save")}</Button>
              </div>}>
        <Form form={form} layout="vertical" className="user-form">
          <Title level={5} style={{ marginBottom: 16 }}>{t("usersExt.basicInfo")}</Title>
          <Row gutter={16}>
            <Col span={12}><Form.Item label={t("users.username")} name="username" rules={[{
              required: true,
              message: t("users.username")
            }, {
              pattern: LOGIN_NAME_PATTERN,
              message: t("usersExt.usernameFormatTip", {defaultValue: "登录名只能输入数字、小写英文、@ 和 _"})
            }]} getValueFromEvent={(event) => sanitizeLoginName(event?.target?.value)}
                                      extra={t("usersExt.usernameFormatTip", {defaultValue: "登录名只能输入数字、小写英文、@ 和 _"})}><Input
              placeholder={t("usersExt.usernamePlaceholder", {defaultValue: "仅支持 a-z、0-9、@、_"})} disabled={!!editing}
              className="tabular-nums"/></Form.Item></Col>
            <Col span={12}><Form.Item label={t("users.displayName")} name="displayName"
                                      rules={[{required: true, message: t("users.displayName")}]}><Input
              placeholder={t("users.displayName")}/></Form.Item></Col>
          </Row>
          <Row gutter={16}>
            <Col span={12}><Form.Item label={t("users.email")} name="email"
                                      rules={[{required: true, message: "请输入邮箱地址"}, {
                                        type: "email",
                                        message: "请输入正确的邮箱格式"
                                      }]}><Input placeholder={t("usersExt.emailPlaceholder")} className="tabular-nums"/></Form.Item></Col>
            <Col span={12}><Form.Item label={t("users.phone")} name="phone"><Input placeholder={t("users.phone")}
                                                                                   className="tabular-nums"/></Form.Item></Col>
          </Row>
          <Form.Item label={t("profile.avatarUrl")} name="avatarUrl"><Input
            placeholder={t("profile.avatarUrlPlaceholder")}/></Form.Item>
          <Upload accept="image/*" showUploadList={false} beforeUpload={handleAvatarUpload}>
            <Button icon={<UploadOutlined/>} loading={avatarUploading}
                    style={{marginBottom: 16}}>{t("profile.uploadAvatar")}</Button>
          </Upload>
          {isPlatformMode && (
            <div className="user-membership-section">
              <Title level={5} className="user-membership-title user-membership-title--required">{t("usersExt.membershipsTitle")}</Title>
              <Form.List
                name="memberships"
                rules={[
                  {
                    validator: async (_, value?: Membership[]) => {
                      if (value?.some((membership) => membership?.tenantId)) {
                        return;
                      }
                      throw new Error(t("usersExt.membershipRequired"));
                    }
                  }
                ]}
              >
                {(fields, { add, remove }, { errors }) => (
                  <>
                    {fields.map(({ key, name, ...restField }) => (
                      <Card key={key} size="small" className="mb-3" styles={{ body: { padding: "12px" } }} title={t("usersExt.membershipTitle", { index: name + 1 })} extra={fields.length > 1 && <Button type="text" danger icon={<MinusCircleOutlined />} onClick={() => remove(name)} />}>
                        <Row gutter={12}>
                          <Col span={12}>
                            <Form.Item {...restField} label={t("users.tenant")} name={[name, "tenantId"]} rules={[{ required: true, message: t("usersExt.membershipRequired") }]}>
                              <Select options={tenants.map((tenant) => ({ label: tenant.tenantName, value: tenant.id }))} placeholder={t("usersExt.selectTenant")} />
                            </Form.Item>
                          </Col>
                          <Col span={12}>
                            <MembershipOrgSelect fieldProps={{ ...restField }} name={name} tenantId={form.getFieldValue(["memberships", name, "tenantId"])} />
                          </Col>
                        </Row>
                      </Card>
                    ))}
                    <Form.ErrorList errors={errors} />
                    <Button type="dashed" onClick={() => add()} block
                            icon={<PlusOutlined/>}>{t("usersExt.addMembership")}</Button>
                  </>
                )}
              </Form.List>
            </div>
          )}
          {!isPlatformMode && (
            <Form.Item
              label={t("users.orgNode")}
              name="orgId"
              rules={[{ required: true, message: t("usersExt.selectOrgPlaceholder") }]}
            >
              <TreeSelect placeholder={t("usersExt.selectOrgPlaceholder")} allowClear treeData={orgTreeData}/>
            </Form.Item>
          )}
          <Form.Item label={t("users.roles")} name="roleIds"
                      rules={[{required: true, message: t("users.roles")}]}><Select mode="multiple"
                                                                                    placeholder={t("users.roles")}
                                                                                    options={roleOptions}
                                                                                    open={roleSelectOpen}
                                                                                    onDropdownVisibleChange={setRoleSelectOpen}
                                                                                    onChange={() => setRoleSelectOpen(false)}
                                                                                    optionFilterProp={isPlatformMode ? "searchText" : "label"}/></Form.Item>
          {!editing ? (
            <Form.Item
              label={t("users.password")}
              name="password"
              validateFirst
              rules={[
                {required: true, message: t("users.password")},
                {validator: buildPasswordPolicyValidator(passwordPolicy, () => form.getFieldValue("username"))}
              ]}
            >
              <Input.Password placeholder={t("usersExt.passwordInitPlaceholder")} autoComplete="new-password"/>
            </Form.Item>
          ) : null}
          {!editing && passwordValue ? (
            <Form.Item
              label={t("usersExt.confirmPassword")}
              name="confirmPassword"
              dependencies={["password"]}
              rules={[
                ({ getFieldValue }) => ({
                  required: !editing || !!getFieldValue("password"),
                  message: t("usersExt.confirmPassword"),
                }),
                ({ getFieldValue }) => ({
                  validator(_, value) {
                    if (!value || getFieldValue("password") === value) {
                      return Promise.resolve();
                    }
                    return Promise.reject(new Error(t("profile.passwordsDoNotMatch")));
                  },
                }),
              ]}
            >
              <Input.Password placeholder={t("usersExt.confirmPasswordPlaceholder")} autoComplete="new-password" />
            </Form.Item>
          ) : null}
          <Row gutter={16}>
            <Col span={12}><Form.Item label={t("common.status")} name="status" initialValue={1}><Select
              options={statusDict.map((item) => ({label: item.itemLabel, value: Number(item.itemValue)}))}/></Form.Item></Col>
            {isPlatformMode &&
              <Col span={12}><Form.Item label={t("users.platformAdmin")} name="isPlatformAdmin" valuePropName="checked"><Switch/></Form.Item></Col>}
          </Row>
        </Form>
      </Drawer>

      <Modal
        title={resetPasswordTarget ? `重置密码: ${resetPasswordTarget.displayName}` : "重置密码"}
        open={resetPasswordOpen}
        onCancel={() => {
          setResetPasswordOpen(false);
          setResetPasswordTarget(null);
          resetPasswordForm.resetFields();
        }}
        onOk={() => void submitResetPassword()}
        confirmLoading={resetPasswordLoading}
        destroyOnClose
      >
        <Form form={resetPasswordForm} layout="vertical">
          <Form.Item
            label={
              <Space size={4}>
                <span>新密码</span>
                <Tooltip
                  title={
                    policyHints.length > 0 ? (
                      <ul style={{paddingLeft: 18, margin: 0, fontSize: 13, lineHeight: 1.6}}>
                        {policyHints.map((hint) => (
                          <li key={hint}>{hint}</li>
                        ))}
                      </ul>
                    ) : (
                      t("profile.passwordRules")
                    )
                  }
                  overlayStyle={{maxWidth: 300}}
                >
                  <QuestionCircleOutlined style={{color: "rgba(0,0,0,0.45)", cursor: "help"}}/>
                </Tooltip>
              </Space>
            }
            name="newPassword"
            validateFirst
            rules={[
              {required: true, message: "请输入新密码"},
              {validator: buildPasswordPolicyValidator(passwordPolicy, () => resetPasswordTarget?.username)}
            ]}
          >
            <Input.Password autoComplete="new-password"/>
          </Form.Item>
          <Form.Item
            label="确认新密码"
            name="confirmPassword"
            dependencies={["newPassword"]}
            rules={[
              {required: true, message: "请再次输入新密码"},
              ({getFieldValue}) => ({
                validator(_, value) {
                  if (!value || getFieldValue("newPassword") === value) {
                    return Promise.resolve();
                  }
                  return Promise.reject(new Error(t("profile.passwordsDoNotMatch")));
                }
              })
            ]}
          >
            <Input.Password autoComplete="new-password"/>
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
}
