import {
  ActionIcon,
  Button,
  Card,
  Group,
  Modal,
  notifier,
  Select,
  SimpleGrid,
  Stack,
  TextInput,
  Tooltip,
  Typography
} from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import {
  IconPlus,
  IconRefreshCcw01,
  IconSearchLg
} from '@tidbcloud/uikit/icons'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'

import { cloudConfigControllerListTemplates } from 'apiClient/services/devops'
import {
  CloudConfigControllerListTemplatesClusterType,
  CloudConfigControllerListTemplatesParams,
  CloudconfigTemplate
} from 'apiClient/services/devops/interface'

import CreateCustomTemplateForm from '../components/CreateCustomTemplateForm'
import TemplateView from '../components/TemplateView'

type FilterKey = 'id' | 'name' | 'version'

type CustomTemplateFilters = {
  keyword: string
  type: FilterKey
}

type TablePaginationState = {
  pageIndex: number
  pageSize: number
}

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

const CUSTOM_TEMPLATE_PAGE_SIZE = 10

const FILTER_OPTIONS: Array<{ label: string; value: FilterKey }> = [
  { label: 'Version', value: 'version' },
  { label: 'Template ID', value: 'id' },
  { label: 'Template Name', value: 'name' }
]

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: CUSTOM_TEMPLATE_PAGE_SIZE
  }
}

const buildListTemplatesParams = (
  filters: CustomTemplateFilters
): CloudConfigControllerListTemplatesParams => {
  const keyword = filters.keyword.trim()

  return {
    cluster_type: CloudConfigControllerListTemplatesClusterType.DEDICATED_TIDB,
    id_in: filters.type === 'id' && keyword ? [keyword] : undefined,
    name_in: filters.type === 'name' && keyword ? [keyword] : undefined,
    template_type: 'custom',
    version: filters.type === 'version' && keyword ? keyword : undefined
  }
}

