import { Table, Typography, Select, Modal, Button, Descriptions } from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { Base64 } from 'js-base64'
import { useMemo, useState } from 'react'

import { auditControllerListAuditLog } from 'apiClient/services/devops'
import {
  AuditAuditLog,
  AuditAuditLogType,
  AuditControllerListAuditLogParams
} from 'apiClient/services/devops/interface'
import SearchBar from 'components/SearchBar'
import { useTable, ListToolBar } from 'components/Table'

export default function Audits() {
  const [currentType, setCurrentType] = useState<AuditAuditLogType>(
    AuditAuditLogType.operation
  )
  const [searchParams, setSearchParams] =
    useState<AuditControllerListAuditLogParams>({})
  const [viewAuditLog, setViewAuditLog] = useState<AuditAuditLog>()

  const getData = (params?: Partial<PageInfo>) =>
    auditControllerListAuditLog({
      type: currentType,
      instance_id: searchParams.instance_id,
      page: params?.page,
      per_page: params?.pageSize
    }).then((res) => {
      return {
        ...res,
        data: {
          ...res.data,
          items: res.data.audit_logs
        }
      }
    })

  const { dataSource, loading, reload, paginationProps, onTableChange } =
    useTable<ListData<AuditAuditLog>>(getData, [], {
      pagination: true
    })

  const onSearch = (query: { object_is: string }) => {
    if (query) {
      if (query.object_is) {
        setSearchParams({ instance_id: query.object_is })
      }
      return reload()
    }
    setSearchParams({})
    return reload()
  }

  const actions = useMemo(
    () => [
      <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
        <Typography.Text>Type:</Typography.Text>
        <Select
          defaultValue={currentType}
          options={Object.values(AuditAuditLogType).map((i) => ({
            value: i,
            label: i
          }))}
          onChange={(value) => {
            setCurrentType(value as AuditAuditLogType)
          }}
          style={{ width: 200 }}
        />
      </div>,
      <SearchBar
        defaultValue={{
          object_is: ''
        }}
        options={['object_is']}
        labels={['Object Is']}
        fetcher={onSearch}
      />
    ],
    []
  )

  const columns: ColumnsType<AuditAuditLog> = [
    {
      title: 'ID',
      render: (_: any, record) => {
        return record.id
      }
    },
    {
      title: 'Operate At',
      render: (_: any, record) => {
        return record.operate_at
      }
    },
    {
      title: 'Type',
      render: (_: any, record) => {
        return record.type
      }
    },
    {
      title: 'Object',
      render: (_: any, record) => {
        return record.object_id
      }
    },
    {
      title: 'Operation',
      render: (_: any, record) => {
        return record.operation
      }
    },
    {
      title: 'Operator',
      render: (_: any, record) => {
        return record.operator
      }
    },
    {
      title: 'Content',
      render: (_: any, record) => (
        <Button type="link" onClick={() => setViewAuditLog(record)}>
          View
        </Button>
      )
    }
  ]

  return (
    <div>
      <ListToolBar actions={actions} reload={reload} />
      <Table<AuditAuditLog>
        columns={columns}
        rowKey="id"
        dataSource={dataSource}
        loading={loading}
        pagination={paginationProps}
        onChange={onTableChange}
        size="small"
      />

      <Modal
        title="Audit Log Detail"
        open={viewAuditLog !== undefined}
        onOk={() => setViewAuditLog(undefined)}
        onCancel={() => setViewAuditLog(undefined)}
        width={800}
        footer={[
          <Button key="close" onClick={() => setViewAuditLog(undefined)}>
            Close
          </Button>
        ]}
      >
        <Descriptions column={2}>
          <Descriptions.Item label="ID">{viewAuditLog?.id}</Descriptions.Item>
          <Descriptions.Item label="Type">
            {viewAuditLog?.type}
          </Descriptions.Item>
          <Descriptions.Item label="Object ID">
            {viewAuditLog?.object_id}
          </Descriptions.Item>
          <Descriptions.Item label="Operation">
            {viewAuditLog?.operation}
          </Descriptions.Item>
          <Descriptions.Item label="Operator">
            {viewAuditLog?.operator}
          </Descriptions.Item>
          <Descriptions.Item label="Operate At">
            {viewAuditLog?.operate_at}
          </Descriptions.Item>
        </Descriptions>

        <pre
          style={{
            background: '#f6f6f6',
            border: '1px solid #ccc',
            padding: '10px',
            borderRadius: '4px',
            whiteSpace: 'pre-wrap',
            wordBreak: 'break-all'
          }}
        >
          <code>
            {viewAuditLog?.details &&
              JSON.stringify(
                JSON.parse(Base64.decode(String(viewAuditLog?.details))),
                null,
                2
              )}
          </code>
        </pre>
      </Modal>
    </div>
  )
}
