import {
  Alert,
  Button,
  Card,
  type CardProps,
  Col,
  message,
  Popconfirm,
  Row,
  Space, Table, type TableProps, Tag,
  Tree,
  type TreeDataNode, type TreeProps, Typography
} from "antd";
import {BankOutlined, DeleteOutlined, PlusOutlined, TeamOutlined, UserOutlined} from "@ant-design/icons";
import {useEffect, useRef, useState} from "react";
import {queryDept, createDept, updateDept, deleteDept, deptUsers} from "@/api/system/sys_dept.ts";
import type {ISysDept} from "@/domain/iSysDept.ts";
import {isArray, omit} from 'lodash';
import type {FormColumn} from "@/components/XinFormField/FieldRender/typings.ts";
import XinForm, {type XinFormRef} from "@/components/XinForm";
import * as React from "react";
import {useTranslation} from "react-i18next";
import AuthButton from "@/components/AuthButton";
import useAuth from "@/hooks/useAuth.ts";
import type ISysUser from "@/domain/iSysUser.ts";

const deptMap = new Map<string, ISysDept>();

interface TableParams {
  page: number;
  pageSize: number;
  total: number;
}

const Dept = () => {
  const {t} = useTranslation();
  const {auth} = useAuth();
  /** 部门信息表单 */
  const formRef = useRef<XinFormRef<ISysDept>>(null);
  /** 新增表单 */
  const modalFormRef = useRef<XinFormRef<ISysDept>>(null);
  /** 当前选中的部门 key */
  const [selectKey, setSelectKey] = useState<string>('');
  /** 当前（多选框）选择的部门 keys */
  const [checkedKeys , setCheckedKeys] = useState<React.Key[]>([]);
  /** 标签页 KEY */
  const [tabKey, setTabKey] = useState<string>('info');
  /** 标签页 Tab */
  const tabList: CardProps['tabList'] = [
    {
      key: 'info',
      label: t("system.dept.tab.info")
    },
    {
      key: 'users',
      label: t("system.dept.tab.users"),
      disabled: !auth("system.dept.users")
    },
  ];
  /** 部门数据 */
  const [deptData, setDeptData] = useState<TreeDataNode[]>([]);
  /** 部门用户列表数据 */
  const [users, setUsers] = useState<ISysUser[]>([]);
  /** 部门用户列表表格参数 */
  const [tableParams, setTableParams] = useState<TableParams>({ page: 1, pageSize: 10, total: 0 });
  /** 加载状态 */
  const [loading, setLoading] = useState<boolean>(false);
  const [tableLoading, setTableLoading] = useState<boolean>(false);
  /** 获取部门用户列表 */
  const selectUsers = async (id: number, params?: TableParams) => {
    try {
      setTableLoading(true);
      const data = await deptUsers(id, omit(params || tableParams, 'total'));
      setUsers(data.data.data!.data);
      setTableParams({
        ...tableParams,
        total: data.data.data!.total
      })
    } finally {
      setTableLoading(false);
    }
  }
  /** 刷新部门数据 */
  const refreshDept = async () => {
    setLoading(true);
    /** 转换部门类型 */
    const convertDeptToTreeData = (depts: ISysDept[]): TreeDataNode[] => {
      if (!depts?.length) return [];
      return depts.map(dept => {
        deptMap.set(dept.id!.toString(), omit(dept, 'children'));
        return {
          title: dept.name || t("system.dept.tab.users"),
          key: dept.id?.toString() || '',
          icon: dept.type === 0 ? <BankOutlined /> : dept.type === 1 ? <TeamOutlined /> : <UserOutlined />,
          children: convertDeptToTreeData(dept.children || [])
        }
      });
    };
    try {
      const res = await queryDept();
      if(res.data.data && res.data.data.length > 0) {
        deptMap.clear();
        setDeptData(convertDeptToTreeData(res.data.data));
        if(!selectKey || !deptMap.has(selectKey)) {
          setSelectKey(res.data.data[0].id!.toString());
          formRef.current?.setFieldsValue(omit(res.data.data[0], 'children'));
          if(auth("system.dept.users")) {
            await selectUsers(res.data.data[0].id!);
          }
        }
      }
    } finally {
      setLoading(false);
    }
  };
  /** 新增部门点击事件 */
  const addChange = (children: boolean = false) => {
    modalFormRef.current?.resetFields();
    modalFormRef.current?.setFieldsValue({
      parent_id: children ? Number(selectKey) : 0,
      sort: 0,
      status: 0,
      type: 0
    })
    modalFormRef.current?.open();
  }
  /** 部门选择事件 */
  const onSelect: TreeProps['onSelect'] = (key) => {
    if(key && key.length >= 1) {
      setSelectKey(key[0].toString());
      const deptInfo = deptMap.get(key[0].toString());
      if (deptInfo) {
        formRef.current?.setFieldsValue(deptInfo);
      }
      selectUsers(Number(key[0])).then();
    }
  }
  /** 部门多选框选中事件 */
  const onCheck: TreeProps['onCheck'] = (checkedKeys) => {
    if(isArray(checkedKeys)) {
      setCheckedKeys(checkedKeys);
    }else {
      setCheckedKeys(checkedKeys.checked);
    }
  }
  /** 表单提交 */
  const onSubmit = async (data: ISysDept, update: boolean = false) => {
    try {
      setLoading(true);
      if(!update) {
        await createDept(data);
        message.success(t("system.dept.createSuccess"));
        modalFormRef.current?.close();
      }else {
        await updateDept(Number(selectKey), data);
        message.success(t("system.dept.updateSuccess"));
      }
      await refreshDept();
    }finally {
      setLoading(false);
    }
  }
  /** 批量删除 */
  const onDeleteConfirm = async () => {
    try {
      setLoading(true);
      await deleteDept(checkedKeys);
      await refreshDept();
      setCheckedKeys([]);
      message.success(t("system.dept.deleteSuccess"));
    }finally {
      setLoading(false);
    }
  }
  /** 表单列数据 */
  const columns: FormColumn<ISysDept>[] = [
    {
      title: t("system.dept.column.name"),
      valueType: 'text',
      dataIndex: 'name',
      rules: [{required: true, message: t("system.dept.column.name.required")}],
    },
    {
      title: t("system.dept.column.code"),
      valueType: 'text',
      dataIndex: 'code',
      rules: [{required: true, message: t("system.dept.column.code.required")}],
    },
    {
      title: t("system.dept.column.type"),
      valueType: 'radioButton',
      dataIndex: 'type',
      fieldProps: {
        options: [
          { value: 0, label: t("system.dept.column.type.0") },
          { value: 1, label: t("system.dept.column.type.1") },
          { value: 2, label: t("system.dept.column.type.2") },
        ],
      },
      rules: [{required: true, message: t("system.dept.column.type.required")}],
    },
    {
      title: t("system.dept.column.parent"),
      valueType: 'treeSelect',
      dataIndex: 'parent_id',
      fieldProps: {
        treeData: [
          {
            title: t("system.dept.column.parent.0"),
            value: 0,
            children: deptData
          }
        ],
        fieldNames: { label: 'title', value: 'key' },
        disabled: true
      },
      rules: [{required: true, message: t("system.dept.column.parent.required")}],
    },
    {
      title: t("system.dept.column.email"),
      valueType: 'text',
      dataIndex: 'email',
    },
    {
      title: t("system.dept.column.address"),
      valueType: 'text',
      dataIndex: 'address',
    },
    {
      title: t("system.dept.column.phone"),
      valueType: 'text',
      dataIndex: 'phone',
    },
    {
      title: t("system.dept.column.sort"),
      valueType: 'digit',
      dataIndex: 'sort',
      rules: [{required: true, message: t("system.dept.column.sort.required")}],
    },
    {
      title: t("system.dept.column.status"),
      valueType: 'radioButton',
      dataIndex: 'status',
      fieldProps: {
        options: [
          { value: 0, label: t("system.dept.column.status.0") },
          { value: 1, label: t("system.dept.column.status.1") },
        ]
      },
      rules: [{required: true, message: t("system.dept.column.status.required")}],
    },
    {
      title: t("system.dept.column.remark"),
      valueType: 'textarea',
      dataIndex: 'remark',
    },
  ];
  /** 部门用户列表表格列 */
  const usersColumns: TableProps<ISysUser>['columns'] = [
    {
      title: t("system.dept.users.column.id"),
      dataIndex: 'id',
      key: 'id',
      align: 'center',
    },
    {
      title: t("system.dept.users.column.username"),
      dataIndex: 'username',
      key: 'username',
      align: 'center',
    },
    {
      title: t("system.dept.users.column.nickname"),
      dataIndex: 'nickname',
      key: 'nickname',
      align: 'center',
    },
    {
      title: t("system.dept.users.column.nickname"),
      dataIndex: 'email',
      key: 'email',
      align: 'center',
    },
    {
      title: t("system.dept.users.column.mobile"),
      dataIndex: 'mobile',
      key: 'mobile',
      align: 'center',
    },
    {
      title: t("system.dept.users.column.status"),
      dataIndex: 'status',
      key: 'status',
      align: 'center',
      render: (value) => (
        <>
          {value === 1 && <Tag color={'success'}>{t("system.dept.users.column.status.0")}</Tag>}
          {value === 0 && <Tag color={'error'}>{t("system.dept.users.column.status.1")}</Tag>}
        </>
      )
    },
  ];
  /** 初始化 */
  useEffect(() => { refreshDept() }, []);

  return (
    <>
      <div className={'mb-5'}>
        <Typography.Title level={3}>{t("system.dept.page.title")}</Typography.Title>
        <Typography.Text type="secondary">{t("system.dept.page.description")}</Typography.Text>
      </div>
      <Row gutter={[20, 20]}>
      <Col xxl={12} lg={12} xs={24}>
        <XinForm<ISysDept>
          layoutType={'ModalForm'}
          formRef={modalFormRef}
          modalProps={{
            title: t("system.dept.createModalTitle"),
            styles: { body: { paddingTop: 20} },
            width: 800
          }}
          onFinish={async (data: ISysDept) => {
            await onSubmit(data, false);
            return true;
          }}
          columns={columns}
          layout={'vertical'}
          grid
          rowProps={{gutter: [30, 0]}}
          colProps={{ span: 12 }}
        />
        <Card
          title={(
            <Space>
              <AuthButton auth={"system.dept.create"}>
                <Button
                  loading={loading}
                  children={t("system.dept.createButton")}
                  icon={<PlusOutlined />}
                  type={'primary'}
                  onClick={() => addChange()}
                />
              </AuthButton>
              <AuthButton auth={"system.dept.create"}>
                <Button
                  loading={loading}
                  children={t("system.dept.createChildrenButton")}
                  icon={<PlusOutlined />}
                  type={'primary'}
                  onClick={() => addChange(true)}
                />
              </AuthButton>
            </Space>
          )}
          variant={'borderless'}
          loading={loading}
          styles={{ body: { minHeight: '70vh' } }}
        >
          {checkedKeys.length > 0 && (
            <Alert
              style={{ marginBottom: 20 }}
              description={t("system.dept.checkedMessage", {checked: checkedKeys.length})}
              type="info"
              action={
                <Space>
                  <Button size="small" type="primary" onClick={()=> setCheckedKeys([])}>
                    {t("system.dept.unselect")}
                  </Button>
                  <AuthButton auth={"system.dept.delete"}>
                    <Popconfirm
                      okText={t("system.dept.delete.ok")}
                      cancelText={t("system.dept.delete.cancel")}
                      title={t("system.dept.delete.title")}
                      description={t("system.dept.delete.description")}
                      onConfirm={() => onDeleteConfirm()}
                    >
                      <Button type="primary" icon={<DeleteOutlined />} size={'small'} danger loading={loading}/>
                    </Popconfirm>
                  </AuthButton>
                </Space>
              }
            />
          )}
          <Tree
            checkable
            treeData={deptData}
            showIcon={true}
            checkStrictly={true}
            selectedKeys={[selectKey]}
            defaultExpandedKeys={[selectKey]}
            onSelect={onSelect}
            checkedKeys={checkedKeys}
            onCheck={onCheck}
          />
        </Card>
      </Col>
      <Col xxl={12} lg={12} xs={24}>
        <Card
          variant={'borderless'}
          tabList={tabList}
          tabProps={{ accessKey: tabKey }}
          onTabChange={setTabKey}
          styles={{ body: { minHeight: '70vh' } }}
        >
          <XinForm<ISysDept>
            formRef={formRef}
            onFinish={async (data: ISysDept) => {
              await onSubmit(data, true);
              return true;
            }}
            columns={columns}
            layout={'horizontal'}
            style={{ display: tabKey === 'info' ? "block" : "none" }}
            submitter={{
              render: (dom) => (
                <AuthButton auth={"system.dept.update"}>
                  {dom['submit']}
                </AuthButton>
              ),
              submitText: t("system.dept.saveInfo")
            }}
          />
          <AuthButton auth={"system.dept.users"}>
            <Table<ISysUser>
              style={{ display: tabKey === 'users' ? "block" : "none" }}
              dataSource={users}
              bordered={true}
              columns={usersColumns}
              loading={tableLoading}
              size={'small'}
              pagination={{
                current: tableParams.page,
                pageSize: tableParams.pageSize,
                total: tableParams.total,
                showSizeChanger: true,
                onChange: (page, pageSize) => {
                  const params = { total: tableParams.total, pageSize, page }
                  setTableParams(params);
                  selectUsers(Number(selectKey), params).then();
                }
              }}
              scroll={{x: 600}}
            />
          </AuthButton>
        </Card>
      </Col>
    </Row>
  </>
  );
};

export default Dept;