function CustomTemplateList() {
  const [filters, setFilters] = useState<CustomTemplateFilters>({
    keyword: '',
    type: 'version'
  })
  const [appliedFilters, setAppliedFilters] =
    useState<CustomTemplateFilters>(filters)
  const [templates, setTemplates] = useState<CloudconfigTemplate[]>([])
  const [loading, setLoading] = useState(false)
  const [pagination, setPagination] = useState<TablePaginationState>({
    pageIndex: 0,
    pageSize: CUSTOM_TEMPLATE_PAGE_SIZE
  })
  const [reloadKey, setReloadKey] = useState(0)
  const [createTemplate, setCreateTemplate] = useState<boolean>(false)
  const [viewTemplate, setViewTemplate] = useState<CloudconfigTemplate>()

  const loadTemplates = useCallback(async () => {
    setLoading(true)
    try {
      const response = await cloudConfigControllerListTemplates(
        buildListTemplatesParams(appliedFilters)
      )
      setTemplates(response.data.items || [])
    } catch (error) {
      notifier.error(getErrorContent(error), {
        title: 'Failed to load custom templates'
      })
    } finally {
      setLoading(false)
    }
  }, [appliedFilters])

  useEffect(() => {
    void loadTemplates()
  }, [loadTemplates, reloadKey])

  useEffect(() => {
    setPagination((current) => ({ ...current, pageIndex: 0 }))
  }, [appliedFilters])

  const handleSearch = useCallback(() => {
    setAppliedFilters(filters)
    setReloadKey((current) => current + 1)
  }, [filters])

  const columns = useMemo<MRT_ColumnDef<CloudconfigTemplate>[]>(
    () => [
      {
        accessorKey: 'id',
        header: 'ID',
        size: 90
      },
      {
        accessorKey: 'name',
        header: 'Name',
        size: 220
      },
      {
        accessorFn: (record) => record.tags?.effective_minor_version || '-',
        header: 'Effective Version',
        id: 'effective_version',
        size: 160
      },
      {
        accessorFn: (record) => record.config_type || '-',
        header: 'Config Type',
        id: 'config_type',
        size: 140
      },
      {
        accessorFn: (record) => record.tags?.creator_email || '-',
        header: 'Creator',
        id: 'creator',
        size: 240
      },
      {
        Cell: ({ row }) => {
          const record = row.original

          return (
            <Group gap={8} wrap="nowrap">
              <Button
                size="sm"
                variant="subtle"
                onClick={() => {
                  setViewTemplate(record)
                }}
              >
                View
              </Button>
              <Button
                component={Link}
                size="sm"
                target="_blank"
                to={`/template/${record.id}?cluster_type=${record.cluster_type}`}
                rel="noreferrer"
                variant="subtle"
              >
                Detail
              </Button>
            </Group>
          )
        },
        header: 'Action',
        id: 'action',
        size: 150
      }
    ],
    []
  )

  const shouldPaginate = templates.length > CUSTOM_TEMPLATE_PAGE_SIZE

  return (
    <Stack gap="md">
      <Card withBorder shadow="xs" padding="md" radius="sm">
        <Stack gap="md">
          <Group justify="space-between" align="flex-end" wrap="wrap">
            <SimpleGrid
              cols={{ base: 1, sm: 2, lg: 4 }}
              spacing="sm"
              style={{ flex: 1, minWidth: 280 }}
            >
              <Select
                data={FILTER_OPTIONS}
                label="Search By"
                value={filters.type}
                onChange={(value) => {
                  if (!value) {
                    return
                  }
                  setFilters((current) => ({
                    ...current,
                    type: value as FilterKey
                  }))
                }}
              />
              <TextInput
                label="Keyword"
                placeholder="Enter search keyword"
                value={filters.keyword}
                onChange={(event) => {
                  setFilters((current) => ({
                    ...current,
                    keyword: event.target.value
                  }))
                }}
                onKeyDown={(event) => {
                  if (event.key === 'Enter') {
                    handleSearch()
                  }
                }}
              />
              <Group align="flex-end" gap="sm">
                <Button
                  leftSection={<IconSearchLg size={16} />}
                  onClick={handleSearch}
                >
                  Search
                </Button>
                <Button
                  variant="default"
                  onClick={() => {
                    const nextFilters: CustomTemplateFilters = {
                      keyword: '',
                      type: 'version'
                    }
                    setFilters(nextFilters)
                    setAppliedFilters(nextFilters)
                    setReloadKey((current) => current + 1)
                  }}
                >
                  Reset
                </Button>
                <Tooltip label="Reload">
                  <ActionIcon
                    aria-label="Reload custom templates"
                    loading={loading}
                    variant="default"
                    onClick={() => setReloadKey((current) => current + 1)}
                  >
                    <IconRefreshCcw01 size={16} />
                  </ActionIcon>
                </Tooltip>
              </Group>
            </SimpleGrid>
            <Button
              leftSection={<IconPlus size={16} />}
              onClick={() => {
                setCreateTemplate(true)
              }}
            >
              Add Template
            </Button>
          </Group>

          <ProTable<CloudconfigTemplate>
            columns={columns}
            data={templates}
            enableColumnActions={false}
            enableColumnFilters={false}
            enableDensityToggle={false}
            enableFullScreenToggle={false}
            enableHiding={false}
            enablePagination={shouldPaginate}
            enableSorting={false}
            enableTopToolbar={false}
            getRowId={(row, rowIndex) => String(row.id || rowIndex)}
            loading={loading}
            onPaginationChange={(updaterOrValue) => {
              setPagination((currentPagination) =>
                getFixedPagination(
                  updaterOrValue as TablePaginationUpdater,
                  currentPagination
                )
              )
            }}
            pagination={{ showRowsPerPage: false }}
            rowCount={shouldPaginate ? templates.length : undefined}
            state={{ pagination }}
          />
        </Stack>
      </Card>

      <Modal
        opened={createTemplate}
        title="Create Template"
        onClose={() => setCreateTemplate(false)}
        size="80vw"
      >
        <CreateCustomTemplateForm
          onSuccess={() => {
            setCreateTemplate(false)
            void loadTemplates()
          }}
          onCancel={() => setCreateTemplate(false)}
        />
      </Modal>

      <Modal
        title={
          <Typography
            variant="title-lg"
            style={{ fontSize: 16, lineHeight: '24px' }}
          >
            View Template
          </Typography>
        }
        opened={viewTemplate !== undefined}
        onClose={() => {
          setViewTemplate(undefined)
        }}
        size="80vw"
      >
        {viewTemplate ? (
          <TemplateView
            template_id={viewTemplate.id?.toString()!}
            cluster_type={viewTemplate.cluster_type!}
            with_default_cases={false}
          />
        ) : (
          <Typography variant="body-lg" c="carbon.6">
            No template selected.
          </Typography>
        )}
      </Modal>
    </Stack>
  )
}

export default CustomTemplateList
