import {
  DateField,
  FilterDropdown,
  getDefaultSortOrder,
  List,
  rangePickerFilterMapper,
  useTable,
} from '@refinedev/antd';
import { getDefaultFilter, HttpError } from '@refinedev/core';

import { SearchOutlined } from '@ant-design/icons';
import {
  DatePicker,
  Input,
  Radio,
  Space,
  Table,
  Tag,
  type TagProps,
} from 'antd';

import { CustomAvatar, PaginationTotal } from 'components';
import { AuditLogActionEnum, auditLogActionOptions } from 'enums';
import { AuditLog } from 'types';

import { ActionCell } from './components/action-cell';
import { LIST_CONTENT_PROPS } from 'constants/layout';

const getActionColor = (action: string): TagProps['color'] => {
  switch (action) {
    case AuditLogActionEnum.create:
      return 'green';
    case AuditLogActionEnum.update:
      return 'cyan';
    case AuditLogActionEnum.delete:
      return 'red';
    default:
      return 'default';
  }
};

export const AuditLogPage = () => {
  const { tableProps, filters, sorters } = useTable<
    AuditLog,
    HttpError,
    Partial<AuditLog>
  >({
    resource: 'audit',
    pagination: {
      pageSize: 20,
    },
    filters: {
      initial: [
        { field: 'authorName', operator: 'contains', value: '' },
        { field: 'resource', operator: 'contains', value: '' },
        { field: 'timestamp', value: undefined as any, operator: 'between' },
      ],
    },
    sorters: {
      initial: [{ field: 'id', order: 'desc' }],
    },
  });

  // fix for ant design filter dropdown contains operator
  filters.map((filter) => {
    if (filter.operator === 'contains' && Array.isArray(filter.value)) {
      filter.value = filter.value.join(',');
    }
  });

  return (
    <div className="page-container">
      <List
        breadcrumb={false}
        canCreate={false}
        contentProps={LIST_CONTENT_PROPS}
      >
        <Table
          className="audit-log-table"
          {...tableProps}
          rowKey="id"
          scroll={{ x: true }}
          pagination={{
            ...tableProps.pagination,
            showTotal: (total) => (
              <PaginationTotal total={total} entityName="audit logs" />
            ),
          }}
        >
          <Table.Column
            dataIndex="authorName"
            title="User"
            width="15%"
            filterIcon={<SearchOutlined />}
            render={(_, record: AuditLog) => {
              return (
                <Space>
                  <CustomAvatar
                    src={`https://rhrc.woa.com/photo/150/${record.authorName}.png`}
                    name={record.authorName}
                  />
                  {record.authorName || 'N/A'}
                </Space>
              );
            }}
            filterDropdown={(props) => (
              <FilterDropdown
                {...(props as any)}
                clearFilters={() => {
                  props.setSelectedKeys([]);
                  props.confirm?.();
                }}
              >
                <Input />
              </FilterDropdown>
            )}
            defaultFilteredValue={getDefaultFilter(
              'authorName',
              filters,
              'contains',
            )}
          />
          <Table.Column
            dataIndex="action"
            title="Action"
            render={(_, record: AuditLog) => {
              return (
                <Space>
                  <Tag color={getActionColor(record.action)}>
                    {
                      auditLogActionOptions.find(
                        (option) => option.value === record.action,
                      )?.label
                    }
                  </Tag>
                </Space>
              );
            }}
            filterDropdown={(props) => (
              <FilterDropdown
                {...(props as any)}
                clearFilters={() => {
                  props.setSelectedKeys([]);
                  props.confirm?.();
                }}
              >
                <Radio.Group>
                  {auditLogActionOptions.map((option) => (
                    <Radio key={option.value} value={option.value}>
                      {option.label}
                    </Radio>
                  ))}
                </Radio.Group>
              </FilterDropdown>
            )}
            defaultFilteredValue={getDefaultFilter('action', filters, 'eq')}
          />
          <Table.Column
            dataIndex="resource"
            title="Entity"
            filterIcon={<SearchOutlined />}
            filterDropdown={(props) => (
              <FilterDropdown
                {...(props as any)}
                clearFilters={() => {
                  props.setSelectedKeys([]);
                  props.confirm?.();
                }}
              >
                <Input />
              </FilterDropdown>
            )}
            defaultFilteredValue={getDefaultFilter(
              'resource',
              filters,
              'contains',
            )}
          />
          <Table.Column dataIndex="resourceId" title="Entity ID" />
          <Table.Column
            dataIndex="data"
            title="Changes"
            render={(_, record: AuditLog) => <ActionCell record={record} />}
          />
          <Table.Column
            dataIndex="timestamp"
            title="Date & Time"
            width="15%"
            render={(value) => (
              <DateField
                style={{ verticalAlign: 'middle' }}
                value={value}
                format="YYYY-MM-DD hh:mm:ss"
              />
            )}
            filterDropdown={(props) => (
              <FilterDropdown
                {...(props as any)}
                mapValue={rangePickerFilterMapper}
                clearFilters={() => {
                  props.setSelectedKeys([]);
                  props.confirm?.();
                }}
              >
                <DatePicker.RangePicker />
              </FilterDropdown>
            )}
            sorter
            defaultFilteredValue={getDefaultFilter(
              'timestamp',
              filters,
              'between',
            )}
            defaultSortOrder={getDefaultSortOrder('timestamp', sorters)}
          />
        </Table>
      </List>
    </div>
  );
};
