import { Alert, Box, Button, Card, Center, Group, Stack, Tooltip, Typography } from '@tidbcloud/uikit'
import { DotBadge, MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconAlertTriangle, IconInfoCircle } from '@tidbcloud/uikit/icons'
import { useMemo, useState } from 'react'

import TimeComponent from 'dbaas/components/TimeComponent'
import { PageAccessGuard } from 'dbaas/contexts/access-control'
import { PageShell } from 'dbaas/layouts/v5/page'
import { TypesExportEvent, useGetAuditLogs, useGetSettings } from 'dbaas/services'
import useStores from 'dbaas/stores/useStores'

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

const DEFAULT_PAGE_SIZE = 20

const AuditLogStatus = ({ result }: { result?: string }) => {
  const succeeded = result === 'Success'

  return (
    <Group gap={8}>
      <Box w={10} h={10} bg={succeeded ? 'green.6' : 'red.6'} sx={{ borderRadius: 999 }} />
      <Typography>{succeeded ? 'Succeeded' : 'Failed'}</Typography>
    </Group>
  )
}

const AuditLogEmpty = ({ enabled, settingIsLoading }: { enabled: boolean; settingIsLoading: boolean }) => {
  if (!enabled && !settingIsLoading) {
    return (
      <Center h={240}>
        <Stack align="center" gap={4}>
          <Typography variant="headline-sm">No logs</Typography>
          <Typography c="carbon.7">Console Audit Logging is disabled.</Typography>
        </Stack>
      </Center>
    )
  }

  return (
    <Center h={240}>
      <Typography c="carbon.7">No Audit Log</Typography>
    </Center>
  )
}

