import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
  DownloadOutlined,
  InboxOutlined,
  PlusOutlined,
  UploadOutlined,
} from '@ant-design/icons';
import { ProTable } from '@ant-design/pro-components';
import type { ActionType } from '@ant-design/pro-components';
import {
  App as AntdApp,
  Button,
  Descriptions,
  Drawer,
  Form,
  Input,
  InputNumber,
  Modal,
  Select,
  Space,
  Tag,
  Upload,
} from 'antd';
import type { UploadFile } from 'antd';
import { createUserColumns, getEmployeeStatusMeta } from './columns';
import {
  createEmployee,
  deleteEmployee,
  exportEmployees,
  getEmployeeDetail,
  getEmployeeList,
  getOrgTree,
  getRoleOptions,
  importEmployees,
  updateEmployee,
} from './server';
import type {
  EmployeeFormValues,
  EmployeeListQuery,
  EmployeeVO,
  OrgTreeNode,
  SelectOption,
  TenantEmployeeListRequest,
} from './types';
import './Users.scss';

const flattenOrgOptions = (nodes: OrgTreeNode[]): SelectOption[] =>
  nodes.flatMap((node) => [
    { label: node.orgName, value: node.id },
    ...flattenOrgOptions(node.children ?? []),
  ]);

const Users = () => {
  const actionRef = useRef<ActionType>();
  const lastQueryRef = useRef<TenantEmployeeListRequest>({});
  const { message, modal } = AntdApp.useApp();
  const [form] = Form.useForm<EmployeeFormValues>();
  const [orgOptions, setOrgOptions] = useState<SelectOption[]>([]);
  const [roleOptions, setRoleOptions] = useState<SelectOption[]>([]);
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<EmployeeVO | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [detail, setDetail] = useState<EmployeeVO | null>(null);
  const [detailOpen, setDetailOpen] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [importOpen, setImportOpen] = useState(false);
  const [importFileList, setImportFileList] = useState<UploadFile[]>([]);
  const [importing, setImporting] = useState(false);
  const [exporting, setExporting] = useState(false);

  useEffect(() => {
    let active = true;

    const loadOptions = async () => {
      try {
        const [orgs, roles] = await Promise.all([getOrgTree(), getRoleOptions()]);
        if (!active) return;

        setOrgOptions(flattenOrgOptions(orgs));
        setRoleOptions(roles.map((role) => ({ label: role.roleName, value: role.id })));
      } catch {
        // 错误已由 request 统一提示
      }
    };

    void loadOptions();

    return () => {
      active = false;
    };
  }, []);

  const orgNameMap = useMemo(
    () => new Map(orgOptions.map((option) => [option.value, option.label])),
    [orgOptions],
  );

  const roleNameMap = useMemo(
    () => new Map(roleOptions.map((option) => [option.value, option.label])),
    [roleOptions],
  );

  const openCreate = useCallback(() => {
    setEditing(null);
    form.resetFields();
    setFormOpen(true);
  }, [form]);

  const closeForm = useCallback(() => {
    setFormOpen(false);
    setEditing(null);
  }, []);

  const openEdit = useCallback(
    (record: EmployeeVO) => {
      setEditing(record);
      form.setFieldsValue({
        name: record.name,
        phone: record.phone,
        orgId: record.orgId,
        roleId: record.roleId,
        position: record.position,
        email: record.email,
        holdLimit: record.holdLimit,
        region: record.region,
      });
      setFormOpen(true);
    },
    [form],
  );

  const handleDetail = useCallback(async (record: EmployeeVO) => {
    setDetail(null);
    setDetailOpen(true);
    setDetailLoading(true);

    try {
      const data = await getEmployeeDetail({ id: record.id });
      setDetail(data);
    } catch {
      // 错误已由 request 统一提示
      setDetailOpen(false);
    } finally {
      setDetailLoading(false);
    }
  }, []);

  const handleDelete = useCallback(
    (record: EmployeeVO) => {
      modal.confirm({
        title: '删除员工',
        content: `确定要删除员工「${record.name}」吗？删除后不可恢复。`,
        okText: '删除',
        cancelText: '取消',
        okButtonProps: { danger: true },
        onOk: async () => {
          await deleteEmployee({ id: record.id });
          message.success('员工已删除');
          actionRef.current?.reload();
        },
      });
    },
    [message, modal],
  );

  const handleSubmit = useCallback(async () => {
    let values: EmployeeFormValues;
    try {
      values = await form.validateFields();
    } catch {
      return;
    }

    setSubmitting(true);
    try {
      if (editing) {
        await updateEmployee({ id: editing.id, ...values });
        message.success('员工信息已更新');
      } else {
        await createEmployee(values);
        message.success('员工创建成功');
      }

      setFormOpen(false);
      setEditing(null);
      form.resetFields();
      actionRef.current?.reload();
    } catch {
      // 错误已由 request 统一提示
    } finally {
      setSubmitting(false);
    }
  }, [editing, form, message]);

  const handleExport = useCallback(async () => {
    setExporting(true);
    try {
      const blob = await exportEmployees({ orgId: lastQueryRef.current.orgId });
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = 'employees.xlsx';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.setTimeout(() => URL.revokeObjectURL(url), 0);
      message.success('导出成功');
    } catch {
      // 错误已由 request 统一提示
    } finally {
      setExporting(false);
    }
  }, [message]);

  const handleImport = useCallback(async () => {
    const file = importFileList[0]?.originFileObj;
    if (!file) {
      message.warning('请先选择要导入的 Excel 文件');
      return;
    }

    setImporting(true);
    try {
      const count = await importEmployees({ file });
      message.success(`成功导入 ${count} 条员工`);
      setImportOpen(false);
      setImportFileList([]);
      actionRef.current?.reload();
    } catch {
      // 错误已由 request 统一提示
    } finally {
      setImporting(false);
    }
  }, [importFileList, message]);

  const columns = useMemo(
    () =>
      createUserColumns({
        orgOptions,
        roleOptions,
        orgNameMap,
        roleNameMap,
        onDetail: handleDetail,
        onEdit: openEdit,
        onDelete: handleDelete,
      }),
    [orgOptions, roleOptions, orgNameMap, roleNameMap, handleDetail, openEdit, handleDelete],
  );

  return (
    <div className="users-page">
      <ProTable<EmployeeVO, EmployeeListQuery>
        rowKey="id"
        actionRef={actionRef}
        columns={columns}
        cardProps={{ className: 'table-card' }}
        search={{ labelWidth: 'auto', defaultCollapsed: false }}
        scroll={{ x: 1290 }}
        options={false}
        pagination={{
          defaultPageSize: 10,
          showSizeChanger: true,
          hideOnSinglePage: false,
          showTotal: (total) => `共 ${total} 条`,
        }}
        toolBarRender={() => [
          <Button
            key="import"
            icon={<UploadOutlined />}
            onClick={() => {
              setImportFileList([]);
              setImportOpen(true);
            }}
          >
            导入
          </Button>,
          <Button
            key="export"
            icon={<DownloadOutlined />}
            loading={exporting}
            onClick={handleExport}
          >
            导出
          </Button>,
          <Button key="create" type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            新增员工
          </Button>,
        ]}
        request={async (params) => {
          const query: TenantEmployeeListRequest = {
            page: params.current,
            size: params.pageSize,
            keyword: params.keyword?.trim() || undefined,
            status: params.status,
            orgId: params.orgId,
            roleId: params.roleId,
          };
          lastQueryRef.current = query;

          const result = await getEmployeeList(query);

          return {
            data: result.records ?? [],
            total: result.total ?? 0,
            success: true,
          };
        }}
      />

      <Drawer
        title={editing ? '编辑员工' : '新增员工'}
        width={420}
        open={formOpen}
        forceRender
        onClose={closeForm}
        footer={
          <Space style={{ display: 'flex', justifyContent: 'flex-end' }}>
            <Button onClick={closeForm}>取消</Button>
            <Button type="primary" loading={submitting} onClick={handleSubmit}>
              {editing ? '保存' : '创建'}
            </Button>
          </Space>
        }
      >
        <Form form={form} layout="vertical" preserve={false}>
          <Form.Item
            name="name"
            label="姓名"
            rules={[{ required: true, message: '请输入姓名' }]}
          >
            <Input placeholder="请输入员工姓名" />
          </Form.Item>
          <Form.Item
            name="phone"
            label="手机号"
            rules={[
              { required: true, message: '请输入手机号' },
              { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号' },
            ]}
          >
            <Input placeholder="请输入手机号" maxLength={11} />
          </Form.Item>
          <Form.Item
            name="orgId"
            label="所属组织"
            rules={[{ required: true, message: '请选择所属组织' }]}
          >
            <Select
              showSearch
              optionFilterProp="label"
              options={orgOptions}
              placeholder="请选择所属组织"
            />
          </Form.Item>
          <Form.Item
            name="roleId"
            label="角色"
            rules={[{ required: true, message: '请选择角色' }]}
          >
            <Select
              showSearch
              optionFilterProp="label"
              options={roleOptions}
              placeholder="请选择角色"
            />
          </Form.Item>
          <Form.Item name="position" label="职位">
            <Input placeholder="请输入职位" />
          </Form.Item>
          <Form.Item name="region" label="负责区域">
            <Input placeholder="请输入负责区域" />
          </Form.Item>
          <Form.Item name="holdLimit" label="客户持有上限">
            <InputNumber min={0} precision={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item
            name="email"
            label="邮箱"
            rules={[{ type: 'email', message: '请输入正确的邮箱' }]}
          >
            <Input placeholder="请输入邮箱" />
          </Form.Item>
        </Form>
      </Drawer>

      <Drawer
        title="员工详情"
        width={480}
        open={detailOpen}
        loading={detailLoading}
        onClose={() => {
          setDetailOpen(false);
          setDetail(null);
        }}
      >
        {detail && (
          <Descriptions column={1} bordered size="small">
            <Descriptions.Item label="姓名">{detail.name}</Descriptions.Item>
            <Descriptions.Item label="手机号">{detail.phone}</Descriptions.Item>
            <Descriptions.Item label="所属组织">
              {orgNameMap.get(detail.orgId) ?? `#${detail.orgId}`}
            </Descriptions.Item>
            <Descriptions.Item label="角色">
              {roleNameMap.get(detail.roleId) ?? `#${detail.roleId}`}
            </Descriptions.Item>
            <Descriptions.Item label="职位">{detail.position || '-'}</Descriptions.Item>
            <Descriptions.Item label="邮箱">{detail.email || '-'}</Descriptions.Item>
            <Descriptions.Item label="负责区域">{detail.region || '-'}</Descriptions.Item>
            <Descriptions.Item label="客户持有上限">
              {detail.holdLimit ?? '-'}
            </Descriptions.Item>
            <Descriptions.Item label="状态">
              <Tag color={getEmployeeStatusMeta(detail.status).color} bordered={false}>
                {getEmployeeStatusMeta(detail.status).text}
              </Tag>
            </Descriptions.Item>
            <Descriptions.Item label="入职日期">{detail.hireDate || '-'}</Descriptions.Item>
            <Descriptions.Item label="创建时间">{detail.createdAt || '-'}</Descriptions.Item>
          </Descriptions>
        )}
      </Drawer>

      <Modal
        title="导入员工"
        open={importOpen}
        onOk={handleImport}
        onCancel={() => {
          setImportOpen(false);
          setImportFileList([]);
        }}
        confirmLoading={importing}
        okText="导入"
        cancelText="取消"
      >
        <Upload.Dragger
          accept=".xlsx,.xls"
          maxCount={1}
          fileList={importFileList}
          beforeUpload={() => false}
          onChange={({ fileList }) => setImportFileList(fileList)}
        >
          <p className="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p className="ant-upload-text">点击或拖拽 Excel 文件到此处</p>
          <p className="ant-upload-hint">仅支持 .xlsx / .xls 格式</p>
        </Upload.Dragger>
      </Modal>
    </div>
  );
};

export default Users;
