import {
  Badge,
  Box,
  Button,
  Center,
  Flex,
  Group,
  Menu,
  Stack,
  Typography
} from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconChevronDown } from '@tidbcloud/uikit/icons'
import { useState } from 'react'

import {
  useGetAuditLogs,
  useGetAuditLogSettings
} from 'apiClient/services/audit'
import { TypesExportEvent } from 'apiClient/services/audit/interface'
import { TenantGetTenantResp } from 'apiClient/services/devops/interface'
import { format } from 'utils/time'

import { DetailDrawer } from './DetailDrawer'
import { Filter, FilterValuesType } from './Filter'
import { useExportData, useSearchParams } from './helper'
import { SettingsButton } from './SettingsButton'

const pageSize = 10

export const AuditLog = ({ tenant }: { tenant: TenantGetTenantResp }) => {
  const [currentPage, setCurrentPage] = useState(1)

  const [selectIndex, setSelectIndex] = useState(-1)

  const [filter, setFilter] = useState<FilterValuesType>({
    type: [],
    result: 0,
    timeRange: {
      type: 'relative',
      value: 30 * 24 * 60 * 60
    },
    search: ''
  })

  const orgId = tenant.id || ''

  const handleFilterChange = (v: FilterValuesType) => {
    setFilter(v)
    setCurrentPage(1)
  }

  const searchParams = useSearchParams(filter, currentPage, pageSize)
  const { data, isLoading: settingIsLoading } = useGetAuditLogSettings(orgId, {
    query: {
      enabled: !!orgId,
      refetchOnWindowFocus: false
    }
  })

  const enabled = !!data?.data?.status

  const { data: listData, isLoading: listIsLoading } = useGetAuditLogs(
    orgId,
    searchParams,
    {
      query: {
        refetchOnWindowFocus: false,
        enabled: !!orgId && !!searchParams && !!currentPage
      }
    }
  )

  const { download } = useExportData(searchParams, tenant)

  const totalPage =
    Math.ceil((listData?.data?.total_count || 0) / pageSize) || 0

  const columns: MRT_ColumnDef<TypesExportEvent>[] = [
    {
      header: 'Type',
      accessorKey: 'type',
      Cell: (data) => (
        <Typography
          variant="body-lg"
          c="peacock.7"
          sx={{ cursor: 'pointer' }}
          onClick={() => {
            setSelectIndex(data.row.index)
          }}
        >
          {data.renderedCellValue}
        </Typography>
      )
    },
    {
      header: 'Status',
      maxSize: 80,
      accessorFn: (data: TypesExportEvent) => (
        <Badge
          color={data.result === 'Success' ? 'green' : 'red'}
          variant="dot"
          size="lg"
          sx={{ padding: 0 }}
        >
          {data.result}
        </Badge>
      )
    },
    {
      header: 'Time',
      maxSize: 100,
      accessorFn: (data: TypesExportEvent) =>
        format(data.ends_at ?? '', undefined, 'YYYY-MM-DD HH:mm:ss', 0)
    },
    {
      header: 'Operator',
      accessorKey: 'operator_email'
    }
  ]

  const Placeholder = () => (
    <Center h="calc(100vh - 354px)">
      <Stack align="center" gap={0}>
        <Typography variant="headline-md" mb={8}>
          No logs
        </Typography>
        <Group gap={0}>
          <Typography variant="body-lg" c="carbon.7">
            Console Audit Log settings is
          </Typography>
          <Typography variant="title-md" c="carbon.7" mx={4}>
            {enabled ? 'enabled' : 'disabled'}.
          </Typography>
        </Group>
      </Stack>
    </Center>
  )

  const table = (
    <ProTable
      loading={listIsLoading}
      mantinePaperProps={{ mx: 24 }}
      mantineTableHeadCellProps={{
        sx: {
          ':first-of-type': { paddingLeft: '24px !important' }
        }
      }}
      mantineTableBodyCellProps={{
        sx: {
          padding: '12px 8px !important',
          ':first-of-type': { paddingLeft: '24px !important' }
        }
      }}
      emptyMessage="No Audit Log"
      columns={columns}
      data={!listData?.data?.events ? [] : listData?.data?.events}
      manualPagination={true}
      renderEmptyRowsFallback={() => {
        return <Placeholder />
      }}
      pagination={
        listData?.data?.total_count
          ? {
              total: totalPage,
              value: currentPage || 1,
              defaultValue: pageSize,
              onChange: (page) => setCurrentPage(page)
            }
          : undefined
      }
    />
  )

  const rightSection = (
    <Group gap={8}>
      <SettingsButton
        enabled={enabled}
        orgId={orgId}
        handler={
          <Button
            size="sm"
            data-testid="auditlog-setting"
            variant="default"
            data-mp-event="Settings button clicked"
            data-mp-source="Audit Log"
          >
            Settings
          </Button>
        }
      />
      <Menu position="bottom-end">
        <Menu.Target>
          <Button
            size="sm"
            variant="default"
            rightSection={<IconChevronDown size={16} />}
          >
            Download logs
          </Button>
        </Menu.Target>
        <Menu.Dropdown>
          <Menu.Item onClick={() => download('csv')}>
            <Typography variant="label-sm">CSV</Typography>
          </Menu.Item>
          <Menu.Item onClick={() => download('json')}>
            <Typography variant="label-sm">JSON</Typography>
          </Menu.Item>
        </Menu.Dropdown>
      </Menu>
    </Group>
  )

  const auditlog = (
    <Flex direction="column">
      <Group justify="space-between" mx="xl" mb="lg">
        <Typography variant="headline-md">Audit Log</Typography>
        {rightSection}
      </Group>
      <Box mx="xl" mb="xs">
        <Filter
          orgId={orgId}
          defaultValues={filter}
          onChange={handleFilterChange}
        />
      </Box>
      {table}
      <DetailDrawer
        opened={selectIndex >= 0}
        onClose={() => setSelectIndex(-1)}
        index={selectIndex}
        list={listData?.data?.events}
      />
    </Flex>
  )

  return auditlog
}
