import {
  MEMBER_TYPE_COLORS,
  MEMBER_TYPE_LABELS,
  STATUS_DISABLED,
  STATUS_ENABLED,
  STATUS_OPTIONS,
} from '@/defines';
import { BindRolesDrawer } from '@/pages/Admin/_shared/BindRolesDrawer';
import { UserPermDrawer } from '@/pages/Admin/_shared/UserPermDrawer';
import {
  useProductRolesBase,
  useUserProductRoles,
} from '@/pages/Admin/_shared/useUserProductRoles';
import { fetchDeptTree } from '@/services/dept';
import {
  fetchResetPassword,
  fetchUpdateUserStatus,
  fetchUserCredentials,
  fetchUserList,
} from '@/services/user';
import { unixTimeFormat } from '@/utils/timeUtils';
import { StopOutlined } from '@ant-design/icons';
import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { Button, Popconfirm, Tag, message } from 'antd';
import { useEffect, useMemo, useRef, useState } from 'react';
import { UserForm } from './components/Form';
import { UserCredentialModal } from './components/UserCredentialModal';

const flattenDeptTree = (items: API.DeptItem[]): { label: string; value: number }[] =>
  items.flatMap((d) => [
    { label: d.name, value: d.id },
    ...(d.children ? flattenDeptTree(d.children) : []),
  ]);

