import { DATE_TIME_FORMAT, DEFAULT_PAGE_SIZE } from '@/constants';
import { apiQueryLogs } from '@/services/master/LogController';
import { apiQueryUsers } from '@/services/master/UserController';
import { ActionType, ProColumns, ProTable } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { theme } from 'antd';
import { DatePicker } from 'antd/lib';
import dayjs from 'dayjs';
import { useRef } from 'react';
import LogActions from './components/LogActions';

const SystemLogs = () => {
  const intl = useIntl();
  const tableRef = useRef<ActionType>();
  const { token } = theme.useToken();

  const queryUserSource = async (): Promise<MasterModel.UserResponse[]> => {
    try {
      const body: MasterModel.SearchUserPaginationBody = {
        offset: 0,
        limit: 100,
        order: 'email',
        dir: 'asc',
      };
      const resp = await apiQueryUsers(body);
      return resp?.users ?? [];
    } catch {
      return [];
    }
  };
  const columns: ProColumns<MasterModel.Message>[] = [
    {
      title: intl.formatMessage({
        id: 'master.logs.date.text',
        defaultMessage: 'Date',
      }),
      key: 'dateTimeRange',
      dataIndex: 'time',
      width: '20%',
      valueType: 'dateTimeRange',
      initialValue: [dayjs().add(-1, 'day'), dayjs()],
      search: {
        transform: (value) => ({ startTime: value[0], endTime: value[1] }),
      },
      render: (_, row) => {
        return dayjs.unix(row?.time || 0).format(DATE_TIME_FORMAT);
      },
      renderFormItem: (_, config, form) => {
        return (
          <DatePicker.RangePicker
            width="50%"
            style={{
              backgroundColor: token.colorBgContainer,
              color: token.colorText,
            }}
            presets={[
              {
                label: intl.formatMessage({
                  id: 'master.logs.search.yesterday',
                  defaultMessage: 'Yesterday',
                }),
                value: [dayjs().add(-1, 'day'), dayjs()],
              },
              {
                label: intl.formatMessage({
                  id: 'master.logs.search.last_week',
                  defaultMessage: 'Last Week',
                }),
                value: [dayjs().add(-7, 'day'), dayjs()],
              },
              {
                label: intl.formatMessage({
                  id: 'master.logs.search.last_month',
                  defaultMessage: 'Last Month',
                }),
                value: [dayjs().add(-30, 'day'), dayjs()],
              },
            ]}
            onChange={(dates) => {
              form.setFieldsValue({ dateTimeRange: dates });
            }}
          />
        );
      },
    },
    {
      title: intl.formatMessage({
        id: 'master.logs.email.text',
        defaultMessage: 'Email',
      }),
      dataIndex: 'publisher',
      valueType: 'select',
      fieldProps: { mode: 'multiple' },
      width: '25%',
      request: async () => {
        const users = await queryUserSource();
        return users.map((u) => ({
          label: u.email,
          value: u.email,
        }));
      },
    },
    {
      title: intl.formatMessage({
        id: 'master.logs.action.text',
        defaultMessage: 'Action',
      }),
      dataIndex: 'subtopic',
      valueType: 'treeSelect',
      width: '25%',
      fieldProps: {
        treeCheckable: true,
        multiple: true,
      },
      request: async () => LogActions(intl),
      render: (_, item) => {
        const childs = LogActions(intl).flatMap((a) => a.children || []);
        const action = childs.find((a) => a?.value === item.subtopic);
        return action?.title ?? '...';
      },
    },
  ];
  return (
    <ProTable<MasterModel.Message>
      actionRef={tableRef}
      columns={columns}
      rowKey={(item) =>
        `${item.subtopic}:${item.time}:${item.publisher}:${item.name}`
      }
      size="large"
      options={{
        search: false,
        setting: false,
        density: false,
        reload: true,
      }}
      pagination={{
        defaultPageSize: DEFAULT_PAGE_SIZE * 2,
        showSizeChanger: true,
        pageSizeOptions: ['10', '15', '20'],
        showTotal: (total, range) =>
          `${range[0]}-${range[1]} 
                          ${intl.formatMessage({
                            id: 'common.paginations.of',
                            defaultMessage: 'of',
                          })}
                        ${total} ${intl.formatMessage({
            id: 'master.logs.table.pagination',
            defaultMessage: 'activities',
          })}`,
      }}
      request={async (params) => {
        try {
          const { current, pageSize, subtopic, publisher, startTime, endTime } =
            params;
          const offset = current === 1 ? 0 : (current! - 1) * pageSize!;
          const body: MasterModel.SearchLogPaginationBody = {
            limit: pageSize,
            offset: offset,
            from: startTime
              ? typeof startTime === 'string'
                ? dayjs(startTime).unix()
                : startTime.unix()
              : undefined,
            to: endTime
              ? typeof endTime === 'string'
                ? dayjs(endTime).unix()
                : endTime.unix()
              : undefined,
            publisher: publisher?.length ? publisher.join(',') : undefined,
            subtopic: subtopic?.length ? subtopic.join(',') : undefined,
          };
          const resp = await apiQueryLogs(body, 'user_logs');
          return {
            data: resp.messages || [],
            success: true,
            total: resp.total || 0,
          };
        } catch (error) {
          console.error('Error when get logs: ', error);
          return {
            data: [],
            success: false,
            total: 0,
          };
        }
      }}
    />
  );
};

export default SystemLogs;
