import { DEFAULT_PAGE_SIZE, DURATION_POLLING } from '@/constants';
import { apiSearchThings } from '@/services/master/ThingController';
import {
  ActionType,
  ProCard,
  ProColumns,
  ProTable,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Grid, Modal, Typography } from 'antd';
import { useEffect, useRef, useState } from 'react';
import TreeGroup from './TreeGroup';

const { Paragraph } = Typography;
type ThingsFilterProps = {
  title?: string;
  isOpen?: boolean;
  setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
  thingIds?: string | string[] | null;
  extra?: React.ReactNode;
  onSubmit?: (thingIds: string[]) => void;
  disabled?: boolean;
};

const ThingsFilter = ({
  title,
  isOpen,
  setIsOpen,
  thingIds,
  extra,
  onSubmit,
  disabled = false,
}: ThingsFilterProps) => {
  const intl = useIntl();
  const { useBreakpoint } = Grid;
  const screens = useBreakpoint();
  const tableRef = useRef<ActionType>();
  const [groupsIds, setGroupIds] = useState<string | string[] | null>(null);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const domain = process.env.DOMAIN_ENV || 'gms';
  useEffect(() => {
    if (thingIds) {
      const ids = Array.isArray(thingIds) ? thingIds : [thingIds];
      setSelectedRowKeys(ids);
    } else {
      setSelectedRowKeys([]);
    }
  }, [thingIds]);

  const handleOk = () => {
    onSubmit?.(selectedRowKeys as string[]);
    setIsOpen(false);
  };

  const handleCancel = () => {
    setIsOpen(false);
  };
  const columns: ProColumns<MasterModel.Thing>[] = [
    {
      key: 'name',
      title: <FormattedMessage id="master.thing.name" defaultMessage="Name" />,
      dataIndex: 'name',
    },
    {
      key: 'external_id',
      title: (
        <FormattedMessage
          id="master.thing.external_id"
          defaultMessage="External ID"
        />
      ),
      dataIndex: 'metadata.external_id',
      render: (_, record) =>
        record?.metadata?.external_id ? (
          <Paragraph
            style={{
              marginBottom: 0,
              verticalAlign: 'middle',
              display: 'inline-block',
            }}
            copyable
          >
            {record?.metadata?.external_id}
          </Paragraph>
        ) : (
          '-'
        ),
    },
    {
      key: 'address',
      title: (
        <FormattedMessage id="master.thing.address" defaultMessage="Address" />
      ),
      dataIndex: 'metadata.address',
      hideInSearch: true,
      render: (_, record) => record?.metadata?.address || '-',
    },
  ];
  return (
    <Modal
      title={title ? title : null}
      open={isOpen}
      centered
      width="80%"
      onOk={handleOk}
      onCancel={handleCancel}
      maskClosable={false}
      okText={<FormattedMessage id="common.search" defaultMessage="Search" />}
      cancelText={
        <FormattedMessage id="common.cancel" defaultMessage="Cancel" />
      }
    >
      <ProCard
        split={screens.md ? 'vertical' : 'horizontal'}
        extra={extra ? extra : null}
      >
        <ProCard colSpan={{ xs: 24, sm: 8, md: 8, lg: 6, xl: 6 }}>
          <TreeGroup
            disable={isLoading}
            multiple
            onSelected={(value) => {
              setGroupIds(value);
              tableRef.current?.reload();
            }}
          />
        </ProCard>
        <ProCard colSpan={{ xs: 24, sm: 16, md: 16, lg: 18, xl: 18 }}>
          <ProTable<MasterModel.Thing>
            tableClassName="table-row-select cursor-pointer-row"
            actionRef={tableRef}
            toolbar={{
              title: null,
            }}
            bordered={true}
            polling={DURATION_POLLING * 4} // 1 minute
            rowSelection={{
              alwaysShowAlert: true,
              selectedRowKeys,
              onChange: (keys) => setSelectedRowKeys(keys),
              getCheckboxProps: (record) => ({
                disabled:
                  disabled && thingIds && record.id
                    ? (Array.isArray(thingIds)
                        ? thingIds
                        : [thingIds]
                      ).includes(record.id)
                    : false,
              }),
            }}
            pagination={{
              size: 'small',
              defaultPageSize: DEFAULT_PAGE_SIZE * 2,
              showSizeChanger: true,
              pageSizeOptions: ['10', '15', '20'],
              showTotal: (total, range) =>
                `${range[0]}-${range[1]} ${intl.formatMessage({
                  id: 'common.paginations.of',
                })} ${total} ${intl.formatMessage({
                  id: 'common.paginations.things',
                  defaultMessage: 'things',
                })}`,
            }}
            columns={columns}
            request={async (params) => {
              setIsLoading(true);
              const { current = 1, pageSize, name, external_id } = params;
              const size = pageSize || DEFAULT_PAGE_SIZE * 2;
              const offset = current === 1 ? 0 : (current - 1) * size;
              const query: MasterModel.SearchThingPaginationBody = {
                offset: offset,
                limit: size,
                order: 'name',
                dir: 'asc',
              };
              if (name) {
                query.name = name;
              }
              if (!query.metadata) query.metadata = {};
              if (groupsIds)
                query.metadata.group_id = Array.isArray(groupsIds)
                  ? groupsIds.join(',')
                  : groupsIds || undefined;

              if (external_id) {
                query.metadata = {
                  ...query.metadata,
                  external_id: external_id,
                };
              }
              const resp = await apiSearchThings(query, domain);
              setIsLoading(false);
              return {
                data: resp.things || [],
                success: true,
                total: resp.total || 0,
              };
            }}
            options={{
              search: false,
              setting: false,
              density: false,
              reload: true,
            }}
            defaultSize="small"
            rowKey="id"
            dateFormatter="string"
          />
        </ProCard>
      </ProCard>
    </Modal>
  );
};

export default ThingsFilter;