export default function UserPage() {
  const intl = useIntl();
  const actionRef = useRef<ActionType>();
  const [pageUsers, setPageUsers] = useState<API.UserItem[]>([]);
  const [deptOptions, setDeptOptions] = useState<{ label: string; value: number }[]>([]);
  const [rolesDrawer, setRolesDrawer] = useState<{ open: boolean; userId: number }>({
    open: false,
    userId: 0,
  });
  const [permDrawer, setPermDrawer] = useState<{ open: boolean; userId: number }>({
    open: false,
    userId: 0,
  });
  const [refreshKey, setRefreshKey] = useState(0);
  const [credData, setCredData] = useState<API.FetchUserCredentialsResp | null>(null);
  const [credOpen, setCredOpen] = useState(false);

  useEffect(() => {
    fetchDeptTree().then((res) => {
      setDeptOptions([{ label: '无部门', value: 0 }, ...flattenDeptTree(res.data ?? [])]);
    });
  }, []);

  const userIds = useMemo(() => pageUsers.map((u) => u.id), [pageUsers]);
  const productRolesBase = useProductRolesBase();
  const { userProductInfo } = useUserProductRoles(userIds, productRolesBase, refreshKey);

  const handleToggleStatus = async (r: API.UserItem) => {
    const res = await fetchUpdateUserStatus({
      id: r.id,
      status: r.status === STATUS_ENABLED ? STATUS_DISABLED : STATUS_ENABLED,
    });
    if (!res.success) return;
    message.success('操作成功');
    actionRef.current?.reload();
  };

  const showCredentials = async (ticket: string) => {
    const res = await fetchUserCredentials({ ticket });
    if (!res.success || !res.data) return;
    setCredData(res.data);
    setCredOpen(true);
  };

  const handleCreateSuccess = async (ticket?: string) => {
    actionRef.current?.reload();
    if (ticket) await showCredentials(ticket);
  };

  const handleResetPassword = async (r: API.UserItem) => {
    const res = await fetchResetPassword({ userId: r.id });
    if (!res.success || !res.data) return;
    message.success('密码已重置');
    await showCredentials(res.data.credentialsTicket);
  };

  const columns: ProColumns<API.UserItem>[] = [
    { title: '用户名', dataIndex: 'username', width: 200 },
    { title: '昵称', dataIndex: 'nickname', width: 200 },
    {
      title: '状态',
      dataIndex: 'status',
      width: 80,
      valueType: 'select',
      fieldProps: { options: STATUS_OPTIONS },
      render: (_, r) => (
        <Tag color={r.status === STATUS_ENABLED ? 'success' : 'error'}>
          {r.status === STATUS_ENABLED ? '启用' : '禁用'}
        </Tag>
      ),
    },
    {
      title: '部门',
      dataIndex: 'deptId',
      width: 150,
      valueType: 'select',
      fieldProps: { options: deptOptions, showSearch: true },
      render: (_, r) => {
        if (!r.deptId)
          return <span className="text-(--ant-color-text-quaternary) text-xs">无部门</span>;
        const dept = deptOptions.find((d) => d.value === r.deptId);
        return (
          dept?.label ?? <span className="text-(--ant-color-text-quaternary) text-xs">无部门</span>
        );
      },
    },
    {
      title: '产品角色',
      key: 'productRoles',
      search: false,
      render: (_, r) => {
        const info = userProductInfo.get(r.id) ?? [];
        if (info.length === 0)
          return <span className="text-(--ant-color-text-quaternary) text-xs">无</span>;
        return (
          <div className="flex flex-col gap-1">
            {info.map((p) => (
              <div
                key={p.productName}
                className="inline-flex flex-row gap-1 rounded border border-dashed border-(--ant-color-border) bg-(--ant-color-fill-quaternary) px-2 py-2 self-start"
              >
                <Tag color="purple" className="mr-0 self-center">
                  {p.productName}
                  {p.productStatus !== STATUS_ENABLED && (
                    <StopOutlined className="ml-1 text-(--ant-color-error)!" />
                  )}
                </Tag>
                <Tag
                  color={MEMBER_TYPE_COLORS[p.memberType ?? ''] ?? 'default'}
                  className="mr-0 self-center"
                >
                  {MEMBER_TYPE_LABELS[p.memberType ?? ''] ?? p.memberType}
                </Tag>
                <div className="flex flex-row flex-wrap gap-1 items-center">
                  {p.roleNames.length > 0 ? (
                    p.roleNames.map((name) => (
                      <Tag key={name} className="mr-0">
                        {name}
                      </Tag>
                    ))
                  ) : (
                    <span className="text-(--ant-color-text-quaternary) text-xs whitespace-nowrap">
                      无角色
                    </span>
                  )}
                </div>
              </div>
            ))}
          </div>
        );
      },
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      width: 180,
      search: false,
      render: (_, r) => unixTimeFormat(r.createTime),
    },
    {
      title: '操作',
      valueType: 'option',
      width: 320,
      render: (_, r) => [
        <UserForm
          key="edit"
          mode="edit"
          initialValues={r}
          trigger={<a>编辑</a>}
          onSuccess={() => actionRef.current?.reload()}
        />,
        <UserForm
          key="copy"
          mode="copy"
          initialValues={r}
          trigger={<a>复制</a>}
          onSuccess={handleCreateSuccess}
        />,
        <a key="roles" onClick={() => setRolesDrawer({ open: true, userId: r.id })}>
          分配角色
        </a>,
        <a key="perms" onClick={() => setPermDrawer({ open: true, userId: r.id })}>
          设置权限
        </a>,
        <Popconfirm
          key="reset"
          title={`确认重置「${r.username}」的密码？`}
          onConfirm={() => handleResetPassword(r)}
        >
          <a>重置密码</a>
        </Popconfirm>,
        <Popconfirm
          key="status"
          title={
            r.status === STATUS_ENABLED
              ? `确认冻结「${r.username}」？`
              : `确认解冻「${r.username}」？`
          }
          onConfirm={() => handleToggleStatus(r)}
        >
          <a className={r.status === STATUS_ENABLED ? 'text-(--ant-color-error)' : ''}>
            {r.status === STATUS_ENABLED ? '冻结' : '解冻'}
          </a>
        </Popconfirm>,
      ],
    },
  ];

  return (
    <PageContainer title={intl.formatMessage({ id: 'admin.user.title' })}>
      <ProTable<API.UserItem>
        actionRef={actionRef}
        columns={columns}
        rowKey="id"
        search={{ span: { xs: 24, sm: 12, md: 8, lg: 6, xl: 4, xxl: 4 } }}
        request={fetchUserList}
        onDataSourceChange={setPageUsers}
        scroll={{ x: 1280 }}
        tableLayout="fixed"
        pagination={{
          defaultPageSize: 20,
          pageSizeOptions: [10, 20, 50, 100],
          showSizeChanger: true,
        }}
        toolBarRender={() => [
          <UserForm
            key="create"
            mode="add"
            trigger={<Button type="primary">新建用户</Button>}
            onSuccess={handleCreateSuccess}
          />,
        ]}
      />
      <BindRolesDrawer
        {...rolesDrawer}
        onClose={() => setRolesDrawer((p) => ({ ...p, open: false }))}
        onSuccess={() => setRefreshKey((k) => k + 1)}
      />
      <UserPermDrawer
        {...permDrawer}
        onClose={() => setPermDrawer((p) => ({ ...p, open: false }))}
      />
      <UserCredentialModal open={credOpen} data={credData} onClose={() => setCredOpen(false)} />
    </PageContainer>
  );
}
