import PageHeader from '@/components/PageHeader';
import SearchTable from '@/components/SearchTable';
import MenuStatus from '@/components/StatusCollection';
import { MENU_EDIT, MENU_PAGE } from '@/services/Urls';
import { updateData } from '@/services/common/components';
import { getAccessInfo } from '@/services/common/login';
import {
  findMenus,
  importMenus,
  sortsMenus,
  statusMenus,
} from '@/services/common/menus';
import PremissBtn from '@/utils/btnPermissions';
import {
  DownOutlined,
  ExclamationCircleFilled,
  PlusOutlined,
} from '@ant-design/icons';
import type { ProColumns } from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useModel, useMutation } from '@umijs/max';
import type { MenuProps } from 'antd';
import {
  Button,
  Dropdown,
  Input,
  Modal,
  Popconfirm,
  Select,
  Space,
} from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import routes from '../../../../config/routes';
import MenuSettingForm from './components/Setting';
import { iconFront } from './components/iconfont';
import './index.less';

type TableListItem = {
  [key: string]: any;
};

const isDev = process.env.NODE_ENV === 'development';
let loading = false;
const MenuManageMent: React.FC = () => {
  const intl = useIntl();
  const meunMes: any = useRef();
  const { setInitialState } = useModel('@@initialState');
  const [reloadNum, setReloadNum] = useState<number>(0);
  const [submitHandle, setSubmitHandle] = useState<number>(0);
  const [visible, setVisible] = useState<boolean>(false);
  const [isEdit, setIsEdit] = useState<boolean>(false);
  const [isAddChild, setIsAddChild] = useState<boolean>(false);
  const [editData, setEditData] = useState<TableListItem>({});
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [disableEnable, setdisableEnable] = useState<any>();
  const [sortType, setSortType] = useState<any>();
  const [searchTerms, setSearchTerms] = useState<any>([]);
  const [searchParams, setSearchParams] = useState<any>({});
  const [searchName, setSearchName] = useState<string>('');
  const [searchStatus, setSearchStatus] = useState<any>('');

  //权限获得
  const fetchAccessInfo = async () => {
    const userInfoRes = await getAccessInfo();
    const data: any = {};
    if (userInfoRes.data) {
      for (const item of userInfoRes.data) {
        data[item] = true;
      }
    }
    return data;
  };

  //更改菜单更新侧边栏菜单
  const updateMenu = async () => {
    localStorage.removeItem('menuData');
    const access: any = await fetchAccessInfo();
    setInitialState((initialState) => ({
      ...initialState,
      accessInfo: access,
      currentUser: {
        ...initialState?.currentUser,
        menuUpdate: !initialState?.currentUser?.menuUpdate,
      },
    }));
  };

  //菜单基础信息获取
  const findMeunMes = (menuId: string | number) => {
    findMenus({ menuId }).then((resp) => {
      const data = resp.data;
      meunMes.current = { version: data.version, status: !data.status };
    });
  };

  //菜单位置排序
  const sortMeuns = (data: any) => {
    sortsMenus(data).then(() => {
      const query = { id: data.menuId, type: data.type };
      setSortType(query);
      updateMenu();
    });
  };

  //其他操作
  const DropdownItems = (record: any, index: any) => {
    const items: MenuProps['items'] = [
      {
        label: (
          <div
            onClick={() => {
              if (index !== 0)
                sortMeuns({ menuId: record.menuId, type: 'top' });
            }}
          >
            {intl.formatMessage({ id: 'columns.handel.top' })}
          </div>
        ),
        key: 'top',
        disabled: index === 0,
      },
      {
        label: (
          <div
            onClick={() => {
              if (index !== 0)
                sortMeuns({ menuId: record.menuId, type: 'prev' });
            }}
          >
            {intl.formatMessage({ id: 'columns.handel.pre' })}
          </div>
        ),
        key: 'advance',
        disabled: index === 0,
      },
      {
        label: (
          <div
            onClick={() => {
              if (!record.finally)
                sortMeuns({ menuId: record.menuId, type: 'bottom' });
            }}
          >
            {intl.formatMessage({ id: 'columns.handel.bottom' })}
          </div>
        ),
        key: 'bottom',
        disabled: record.finally,
      },

      {
        label: (
          <div
            onClick={() => {
              if (!record.finally)
                sortMeuns({ menuId: record.menuId, type: 'next' });
            }}
          >
            {intl.formatMessage({ id: 'columns.handel.next' })}
          </div>
        ),
        key: 'retreat',
        disabled: record.finally,
      },
    ];
    return items;
  };

  // 禁用启用
  const disEnAble = (record: any) => {
    findMeunMes(record.menuId);
    setTimeout(() => {
      const data = { menuId: record.menuId, ...meunMes.current };
      statusMenus(data).then(() => {
        setdisableEnable({ id: record.menuId, status: record.status });
        updateMenu();
      });
    }, 500);
  };

  // 搜索框值改变
  const onSearchNameChange = (e: any) => {
    setSearchName(e.target.value);
  };

  const onSearchStatusChange = (e: any) => {
    setSearchStatus(e);
  };

  // 重置输入框
  const onResetSearch = () => {
    setSearchName('');
    setSearchStatus('');
    setSearchParams({});
  };

  useEffect(() => {
    const searchObj: { name?: string; status?: string } = {};
    if (searchName !== '') {
      searchObj.name = searchName;
    }

    if (searchStatus !== '') {
      searchObj.status = searchStatus;
    }

    setSearchParams(searchObj);
  }, [searchName, searchStatus]);

  const columns: ProColumns<TableListItem>[] = [
    {
      title: intl.formatMessage({ id: 'menu.columns.title.name' }),
      dataIndex: 'name',
      key: 'name',
      hideInTable: true,
      renderFormItem: () => {
        return (
          <Input
            allowClear
            onChange={onSearchNameChange}
            placeholder={intl.formatMessage({
              id: 'form.info.text.entrt',
              defaultMessage: '请输入',
            })}
          />
        );
      },
    },
    {
      title: intl.formatMessage({ id: 'menu.columns.title.name' }),
      dataIndex: 'name',
      key: 'name',
      fixed: 'left',
      search: false,
      width: 250,
      ellipsis: true,
      renderText: (_, { icon, name, status }) => {
        return (
          <div className={!status ? '' : 'color-disable'}>
            <span style={{ margin: '0 8px' }}>{iconFront[icon]}</span>
            {name}
          </div>
        );
      },
    },

    {
      title: intl.formatMessage({ id: 'menu.columns.title.privilegeUrl' }),
      dataIndex: 'path',
      search: false,
      key: 'path',
      width: 250,
      render: (_, { path, status }) => {
        return <div className={!status ? '' : 'color-disable'}>{path}</div>;
      },
    },
    {
      title: intl.formatMessage({ id: 'menu.columns.title.status' }),
      dataIndex: 'status',
      key: 'status',
      valueType: 'select',
      width: 200,
      valueEnum: {
        0: intl.formatMessage({ id: 'columns.handel.enable' }),
        1: intl.formatMessage({ id: 'columns.handel.disabled' }),
      },
      render: (_, { status }) => <MenuStatus code={status} />,
      renderFormItem: () => {
        return (
          <Select
            allowClear
            onChange={onSearchStatusChange}
            options={[
              { value: 0, label: intl.formatMessage({ id: 'columns.handel.enable' }) },
              { value: 1, label: intl.formatMessage({ id: 'columns.handel.disabled' }) },
            ]}
            placeholder={intl.formatMessage({
              id: 'form.info.text.selected',
              defaultMessage: '请选择',
            })}
          />
        );
      },
    },
    {
      title: intl.formatMessage({ id: 'menu.columns.title.menuType' }),
      dataIndex: 'menuType',
      search: false,
      key: 'menuType',
      width: 200,
      render: (_, { menuType, status }) => {
        return <div className={!status ? '' : 'color-disable'}>{menuType}</div>;
      },
    },
    {
      title: intl.formatMessage({ id: 'columns.title.option' }),
      valueType: 'option',
      key: 'option',
      fixed: 'right',
      width: 180,
      render: (_, record, index) => [
        <div key="option">
          <PremissBtn
            buttonKey={'menuEdit'}
            buttonRender={
              <Button
                size="small"
                type="link"
                key="editable"
                disabled={record.status}
                onClick={() => {
                  setVisible(true);
                  setIsEdit(true);
                  setEditData(record);
                }}
              >
                {intl.formatMessage({ id: 'columns.handel.edit' })}
              </Button>
            }
          />

          <PremissBtn
            buttonKey={'menuDisable/menuEnable'}
            buttonRender={
              <Popconfirm
                title={intl.formatMessage({
                  id: !record.status ? 'columns.handel.disabled' : 'columns.handel.enable',
                })}
                description={`${intl.formatMessage({
                  id: !record.status ? 'modal.text.disableMes' : 'modal.text.enableMes',
                })}${record.name}?`}
                onConfirm={() => disEnAble(record)}
                okText={intl.formatMessage({ id: 'columns.handel.ok' })}
                cancelText={intl.formatMessage({ id: 'columns.handel.cancel' })}
                disabled={
                  record.access === 'menu' ||
                  record.access === 'menuDisable/menuEnable'
                }
              >
                <Button
                  size="small"
                  type="link"
                  disabled={
                    record.access === 'menu' ||
                    record.access === 'menuDisable/menuEnable'
                  }
                >
                  {intl.formatMessage({
                    id: !record.status ? 'columns.handel.disabled' : 'columns.handel.enable',
                  })}
                </Button>
              </Popconfirm>
            }
          />

          <PremissBtn
            buttonKey={'menuSort'}
            buttonRender={
              record.menuType !== 'button' &&
              record.menuType !== 'detailPage' ? (
                <Dropdown
                  disabled={record.status}
                  menu={{ items: DropdownItems(record, index) }}
                  key="other"
                  placement="bottomRight"
                  arrow
                >
                  <a onClick={(e) => e.preventDefault()} className="dropdown-a">
                    {intl.formatMessage({ id: 'columns.handel.sort' })}
                    <DownOutlined className="down-outlined" />
                  </a>
                </Dropdown>
              ) : null
            }
          />
        </div>,
      ],
    },
  ];

  // 关闭抽屉
  const onDrawerClose = () => {
    setVisible(false);
    setIsEdit(false);
    setIsAddChild(false);
    setSubmitHandle(0);
    setEditData({});
  };

  const { mutate } = useMutation(updateData, {
    onSuccess: async () => {
      setIsLoading(false);
      onDrawerClose();
      setReloadNum((reloadNum) => reloadNum + 1);
      updateMenu();
    },
    onError: () => setIsLoading(false),
  });

  // 添加或者编辑
  const onAddOREdit = (values: { [key: string]: any }) => {
    // 处理数据
    setIsLoading(true);
    //连接后端接口，阻止重复提交，提交接口数据
    mutate({ url: MENU_EDIT, values });
  };

  //菜单数据替换处理
  const replaceKey = (data: any, oldKey: string, newKey: string) => {
    if (Array.isArray(data)) {
      data.forEach((item) => replaceKey(item, oldKey, newKey));
    } else if (typeof data === 'object' && data !== null) {
      if (data.hasOwnProperty(oldKey)) {
        data[newKey] = data[oldKey];
        delete data[oldKey];
      }
      Object.values(data).forEach((value) => replaceKey(value, oldKey, newKey));
    }
  };

  //菜单数据处理
  const mergeButtonsToRoutes = (data: any) => {
    data.forEach((value: any) => {
      if (value.buttons) {
        if (value.routes) {
          value.routes = value.routes.concat(value.buttons);
        } else {
          value.routes = value.buttons;
        }
        delete value.buttons;
      }
      if (value.routes) {
        mergeButtonsToRoutes(value.routes);
      }
    });
  };

  //导入菜单
  const importMenu = () => {
    if (loading) {
      return;
    }
    loading = true;
    Modal.confirm({
      title: <div>{intl.formatMessage({ id: 'menu.text.importMenu' })}</div>,
      icon: <ExclamationCircleFilled />,
      content: <>{intl.formatMessage({ id: 'menu.info.text.importMenuMes' })}</>,
      cancelText: intl.formatMessage({ id: 'columns.handel.cancel' }),
      okText: intl.formatMessage({ id: 'columns.handel.ok', defaultMessage: 'OK' }),
      onOk() {
        const routeDate = [...routes];
        const newRoute = routeDate.slice(0, routeDate.length - 5);
        mergeButtonsToRoutes(newRoute);
        replaceKey(newRoute, 'key', 'access');
        importMenus(newRoute).then(() => {
          setReloadNum((reloadNum) => reloadNum + 1);
          updateMenu();
          loading = false;
        });
      },
      onCancel() {
        loading = false;
      },
    });
  };

  return (
    <div>
      <PageHeader />

      <Modal
        destroyOnClose={true}
        title={intl.formatMessage({
          id: !isEdit ? 'menu.setting.title.add' : 'menu.setting.title.edit',
        })}
        footer={
          <div className="text-right">
            <Space>
              <Button onClick={onDrawerClose}>
                <FormattedMessage
                  id="form.handel.cancel"
                  defaultMessage="取消"
                />
              </Button>
              <Button
                onClick={() => setSubmitHandle(submitHandle + 1)}
                type="primary"
                loading={isLoading}
              >
                <FormattedMessage id="form.handel.save" defaultMessage="保存" />
              </Button>
            </Space>
          </div>
        }
        closable={true}
        open={visible}
        onCancel={onDrawerClose}
      >
        <div className="menu-edit">
          <MenuSettingForm
            isAddChild={isAddChild}
            onSave={onAddOREdit}
            initialValues={editData}
            isEdit={isEdit}
            handelSubmit={submitHandle}
          />
        </div>
      </Modal>

      <SearchTable
        headerTitle={intl.formatMessage({ id: 'columns.title.header' })}
        reload={reloadNum}
        columns={columns}
        rowKey={'menuId'}
        searchParams={searchParams}
        onResetSearch={onResetSearch}
        toolBarRender={() => [
          <PremissBtn
            key="primary"
            buttonKey={'menu'}
            buttonRender={
              isDev ? (
                <Button onClick={() => importMenu()} type="primary">
                  <PlusOutlined className="margin-r-s" />
                  {intl.formatMessage({ id: 'menu.text.importMenu' })}
                </Button>
              ) : null
            }
          />,
        ]}
        initAPI={MENU_PAGE}
        disableEnable={disableEnable}
        sortType={sortType}
        pageParams={{ pageSize: 999 }}
        lastTable={true}
        tableProps={{
          expandable: {
            childrenColumnName: 'routes',
            onExpandedRowsChange: (keys: any) => setSearchTerms(keys),
            expandedRowKeys: searchTerms,
          },
        }}
        setSearchTerms={(ele) => setSearchTerms(ele)}
        extendedMenus={2}
      />
    </div>
  );
};
export default MenuManageMent;
