import { Column } from '@ant-design/plots'
import {
  Radio,
  DatePicker,
  Input,
  Table,
  TableProps,
  Typography,
  Space,
  message,
  Col,
  Card,
  Spin,
  Row
} from 'antd'
import type { RangePickerProps } from 'antd/es/date-picker'
import { ColumnsType, TablePaginationConfig } from 'antd/lib/table'
import dayjs from 'dayjs'
import moment from 'moment'
import React, { useEffect, useMemo, useState } from 'react'

import { getAlertSummary, listAlerts } from 'apiClient/services/devops'

import {
  ClusterGetAlertSummaryResp,
  JiraAlert,
  ListAlertsPriorityItem,
  ListAlertsType
} from '../../../apiClient/services/devops/interface'
import { ListToolBar, useTable } from '../../../components/Table'
import CursorTable from '../../../components/Table/CursorTable'
import { TimeRange } from '../../Overview/TimeRange'

const { RangePicker } = DatePicker

interface AlertFilter {
  recovered?: boolean
  priority?: ListAlertsPriorityItem[]
}

export const AlertInfo: React.FC<
  React.PropsWithChildren<{
    clusterId: string
    timeRange: TimeRange
  }>
> = ({ clusterId, timeRange }) => {
  const [alertInfo, setAlertInfo] = useState<ClusterGetAlertSummaryResp>({})
  const [loading, setLoading] = useState(false)
  useEffect(() => {
    async function fetchInfo() {
      try {
        setLoading(true)
        await getAlertSummary(clusterId, {
          start_ts: timeRange.startTs,
          end_ts: timeRange.endTs
        })
          .then((resp) => {
            setAlertInfo(resp.data)
          })
          .catch((err) => {
            message.error({
              content: err.response?.data?.errmsg || 'Internal server error',
              key: 'overview'
            })
          })
      } finally {
        setLoading(false)
      }
    }

    fetchInfo()
  }, [clusterId, timeRange])

  const alertMonthlyTrendConfig = {
    data: alertInfo.trends || [],
    xField: 'name',
    yField: 'value',
    seriesField: 'series',
    isStack: true,
    height: 250,
    label: {
      style: {
        fill: '#fff'
      }
    }
  }
  return (
    <>
      <Card title="Alert Trends">
        {loading ? <Spin></Spin> : <Column {...alertMonthlyTrendConfig} />}
      </Card>
    </>
  )
}

interface AlertTableDatasource extends JiraAlert {
  lastPageToken?: string
}

export const Alerts: React.FC<
  React.PropsWithChildren<{ clusterId: string }>
