import React, { useMemo, useState } from 'react'

import {
  FilterOutlined,
  ReloadOutlined,
  SortAscendingOutlined
} from '@ant-design/icons'
import { Checkbox, Group, Paper } from '@mantine/core'
import { Button, Input, Modal, Space, Table, Typography, Alert } from 'antd'
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'
import type { TableCurrentDataSource } from 'antd/es/table/interface'
import { Link } from 'react-router-dom'

import { ViewDashboardItemExternal } from '@clinic/client'
import { GitOPSModalBody } from '~/components/GitOPSModalBody'
import { AppLayout } from '~/components/Layout'
import { clustersTelemetry } from '~/telemetry'
import {
  ClusterStatus,
  ClusterDeployType,
  actionPreflightMap
} from '~/utils/cluster-status'
import envConfig, { setLocalStorageItem } from '~/utils/env-config'

import { ColumnFilter, IColumn } from './components/ColumnFilter'
import { OverviewSortSelect } from './components/SortSelect'
import { useOverviewTableQuery } from './hooks/use-overview-table-query'
import { useColumns } from './hooks/use-table-columns'

const Page: React.FC = () => {
  const {
    data,
    regionFilters,
    total,
    hasMore,
    page,
    pageSize,
    queryParams,
    setQueryParams,
    loading,
    isValidating,
    calculatingTotal,
    calculateTotal,
    search,
    query,
    refresh
  } = useOverviewTableQuery()
  const [searchInputStr, setSearchInputStr] = useState(query)
  const [curDashboardItem, setCurDashboardItem] =
    useState<ViewDashboardItemExternal | null>(null)
  const { columns, visibleColumns, visibleColumnKeys, setVisibleColumnKeys } =
    useColumns(
      {
        clusterStatus: queryParams.clusterStatus,
        provider: queryParams.provider,
        tenantPlan: queryParams.tenantPlan,
        controlPlaneArch: queryParams.controlPlaneArch,
        deployType: queryParams.deployType,
        region: queryParams.region
      },
      {
        sort: queryParams.sort,
        order: queryParams.order
      },
      regionFilters
    )
  const columnsKV = useMemo<IColumn[]>(
    () =>
      columns.map((c) => ({
        key: (c as any).dataIndex,
        name: c.title! as string
      })),
    [columns]
  )
  const columnsWithActions = useMemo<ColumnsType<ViewDashboardItemExternal>>(
    () => [
      ...visibleColumns,
      {
        title: 'Details',
        key: 'operation',
        fixed: 'right',
        width: 150,
        render: (val: null, record) => {
          if (record.controlPlaneArch === '3layer') {
            return (
              <Space>
                <Link
                  to={`/orgs/${record.orgID!}/clusters/${record.clusterID!}`}
                  target='_blank'
                >
                  Clinic
                </Link>
                <Typography.Link
                  onClick={() => {
                    var url =
                      envConfig.quickLinks.opsPortal +
                      `/orgs/${record.tenantID}/clusters/${record.clusterID!}`
                    if (record.clusterDeployType === ClusterDeployType.ByocM1) {
                      url =
                        envConfig.quickLinks.opsPortal +
                        `/orgs/${
                          record.tenantID
                        }/byoc-clusters/${record.clusterID!}?vendor=${
                          record.clusterProviderName
                        }&region=${record.clusterRegionName}`
                    }
                    window.open(url)
                  }}
                >
                  Ops
                </Typography.Link>
                <Typography.Link
                  disabled={
                    record.clusterDeployType !== ClusterDeployType.Dedicated ||
                    !actionPreflightMap.gitops(
                      record.clusterStatus! as ClusterStatus
                    )
                  }
                  onClick={() =>
                    window.open(
                      envConfig.quickLinks.opsPortal +
                        `/orgs/${
                          record.tenantID
                        }/clusters/${record.clusterID!}?activeKey=configs`
                    )
                  }
                >
                  Config
                </Typography.Link>
              </Space>
            )
          }
          return (
            <Space>
              <Link
                to={`/orgs/${record.orgID!}/clusters/${record.clusterID!}`}
                target='_blank'
              >
                Clinic
              </Link>
              <Typography.Link
                onClick={() => {
                  var url =
                    envConfig.quickLinks.opsPortal +
                    `/orgs/${record.tenantID}/clusters/${record.clusterID!}`
                  if (record.clusterDeployType === ClusterDeployType.ByocM1) {
                    url =
                      envConfig.quickLinks.opsPortal +
                      `/orgs/${
                        record.tenantID
                      }/byoc-clusters/${record.clusterName!}?vendor=${
                        record.clusterProviderName
                      }&region=${record.clusterRegionName}`
                  }
                  window.open(url)
                }}
              >
                Ops
              </Typography.Link>
              <Typography.Link
                disabled={
                  record.clusterDeployType !== ClusterDeployType.Dedicated ||
                  !actionPreflightMap.gitops(
                    record.clusterStatus! as ClusterStatus
                  )
                }
                onClick={() => setCurDashboardItem(record)}
              >
                GitOPS
              </Typography.Link>
            </Space>
          )
        }
      }
    ],
    [visibleColumns]
  )

  function handleTableChange(
    newPagination: TablePaginationConfig,
    filters: any,
    sorter: any,
    extra: TableCurrentDataSource<ViewDashboardItemExternal>
  ) {
    // filters: {clusterDeployType: null, clusterStatus:['normal', 'upgrading'], tenantPlan: null}
    // sorter: {}, or {order:'ascend'|'descend', field:'clusterDeletedAt'}
    setQueryParams({
      clusterStatus: filters.clusterStatus || [],
      tenantPlan: filters.tenantPlan || [],
      controlPlaneArch: filters.controlPlaneArch || [],
      deployType: filters.clusterDeployTypeV2 || [],
      provider: filters.clusterProviderName || [],
      region: filters.clusterRegionName || [],
      clusterVersion: filters.clusterVersion || [],
      sort: sorter.field ?? '',
      order: sorter.order ?? '',
      page: extra.action === 'paginate' ? newPagination.current ?? page : 1,
      pageSize: newPagination.pageSize ?? pageSize
    })
  }

  function onSearch(str: string) {
    clustersTelemetry.search()
    search(str.trim())
  }

  function handleShowDeletedClustersCheck(checked: boolean) {
    setQueryParams({
      page: 1,
      showDeleted: checked
    })

    setLocalStorageItem('search.show_deleted_clusters', checked + '')
  }

  return (
    <AppLayout>
      <Paper shadow='md' radius='sm'>
        <Group
          position='apart'
          mx='md'
          py='md'
          className='border-0 border-b border-solid border-gray-200'
        >
          <Group spacing='xs'>
            <Input.Search
              placeholder='Search by tenant/cluster name or id'
              onSearch={onSearch}
              onChange={(e) => setSearchInputStr(e.target.value.trim())}
              loading={loading || isValidating}
              style={{ width: 320 }}
              value={searchInputStr}
              size='large'
            />

            <Checkbox
              label='Show deleted clusters'
              className='flex'
              defaultChecked={queryParams.showDeleted}
              onChange={(e) => handleShowDeletedClustersCheck(e.target.checked)}
            />
          </Group>

          <Group spacing='xs'>
            <Button size='large' onClick={() => refresh()}>
              <ReloadOutlined />
            </Button>
            <OverviewSortSelect
              defSortOption={{
                field: queryParams.sort,
                order: queryParams.order
              }}
              onChange={(o) =>
                setQueryParams({
                  sort: o?.field ?? '',
                  order: o?.order ?? '',
                  page: 1
                })
              }
            >
              <Button size='large'>
                <SortAscendingOutlined />
              </Button>
            </OverviewSortSelect>
            <ColumnFilter
              columns={columnsKV}
              visibleColumnKeys={visibleColumnKeys}
              onChange={(v) => setVisibleColumnKeys(v)}
            >
              <Button size='large'>
                <FilterOutlined />
              </Button>
            </ColumnFilter>
          </Group>
        </Group>

        <Group px='md'>
          <Alert
            description='Cluster status and version displayed here may not be accurate. Please refer to the cluster detail page for the most up-to-date information.'
            type='warning'
            showIcon
            style={{ width: '100%', marginTop: '10px', marginBottom: '10px' }}
          />
          <Table
            size='small'
            loading={loading}
            columns={columnsWithActions}
            dataSource={data}
            scroll={{ x: 1400 }}
            pagination={
              total === undefined
                ? false
                : {
                    position: ['bottomRight'],
                    current: page,
                    pageSize,
                    total,
                    showTotal: (total) => `Total ${total} items`
                  }
            }
            onChange={handleTableChange}
          />
          {total === undefined && !loading && (
            <div className='flex w-full items-center justify-end gap-2 py-4'>
              <Button
                size='small'
                disabled={page <= 1}
                onClick={() => setQueryParams({ page: page - 1 })}
              >
                Previous
              </Button>
              <Typography.Text>Page {page}</Typography.Text>
              <Button
                size='small'
                disabled={hasMore !== true}
                onClick={() => setQueryParams({ page: page + 1 })}
              >
                Next
              </Button>
              {hasMore === true && (
                <Button
                  size='small'
                  loading={calculatingTotal}
                  onClick={() => calculateTotal()}
                >
                  Calculate total
                </Button>
              )}
            </div>
          )}
        </Group>
      </Paper>

      <Modal
        width={400}
        visible={curDashboardItem !== null}
        title={`GitOPS for ${curDashboardItem?.clusterID ?? ''}`}
        footer={null}
        onCancel={() => setCurDashboardItem(null)}
        destroyOnClose={true}
      >
        <Alert
          message='Change Notification!!'
          description={
            <span>
              Config change and upgrade process has been updated on 2023/07/11,
              secondary confirmation action is needed for each change. Please
              see details{' '}
              <a href='https://pingcap.feishu.cn/wiki/wikcn5YfxEQ5z9Fa8FUPARU9DOh?source_type=message&from=message#doxcnjMxuMUYOljJPP2vE66rwHe'>
                {' '}
                here{' '}
              </a>
            </span>
          }
          type='warning'
        />
        <br />
        {curDashboardItem && (
          <GitOPSModalBody
            clusterId={curDashboardItem.clusterID!}
            orgId={curDashboardItem.tenantID!}
            orgName={curDashboardItem.tenantName!}
          />
        )}
      </Modal>
    </AppLayout>
  )
}

export default Page