export const AuditLogWrapper = () => {
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: DEFAULT_PAGE_SIZE })
  const [selectIndex, setSelectIndex] = useState(-1)
  const [filter, setFilter] = useState<FilterValuesType>({
    type: [],
    result: 0,
    timeRange: {
      type: 'relative',
      value: 30 * 60
    },
    search: ''
  })

  const {
    store: {
      lastVisitLocation: { orgId }
    }
  } = useStores()

  const {
    data,
    isLoading: settingIsLoading,
    refetch: refetchSettings
  } = useGetSettings(orgId, {
    query: {
      enabled: !!orgId,
      refetchOnWindowFocus: false
    }
  })

  const enabled = !!data?.status

  const handleFilterChange = (values: FilterValuesType) => {
    setFilter(values)
    setPagination((prev) => ({ ...prev, pageIndex: 0 }))
  }

  const searchParams = useSearchParams(filter, pagination.pageIndex + 1, pagination.pageSize)

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

  const { download } = useExportData(searchParams)

  const events = enabled ? (listData?.events ?? []) : []
  const totalCount = listData?.total_count ?? 0
  const columns = useMemo<MRT_ColumnDef<TypesExportEvent>[]>(
    () => [
      {
        header: 'Type',
        accessorKey: 'type',
        Cell: ({ row }) => (
          <Typography
            c="peacock.7"
            sx={{ cursor: 'pointer' }}
            onClick={() => {
              setSelectIndex(row.index)
            }}
          >
            {row.original.type}
          </Typography>
        )
      },
      {
        header: 'Status',
        accessorKey: 'result',
        Cell: ({ row }) => <AuditLogStatus result={row.original.result} />
      },
      {
        header: 'Time',
        Header: () => (
          <Group gap={6}>
            Time
            <Tooltip label="The time when the audit log event ended." withArrow>
              <IconInfoCircle size={16} />
            </Tooltip>
          </Group>
        ),
        accessorKey: 'ends_at',
        Cell: ({ row }) => <TimeComponent time={row.original.ends_at ?? ''} format="YYYY-MM-DD HH:mm:ss" />
      },
      {
        header: 'Operator',
        accessorKey: 'operator_email'
      }
    ],
    []
  )

  const statusBadge = <DotBadge color={enabled ? 'green' : 'gray'}>{enabled ? 'Enabled' : 'Disabled'}</DotBadge>
  const settingsAction = (
    <SettingsButton
      enabled={enabled}
      handler={
        <Button
          size="sm"
          variant={enabled ? 'outline' : 'filled'}
          color={enabled ? 'red' : 'carbon'}
          data-testid="auditlog-setting"
          data-mp-event="Settings button clicked"
          data-mp-source="Audit Log"
        >
          {enabled ? 'Disable' : 'Enable'}
        </Button>
      }
      onConfirm={refetchSettings}
    />
  )

  const content = (
    <Stack gap={24} px={24} pb={24}>
      <Card withBorder p={24} radius="md">
        <Stack gap={24}>
          <Group justify="space-between" align="flex-start">
            <Stack gap={8}>
              <Group gap={12}>
                <Typography variant="headline-sm">Console Audit Logging</Typography>
                {statusBadge}
              </Group>
              <Typography c="carbon.7">
                Track various behaviors and operations of organization{enabled ? ' in the last 90 days' : ''}.{' '}
                <Box
                  component="a"
                  href="https://docs.pingcap.com/tidbcloud/tidb-cloud-console-auditing"
                  target="_blank"
                  rel="noreferrer"
                  c="peacock.7"
                >
                  Learn more
                </Box>
              </Typography>
            </Stack>
            {settingsAction}
          </Group>

          {!enabled && (
            <Alert color="yellow" icon={<IconAlertTriangle size={16} />}>
              Notice: No new logs have been recorded in disabled period, and also the previously collected logs are
              unaccessible. This may introduce potential audit gaps. To re-activate continuous monitoring, please enable
              it.
            </Alert>
          )}
        </Stack>
      </Card>

      {enabled ? (
        <>
          <Filter
            defaultValues={filter}
            onChange={handleFilterChange}
            onDownload={download}
            onRefresh={() => refetchAuditLogs()}
          />

          <ProTable<TypesExportEvent>
            columns={columns}
            data={events}
            loading={listIsLoading}
            manualPagination
            enablePagination
            rowCount={totalCount}
            state={{ pagination }}
            onPaginationChange={(updater) => {
              setPagination((prev) => {
                const next = typeof updater === 'function' ? updater(prev) : updater

                return {
                  ...next,
                  pageIndex: next.pageSize === prev.pageSize ? next.pageIndex : 0
                }
              })
            }}
            pagination={{
              rowsPerPageOptions: ['10', '20', '50'],
              showRowsPerPage: true,
              showTotal: true,
              localization: { total: 'Total: ' }
            }}
            renderEmptyRowsFallback={() => <AuditLogEmpty enabled={enabled} settingIsLoading={settingIsLoading} />}
            mantinePaperProps={{ withBorder: true, radius: 'md', sx: { overflow: 'hidden' } }}
            mantineTableProps={{ verticalSpacing: 8, horizontalSpacing: 22 }}
            mantineTableHeadRowProps={{ bg: 'carbon.1' }}
            mantineTableHeadCellProps={{ fw: 500, c: 'carbon.7', h: 40 }}
            mantineTableBodyCellProps={{ h: 48 }}
          />

          <DetailDrawer
            opened={selectIndex >= 0}
            onClose={() => setSelectIndex(-1)}
            index={selectIndex}
            list={listData?.events}
          />
        </>
      ) : (
        <Card withBorder p={0} radius="md">
          <Center h={480}>
            <Typography variant="headline-sm" c="carbon.7">
              No logs
            </Typography>
          </Center>
        </Card>
      )}
    </Stack>
  )

  return (
    <PageAccessGuard
      id="OrgAuditGate"
      fallback={(defaultFallback) => <PageShell title="Console Audit Logging">{defaultFallback}</PageShell>}
    >
      <PageShell
        title="Console Audit Logging"
        bodyProps={{
          px: 0,
          sx: {
            flexGrow: 1,
            display: 'flex',
            flexDirection: 'column'
          }
        }}
      >
        {content}
      </PageShell>
    </PageAccessGuard>
  )
}