> = ({ clusterId }) => {
  const [curAlerts, setCurAlerts] = useState<AlertTableDatasource[]>()
  const [loading, setLoading] = useState<boolean>(false)
  const [pageToken, setPageToken] = useState<string | undefined>(undefined)
  const [reloadTrigger, setReloadTrigger] = useState(0)
  const [alertType, setAlertType] = useState<ListAlertsType>(
    ListAlertsType.external
  )
  const [timeRange, setTimeRange] = useState<TimeRange>({
    startTs: moment().utc().add(-2, 'month').startOf('month').unix(),
    endTs: moment().unix()
  })
  const [searchParams, setSearchParams] = useState<string>('')
  const [alertsFilter, setAlertsFilter] = useState<AlertFilter>({})
  const alertTypeOptions = [
    { label: 'External', value: ListAlertsType.external },
    { label: 'Internal', value: ListAlertsType.internal }
  ]

  const reload = async () => {
    setReloadTrigger((current) => current + 1)
  }

  useEffect(() => {
    const fetchAlerts = async () => {
      setLoading(true)
      try {
        const response = await listAlerts(clusterId, {
          start_ts: timeRange.startTs,
          end_ts: timeRange.endTs,
          type: alertType,
          page_token: pageToken,
          page_size: 10,
          search: searchParams,
          ...alertsFilter
        })
        setCurAlerts(
          response.data.items?.map((item) => ({
            ...item,
            lastPageToken: response.data.next_page_token // used in CursorTable
          })) || []
        )
      } catch (error) {
        message.error('Failed to fetch alerts')
      } finally {
        setLoading(false)
      }
    }

    fetchAlerts()
  }, [pageToken, reloadTrigger])

  const columns = useMemo(() => {
    const cols: ColumnsType<AlertTableDatasource> = [
      {
        title: 'Name',
        dataIndex: 'name',
        render: (_: any, { name, key }: JiraAlert) => {
          return (
            <Space direction="vertical">
              <a
                href={'https://tidb.atlassian.net/browse/' + key}
                target="_blank"
                rel="noreferrer"
              >
                {name}
              </a>
              <Typography.Text type="secondary">{key}</Typography.Text>
            </Space>
          )
        },
        width: 200
      },
      {
        title: 'Priority',
        dataIndex: 'priority',
        filters: [
          { text: 'Major', value: 'Major' },
          { text: 'Critical', value: 'Critical' }
        ],
        filterMultiple: true
      },
      {
        title: 'Recovered',
        dataIndex: 'recovered',
        render: (_: any, { recovered }: JiraAlert) => {
          return recovered ? 'true' : 'false'
        },
        filters: [
          { text: 'true', value: true },
          { text: 'false', value: false }
        ],
        filterMultiple: false
      },
      {
        title: 'CreatedAt',
        dataIndex: 'created_at',
        render: (_: any, { created_at }: JiraAlert) => {
          return dayjs
            .unix(created_at || 0)
            .format('YYYY-MM-DD HH:mm:ss (UTCZ)')
        }
      }
    ]
    return cols
  }, [])

  const onSearch = (search: string) => {
    setSearchParams(search)
    setPageToken(undefined)
  }

  const onTypeChange = (alertType: ListAlertsType) => {
    setAlertType(alertType)
    return reload()
  }

  const onTimeRangeChange: RangePickerProps['onChange'] = (
    dates,
    dateStrings
  ) => {
    if (dates) {
      setTimeRange({
        startTs: dates[0]?.unix() || 0,
        endTs: dates[1]?.unix() || 0
      })
      return reload()
    } else {
      console.log('Clear')
    }
  }

  const handleTableChange = (key: string) => {
    setPageToken(key)
  }

  return (
    <>
      <Row gutter={[16, 16]}>
        <Col span={24}>
          <RangePicker
            ranges={{
              'This Month': [
                moment().startOf('month'),
                moment().endOf('month')
              ],
              'Last 3 Months': [
                moment().add(-2, 'month').startOf('month'),
                moment()
              ],
              'Last 6 Months': [
                moment().add(-5, 'month').startOf('month'),
                moment()
              ]
            }}
            defaultValue={[
              moment(timeRange.startTs * 1000),
              moment(timeRange.endTs * 1000)
            ]}
            onChange={onTimeRangeChange}
          />
        </Col>
        <Col span={24}>
          <AlertInfo clusterId={clusterId} timeRange={timeRange} />
        </Col>
        <Col span={24}>
          <Card
            title="Alert List"
            extra={
              <ListToolBar
                reload={reload}
                noMgb={true}
                actions={[
                  <Radio.Group
                    options={alertTypeOptions}
                    onChange={(e) => onTypeChange(e.target.value)}
                    value={alertType}
                    optionType="button"
                    buttonStyle="solid"
                  />,
                  <Input.Group compact className="list-search-bar-container">
                    <Input.Search
                      placeholder="Search by Name"
                      style={{ width: '18rem' }}
                      defaultValue={searchParams || ''}
                      onSearch={(value: string) => {
                        return onSearch(value ? value.trim() : '')
                      }}
                      allowClear
                    />
                  </Input.Group>
                ]}
              />
            }
          >
            <CursorTable<AlertTableDatasource>
              columns={columns}
              rowKey="key"
              dataSource={curAlerts || []}
              loading={loading}
              onChange={handleTableChange as any}
              size="small"
              pagination={{
                position: 'bottomRight',
                size: 'small'
              }}
              // scroll={{ x: 1200 }}
            />
          </Card>
        </Col>
      </Row>
    </>
  )
}
