import { ProFormCheckbox } from '@ant-design/pro-form';
import { Alert, Button, Card, Checkbox, Drawer, Form, Space, Spin, Tabs } from 'antd';
import _ from 'lodash';
import { cloneElement, isValidElement, useCallback, useEffect, useMemo, useState } from 'react';
import { FormattedMessage, useIntl, useRequest } from 'umi';
import List from './List';
import UserDepart from './UserDepart';

const PermissionManage = ({
  isCreate = false,
  userId,
  appId,
  manualOpen = false,
  setManualOpen = () => {},
  children,
  onFinish,
}: {
  isCreate?: boolean;
  userId?: number;
  appId: number;
  manualOpen?: boolean;
  setManualOpen?: (open: boolean) => void;
  children?: React.ReactElement<{ onClick: () => void }>;
  onFinish?: () => void;
}) => {
  const [form] = Form.useForm();
  const [open, setOpen] = useState(false);
  const { formatMessage } = useIntl();
  const [activeKey, setActiveKey] = useState('_UacPermissionFeature');
  const [values, setValues] = useState({});
  const menuMap = useMemo(
    () => ({
      _UacPermissionFeature: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.feature',
        defaultMessage: '功能权限',
      }),
      _UacPermissionFlag: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.flag',
        defaultMessage: '数据管理',
      }),
      _UacPermissionPolicy: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.policy',
        defaultMessage: '策略管理',
      }),
      _UacPermissionRole: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.role',
        defaultMessage: '角色管理',
      }),
      _UacPermissionUser: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.user',
        defaultMessage: '用户管理',
      }),
      _UacPermissionTemplate: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.template',
        defaultMessage: '审批模版管理',
      }),
      _UacPermissionAudit: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.audit',
        defaultMessage: '审计',
      }),
      _UacPermissionAuditRequest: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.auditRequest',
        defaultMessage: '申请单管理',
      }),
      _UacPermissionLog: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.log',
        defaultMessage: '日志',
      }),
      _UacPermissionSetting: formatMessage({
        id: 'components.ManageAdmin.permissionManage.menu.setting',
        defaultMessage: '设置',
      }),
      // _UacPermissionGroup: '',
      // _UacPermissionTask: '',
    }),
    [],
  );
  const menuDisabled = {
    _UacPermissionAudit: true,
    _UacPermissionLog: true,
    _UacPermissionSetting: true,
  };
  const menuRender = {
    _UacPermissionFeature: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionFeatureValues">
        <List appId={appId} disabled={disabled} type="_UacPermissionFeature" show={show} />
      </Form.Item>
    ),
    _UacPermissionFlag: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionFlagValues">
        <List
          appId={appId}
          disabled={disabled}
          type="_UacPermissionFlag"
          show={show}
          isLevel={false}
        />
      </Form.Item>
    ),
    _UacPermissionPolicy: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionPolicyValues">
        <List
          appId={appId}
          disabled={disabled}
          type="_UacPermissionPolicy"
          show={show}
          isLevel={false}
        />
      </Form.Item>
    ),
    _UacPermissionRole: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionRoleValues">
        <List
          appId={appId}
          disabled={disabled}
          type="_UacPermissionRole"
          show={show}
          isLevel={false}
        />
      </Form.Item>
    ),
    _UacPermissionUser: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionUserValues">
        <UserDepart show={show} disabled={disabled} appId={appId} />
      </Form.Item>
    ),
    _UacPermissionTemplate: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionTemplateValues">
        <List
          appId={appId}
          disabled={disabled}
          type="_UacPermissionTemplate"
          show={show}
          isLevel={false}
        />
      </Form.Item>
    ),
    _UacPermissionAuditRequest: (show, disabled) => (
      <Form.Item noStyle name="_UacPermissionAuditRequestValues">
        <UserDepart show={show} disabled={disabled} appId={appId} />
      </Form.Item>
    ),
  };
  const { data, run } = useRequest(
    {
      url: '/goapi/app/action',
      data: { appId },
      method: 'POST',
    },
    {
      manual: true,
    },
  );
  const { data: userPermissions, run: runUserPermissions } = useRequest(
    {
      url: '/goapi/app/user/permission/detail',
      data: { userId, appId },
      method: 'POST',
    },
    {
      manual: true,
    },
  );
  const { loading: saveLoading, run: runSave } = useRequest(
    (d) => ({
      url: '/goapi/app/user/permission/update',
      method: 'POST',
      data: d,
    }),
    {
      manual: true,
    },
  );
  const { loading: addLoading, run: runAddUser } = useRequest(
    (userIds) => ({
      url: '/goapi/app/managerUser/add',
      method: 'POST',
      data: {
        appId,
        userIds,
      },
    }),
    {
      manual: true,
    },
  );
  const onClose = () => {
    setOpen(false);
    setManualOpen(false);
  };
  const triggerRender = () => {
    if (!isValidElement(children)) {
      if (!isCreate) {
        return (
          <a onClick={() => setOpen(true)}>
            <FormattedMessage id="components.ManageAdmin.management" defaultMessage="权限管理" />
          </a>
        );
      } else {
        return <> </>;
      }
    }

    return cloneElement(children, {
      onClick: () => {
        setOpen(true);
      },
    });
  };
  const onValuesChange = useCallback(
    (changedValues, allValues) => {
      // 根据全选来设置其他权限
      if (!_.isUndefined(changedValues.all)) {
        const filedsval = _.fromPairs([
          ..._.map(_.keys(menuMap), (key) => [key, changedValues.all]),
          ..._.map(_.keys(menuMap), (key) => [`${key}All`, changedValues.all]),
          ..._.map(_.keys(menuMap), (key) => [`${key}Values`, { data: [], type: 'User' }]),
        ]);
        form?.setFieldsValue(filedsval);
        setValues((val) => ({ ...val, ...filedsval }));
      } else if (menuMap[_.keys(changedValues)?.[0]]) {
        // 根据其他按钮的勾选来设置全选
        let isAll = true;
        if (!_.values(changedValues)?.[0]) {
          isAll = false;
        } else {
          _.keys(menuMap)?.forEach((item) => {
            if (!allValues[item]) {
              isAll = false;
            }
          });
        }
        const filedsval = {
          all: isAll,
          [`${_.keys(changedValues)?.[0]}All`]: _.values(changedValues)?.[0],
          [`${_.keys(changedValues)?.[0]}Values`]: { data: [], type: 'User' },
        };
        form?.setFieldsValue(filedsval);
        setValues((val) => ({ ...val, ...changedValues, ...filedsval }));
      } else {
        setValues((val) => ({ ...val, ...changedValues }));
      }
    },
    [form, menuMap],
  );
  useEffect(() => {
    if (manualOpen) {
      setOpen(manualOpen);
    }
  }, [manualOpen, setOpen]);
  useEffect(() => {
    if (open) {
      run().then((d) => setActiveKey(d?.[0]?.value));
      runUserPermissions();
    }
  }, [open, run, runUserPermissions]);
  useEffect(() => {
    if (isCreate) {
      // 创建进来默认全选
      const filedsval = _.fromPairs([
        ..._.map(
          _.keys(menuMap)?.filter((item) => menuMap[item]),
          (key) => [key, true],
        ),
        ..._.map(
          _.keys(menuMap)?.filter((item) => menuMap[item]),
          (key) => [`${key}All`, true],
        ),
        ..._.map(
          _.keys(menuMap)?.filter((item) => menuMap[item]),
          (key) => [`${key}Values`, { data: [], type: 'User' }],
        ),
      ]);
      filedsval.all = true;
      form?.setFieldsValue(filedsval);
      setValues(filedsval);
    } else {
      // 编辑进来需要看有哪些权限，再判断是否有全部
      const { action, resource } = userPermissions || {};
      if (action) {
        const filedsval = _.fromPairs([
          ..._.map(
            _.keys(menuMap)?.filter((item) => menuMap[item]),
            (key) => [key, action.includes(key) ? true : false],
          ),
          ..._.map(
            _.keys(menuMap)?.filter((item) => menuMap[item]),
            (key) => [`${key}All`, resource[key]?.allowAll || false],
          ),
          ..._.map(
            _.keys(menuMap)?.filter((item) => menuMap[item]),
            (key) => [
              `${key}Values`,
              { data: resource[key]?.permissionId?.map((id) => ({ id: `${id}` })), type: 'User' },
            ],
          ),
        ]);
        if (resource?.['_UacPermissionAuditRequestDepart']) {
          filedsval['_UacPermissionAuditRequestValues'] = {
            data: resource?.['_UacPermissionAuditRequestDepart']?.permissionId?.map((id) => ({
              id: `${id}`,
            })),
            type: 'Depart',
          };
        }
        if (resource?.['_UacPermissionDepart']) {
          filedsval['_UacPermissionUserValues'] = {
            data: resource?.['_UacPermissionDepart']?.permissionId?.map((id) => ({ id: `${id}` })),
            type: 'Depart',
          };
        }
        let isAll = true;
        _.keys(menuMap)?.forEach((item) => {
          if (!action?.includes(item)) {
            isAll = false;
          }
        });
        filedsval.all = isAll;
        form?.setFieldsValue(filedsval);
        setValues(filedsval);
      }
    }
  }, [userPermissions, form, menuMap, isCreate]);
  const CustomCheckbox = ({
    disabled,
    value,
    onChange,
    label,
  }: {
    disabled?: boolean;
    value?: boolean;
    onChange?: (e?: boolean) => void;
    label: string;
  }) => {
    return (
      <Space>
        <Checkbox
          disabled={disabled}
          checked={value}
          onChange={(e) => onChange?.(e?.target?.checked)}
        />
        {label}
      </Space>
    );
  };
  return (
    <>
      {triggerRender()}
      <Drawer
        width={840}
        maskClosable={false}
        bodyStyle={{ paddingLeft: 0, paddingRight: 0 }}
        title={
          <FormattedMessage
            id="components.ManageAdmin.PermissionManage.title"
            defaultMessage="权限管理"
          />
        }
        footerStyle={{ textAlign: 'right' }}
        footer={
          saveLoading || addLoading ? (
            <Spin />
          ) : (
            <Button
              disabled={saveLoading || addLoading}
              type="primary"
              onClick={async () => {
                if (isCreate) {
                  await runAddUser([userId]);
                }
                // values
                const action: string[] = [];
                const resource: string[] = [];
                _.keys(menuMap).forEach((item) => {
                  // todo
                  // 首先拿到菜单权限
                  if (values[item]) {
                    action.push(item);
                    // 再看看是否勾了全部
                    if (values[`${item}All`]) {
                      resource.push(`${item}:*`);
                    } else {
                      // 否则就要查看其他权限
                      if (values[`${item}Values`]?.type !== 'Depart') {
                        values[`${item}Values`]?.data?.forEach((obj) =>
                          resource.push(`${item}:${obj.id}`),
                        );
                      } else {
                        let name = item + 'Depart';
                        if (item === '_UacPermissionUser') {
                          name = '_UacPermissionDepart';
                        }
                        values[`${item}Values`]?.data?.forEach((obj) =>
                          resource.push(`${name}:${obj.id}`),
                        );
                      }
                    }
                  }
                });
                await runSave({
                  appId,
                  userId,
                  policyDetail: [
                    {
                      version: '2',
                      statement: [
                        {
                          action: action,
                          effect: 'Allow',
                          condition: [],
                          resource: resource,
                        },
                      ],
                    },
                  ],
                });
                onClose();
                onFinish?.();
              }}
            >
              {formatMessage({ id: 'public.btn.ok' })}
            </Button>
          )
        }
        onClose={onClose}
        open={open}
      >
        <Card bordered={false} bodyStyle={{ paddingTop: 0 }}>
          <Space direction="vertical" style={{ width: '100%' }}>
            <Alert
              message={formatMessage({ id: 'components.ManageAdmin.permissionManage.alert' })}
              type="warning"
              showIcon
              closable
            />
            <Form form={form} onValuesChange={onValuesChange}>
              <ProFormCheckbox
                label={formatMessage({ id: 'components.ManageAdmin.permissionManage.all' })}
                name="all"
              />
              <Tabs tabPosition="left" activeKey={activeKey} onChange={(key) => setActiveKey(key)}>
                {data
                  ?.filter((item) => menuMap[item?.value])
                  ?.map((item) => {
                    const { value } = item;
                    return (
                      <Tabs.TabPane
                        key={value}
                        disabled={menuDisabled[value]}
                        tab={
                          <Form.Item noStyle name={value}>
                            <CustomCheckbox label={menuMap[value]} />
                          </Form.Item>
                        }
                      >
                        <Space direction="vertical" style={{ width: '100%' }}>
                          <Form.Item noStyle name={`${value}All`}>
                            <CustomCheckbox
                              label={formatMessage({
                                id: 'components.ManageAdmin.permissionManage.all',
                              })}
                              disabled={!values[value]}
                            />
                          </Form.Item>
                          {menuRender[value]?.(
                            activeKey === value,
                            values[`${value}All`] || !values[value],
                          )}
                        </Space>
                      </Tabs.TabPane>
                    );
                  })}
              </Tabs>
            </Form>
          </Space>
        </Card>
      </Drawer>
    </>
  );
};

export default PermissionManage;
