import { Button, notifier } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { IconFileSearch02 } from '@tidbcloud/uikit/icons'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'

import { cloudConfigControllerListDefaultConfigurationChanges } from 'apiClient/services/devops'
import {
  CloudConfigControllerListDefaultConfigurationChangesContainItemType,
  CloudconfigDefaultConfigurationChange
} from 'apiClient/services/devops/interface'
import { toLocal } from 'pages/Devops/Maintenance/Detail'

type TablePaginationState = {
  pageIndex: number
  pageSize: number
}

type TablePaginationUpdater =
  | TablePaginationState
  | ((prev: TablePaginationState) => TablePaginationState)

const CHANGE_PAGE_SIZE = 10

const getErrorContent = (error: any) =>
  error?.response?.data?.errmsg ||
  error?.response?.data?.message ||
  error?.message ||
  String(error)

const getFixedPagination = (
  updaterOrValue: TablePaginationUpdater,
  currentPagination: TablePaginationState
) => {
  const nextPagination =
    typeof updaterOrValue === 'function'
      ? updaterOrValue(currentPagination)
      : updaterOrValue

  return {
    pageIndex: nextPagination.pageIndex,
    pageSize: CHANGE_PAGE_SIZE
  }
}

function ChangesTable({
  type
}: {
  type: CloudConfigControllerListDefaultConfigurationChangesContainItemType
}) {
  const [rows, setRows] = useState<CloudconfigDefaultConfigurationChange[]>([])
  const [total, setTotal] = useState(0)
  const [loading, setLoading] = useState(false)
  const [pagination, setPagination] = useState<TablePaginationState>({
    pageIndex: 0,
    pageSize: CHANGE_PAGE_SIZE
  })

  const loadChanges = useCallback(async () => {
    setLoading(true)
    try {
      const response =
        await cloudConfigControllerListDefaultConfigurationChanges({
          contain_item_type: type,
          page: pagination.pageIndex + 1,
          per_page: pagination.pageSize
        })
      setRows(response.data.items || [])
      setTotal(response.data.total || 0)
    } catch (error) {
      notifier.error(getErrorContent(error), {
        title: 'Failed to load changes'
      })
    } finally {
      setLoading(false)
    }
  }, [pagination.pageIndex, pagination.pageSize, type])

  useEffect(() => {
    void loadChanges()
  }, [loadChanges])

  const columns = useMemo<
    MRT_ColumnDef<CloudconfigDefaultConfigurationChange>[]
  >(
    () => [
      {
        accessorFn: (record) => record.id || '-',
        header: 'ID',
        id: 'id',
        size: 100
      },
      {
        accessorFn: (record) => toLocal(record.created_at),
        header: 'Created At',
        id: 'created_at',
        size: 180
      },
      {
        accessorFn: (record) => toLocal(record.closed_at),
        header: 'Closed At',
        id: 'closed_at',
        size: 180
      },
      {
        accessorFn: (record) => record.phase || '-',
        header: 'Phase',
        id: 'phase',
        size: 140
      },
      {
        accessorFn: (record) => record.reason || '-',
        header: 'Reason',
        id: 'reason',
        size: 320
      },
      {
        Cell: ({ row }) => (
          <Button
            component={Link}
            leftSection={<IconFileSearch02 size={16} />}
            size="sm"
            target="_blank"
            to={`/defaultconfig/change/${row.original.id}`}
            rel="noreferrer"
            variant="subtle"
          >
            Detail
          </Button>
        ),
        header: 'Action',
        id: 'action',
        size: 120
      }
    ],
    []
  )

  return (
    <ProTable<CloudconfigDefaultConfigurationChange>
      columns={columns}
      data={rows}
      enableColumnActions={false}
      enableColumnFilters={false}
      enableDensityToggle={false}
      enableFullScreenToggle={false}
      enableHiding={false}
      enablePagination={total > CHANGE_PAGE_SIZE}
      enableSorting={false}
      enableTopToolbar={false}
      getRowId={(row, rowIndex) => String(row.id || rowIndex)}
      loading={loading}
      manualPagination
      onPaginationChange={(updaterOrValue) => {
        setPagination((currentPagination) =>
          getFixedPagination(
            updaterOrValue as TablePaginationUpdater,
            currentPagination
          )
        )
      }}
      pagination={{ showRowsPerPage: false }}
      rowCount={total}
      state={{ pagination }}
    />
  )
}

export default ChangesTable
