import IconFont from '@/components/IconFont';
import TreeGroup from '@/components/shared/TreeGroup';
import { HTTPSTATUS } from '@/constants';
import {
  apiDeleteGroup,
  apiUpdateGroup,
} from '@/services/master/GroupController';
import {
  DeleteOutlined,
  EditOutlined,
  ExclamationCircleOutlined,
  PlusOutlined,
} from '@ant-design/icons';
import { ProCard, ProDescriptions } from '@ant-design/pro-components';
import { FormattedMessage, useIntl, useModel } from '@umijs/max';
import { Button, Grid, message, Modal } from 'antd';
import { Dropdown, MenuProps, Tooltip } from 'antd/lib';
import { useState } from 'react';
import CreateOrUpdateGroup from './components/CreateOrUpdateGroup';
type MenuItem = Required<MenuProps>['items'][number];
const ManagerGroupPage = () => {
  const { useBreakpoint } = Grid;
  const { initialState } = useModel('@@initialState');
  const { currentUserProfile } = initialState || {};
  const intl = useIntl();
  const screens = useBreakpoint();
  const [selectedItem, setSelectedItem] = useState<
    MasterModel.GroupNode | undefined
  >();
  const [selectedGroup, setSelectedGroup] = useState<
    MasterModel.GroupNode | undefined
  >();

  const { groups, getGroups } = useModel('master.useGroups');
  const [handleChildModal, setHandleChildModal] = useState<boolean>(false);
  const [type, setType] = useState<'create-root' | 'create-child' | 'update'>(
    'create-root',
  );
  const [messageApi, contextHolder] = message.useMessage();
  const [modalKey, setModalKey] = useState(0);

  const findGroupById = (
    groups: MasterModel.GroupNode[],
    id: string,
  ): MasterModel.GroupNode | undefined => {
    for (const group of groups) {
      if (group.id === id) return group;
      if (group.children) {
        const found = findGroupById(group.children, id);
        if (found) return found;
      }
    }
    return undefined;
  };

  const handleUpdate = async (group: Partial<MasterModel.GroupNode>) => {
    const key = 'update_group';
    const { name, description, parent_id, code, short_name } = group;
    const editGroup = parent_id
      ? {
          ...selectedItem,
          name: name,
          parent_id: parent_id,
          metadata: {
            code: code,
            short_name: short_name,
          },
          description: description,
        }
      : {
          ...selectedItem,
          name: name,
          metadata: {
            code: code,
            short_name: short_name,
          },
          description: description,
        };
    try {
      messageApi.open({
        type: 'loading',
        content: intl.formatMessage({
          id: 'common.updating',
          defaultMessage: 'updating...',
        }),
        key,
      });
      await apiUpdateGroup({ ...editGroup });
      messageApi.open({
        type: 'success',
        content: intl.formatMessage({
          id: 'master.groups.update.success',
          defaultMessage: 'Updated successfully',
        }),
        key,
      });
      await getGroups();
      return true;
    } catch (error) {
      messageApi.open({
        type: 'error',
        content: intl.formatMessage({
          id: 'master.groups.update.failed',
          defaultMessage: 'Updating failed, please try again!',
        }),
        key,
      });
      return false;
    }
  };
  const showDeleteConfirm = (group: MasterModel.GroupNode) => {
    Modal.confirm({
      title: intl.formatMessage({
        id: 'master.groups.delete.confirm',
        defaultMessage: 'Are you sure delete this group',
      }),
      content: selectedItem?.name,
      icon: <ExclamationCircleOutlined />,
      okText: intl.formatMessage({ id: 'common.yes', defaultMessage: 'Yes' }),
      okType: 'danger',
      cancelText: intl.formatMessage({ id: 'common.no', defaultMessage: 'No' }),
      async onOk() {
        try {
          const resp = await apiDeleteGroup(group.id);
          if (resp.status === HTTPSTATUS.HTTP_NOCONTENT) {
            messageApi.success(
              intl.formatMessage({
                id: 'master.groups.delete.success',
                defaultMessage: 'Deleted group successfully',
              }),
            );
            setSelectedItem(undefined);
            await getGroups();
          } else if (resp.status === HTTPSTATUS.HTTP_SERVERERROR) {
            messageApi.warning(
              intl.formatMessage({
                id: 'master.groups.delete.failed_internal',
                defaultMessage:
                  'The group contains devices or users and cannot be deleted',
              }),
            );
          } else {
            throw new Error('Delete group failed');
          }
        } catch (error) {
          console.error('Error when delete group ', error);

          messageApi.error(
            intl.formatMessage({
              id: 'master.groups.delete.failed',
              defaultMessage: 'Delete group failed',
            }),
          );
        }
      },
    });
  };
  const onItemClick = ({ key }: { key: string }) => {
    const splitIndex = key.indexOf('-');
    const action = key.substring(0, splitIndex);
    const groupId = key.substring(splitIndex + 1);

    const groupNode = findGroupById(groups || [], groupId);
    console.log('GroupName', groupNode?.name);

    setSelectedItem(groupNode);
    setSelectedGroup(groupNode);
    if (action === '1') {
      setType('create-child');
    } else if (action === '2') {
      setType('update');
    } else if (action === '3') {
      showDeleteConfirm(groupNode!);
      return;
    }

    // Increment modalKey to force remount component
    setModalKey((prev) => prev + 1);
    setHandleChildModal(true);
  };

  return (
    <>
      {contextHolder}

      <CreateOrUpdateGroup
        type={type}
        key={modalKey}
        isOpen={handleChildModal}
        setIsOpen={setHandleChildModal}
        group={selectedGroup}
        message={messageApi}
      />
      <ProCard split={screens.md ? 'vertical' : 'horizontal'}>
        <ProCard
          colSpan={{ xs: 24, sm: 24, md: 10, lg: 10, xl: 10 }}
          extra={[
            currentUserProfile?.metadata?.user_type === 'sysadmin' && (
              <Button
                type="primary"
                key="primary"
                icon={<PlusOutlined />}
                onClick={() => {
                  setType('create-root');
                  setSelectedItem(undefined);
                  setModalKey((prev) => prev + 1);
                  setHandleChildModal(true);
                }}
              >
                <FormattedMessage
                  id="master.groups.root"
                  defaultMessage="Add root"
                />
              </Button>
            ),
          ]}
        >
          <TreeGroup
            titleRender={(item) => {
              const groupNode = findGroupById(groups || [], item.key as string);
              const menus: MenuItem[] = [
                {
                  label: (
                    <Tooltip
                      title={
                        groupNode?.metadata?.has_thing
                          ? intl.formatMessage({
                              id: 'master.groups.cannot-add-group',
                              defaultMessage:
                                'Cannot add child to a group that has things',
                            })
                          : undefined
                      }
                    >
                      {intl.formatMessage({
                        id: 'master.groups.add',
                        defaultMessage: 'Add child',
                      })}
                    </Tooltip>
                  ),
                  key: `1-${groupNode?.id}`,

                  icon: <IconFont type="icon-leaf" />,
                  disabled: groupNode?.metadata?.has_thing === true,
                },
                {
                  label: intl.formatMessage({
                    id: 'common.edit',
                    defaultMessage: 'Update',
                  }),
                  key: `2-${groupNode?.id}`,
                  icon: <EditOutlined />,
                },
                {
                  label: (
                    <Tooltip
                      title={
                        groupNode?.metadata?.has_thing
                          ? intl.formatMessage({
                              id: 'master.groups.delete.failed_internal',
                              defaultMessage:
                                'The group contains devices or users and cannot be deleted',
                            })
                          : undefined
                      }
                    >
                      {intl.formatMessage({
                        id: 'common.delete',
                        defaultMessage: 'Delete',
                      })}
                    </Tooltip>
                  ),
                  key: `3-${groupNode?.id}`,
                  icon: <DeleteOutlined />,
                  disabled: groupNode?.metadata?.has_thing === true,
                },
              ];
              return (
                <Dropdown
                  menu={{
                    items: menus,
                    onClick: onItemClick,
                  }}
                  trigger={['contextMenu']}
                  placement="bottomRight"
                  arrow
                >
                  <span>
                    {typeof item.title === 'function'
                      ? item.title(item)
                      : item.title}
                  </span>
                </Dropdown>
              );
            }}
            multiple={false}
            onSelected={(value: string | string[] | null) => {
              if (!groups) {
                setSelectedItem(undefined);
                return;
              }
              // Find the selected group from model
              if (value && !Array.isArray(value)) {
                const found = findGroupById(groups, value);
                setSelectedItem(found);
              } else {
                setSelectedItem(undefined);
              }
            }}
          />
        </ProCard>
        <ProCard colSpan={{ xs: 24, sm: 24, md: 14, lg: 14, xl: 14 }}>
          {selectedItem?.name && (
            <>
              <ProDescriptions<Partial<MasterModel.GroupNode>>
                column={1}
                bordered
                title={selectedItem.name}
                extra={[
                  <Tooltip
                    key="add"
                    title={
                      selectedItem?.metadata?.has_thing
                        ? intl.formatMessage({
                            id: 'master.groups.cannot-add-group',
                            defaultMessage:
                              'Cannot add child to a group that has things',
                          })
                        : undefined
                    }
                  >
                    <Button
                      key="add"
                      type="primary"
                      icon={<PlusOutlined />}
                      onClick={() => {
                        setType('create-child');
                        setModalKey((prev) => prev + 1);
                        setHandleChildModal(true);
                      }}
                      disabled={
                        selectedItem.metadata?.has_thing === true ? true : false
                      }
                    >
                      <FormattedMessage
                        id="master.groups.add"
                        defaultMessage="Add Group"
                      />
                    </Button>
                  </Tooltip>,
                  <Tooltip
                    key="add-fail"
                    title={
                      selectedItem?.metadata?.has_thing
                        ? intl.formatMessage({
                            id: 'master.groups.delete.failed_internal',
                            defaultMessage:
                              'Cannot add child to a group that has things',
                          })
                        : undefined
                    }
                  >
                    <Button
                      danger
                      key="delete"
                      title={intl.formatMessage({
                        id: 'master.groups.delete.confirm',
                        defaultMessage: 'Delete this group?',
                      })}
                      onClick={() => {
                        showDeleteConfirm(selectedItem);
                      }}
                      icon={<DeleteOutlined />}
                      disabled={
                        selectedItem.metadata?.has_thing === true ? true : false
                      }
                    >
                      <FormattedMessage
                        id="common.delete"
                        defaultMessage="Delete"
                      />
                    </Button>
                    ,
                  </Tooltip>,
                ]}
                dataSource={{
                  name: selectedItem.name,
                  code: selectedItem.metadata?.code || '',
                  short_name: selectedItem.metadata?.short_name || '',
                  description: selectedItem.description || '',
                }}
                columns={[
                  {
                    title: intl.formatMessage({
                      id: 'common.name',
                      defaultMessage: 'Name',
                    }),
                    dataIndex: 'name',
                  },
                  {
                    title: intl.formatMessage({
                      id: 'master.groups.code',
                      defaultMessage: 'Code',
                    }),
                    dataIndex: 'code',
                  },
                  {
                    title: intl.formatMessage({
                      id: 'master.groups.short_name',
                      defaultMessage: 'Short name',
                    }),
                    dataIndex: 'short_name',
                  },
                  {
                    title: intl.formatMessage({
                      id: 'common.description',
                      defaultMessage: 'Description',
                    }),
                    dataIndex: 'description',
                  },
                ]}
                editable={{
                  onSave: async (_, record) => {
                    const updatedData: MasterModel.GroupNode = {
                      ...selectedItem,
                      name: record.name || '',
                      description: record.description || '',
                      metadata: {
                        ...selectedItem.metadata,
                        code: record.code,
                        short_name: record.short_name,
                      },
                    };
                    const success = await handleUpdate(updatedData);
                    if (success) {
                      setSelectedItem(updatedData);
                      return true;
                    }
                    return false;
                  },
                }}
              />
            </>
          )}
        </ProCard>
      </ProCard>
    </>
  );
};

export default ManagerGroupPage;
