import { Bar, Column, G2 } from '@ant-design/plots'
import { AspectRatio } from '@tidbcloud/uikit'
import {
  Card,
  Col,
  Divider,
  message,
  Row,
  Space,
  Spin,
  Statistic,
  DatePicker,
  Collapse
} from 'antd'
import moment from 'moment'
import type { Moment } from 'moment'
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'

import { getCloudOncallInfo } from 'apiClient/services/devops'
import {
  DashboardCloudOncallInfoResp,
  EntitySeriesMonthlyTrend
} from 'apiClient/services/devops/interface'

import { TimeRange } from '../TimeRange'
import { TopTenantTable } from '../TopTenants'

type RangeValue = [Moment | null, Moment | null] | null

export const OncallDashboard: React.FC<
  React.PropsWithChildren<unknown>
> = () => {
  const [dates, setDates] = useState<RangeValue>(null)
  const [value, setValue] = useState<RangeValue>([
    moment().utc().add(-2, 'month').startOf('month'),
    moment().utc().endOf('month')
  ])
  const [timeRange, setTimeRange] = useState<TimeRange>({
    startTs: moment().utc().add(-2, 'month').startOf('month').unix(),
    endTs: moment().unix()
  })

  const disabledDate = (current: Moment) => {
    if (current < moment().utc().add(-12, 'month')) {
      return true
    }
    if (current > moment().utc().endOf('month')) {
      return true
    }
    if (!dates) {
      return false
    }
    const tooLate = dates[0] && current.diff(dates[0], 'months') > 12
    const tooEarly = dates[1] && dates[1].diff(current, 'months') > 12
    return !!tooEarly || !!tooLate
  }

  const onOpenChange = (open: boolean) => {
    if (open) {
      setDates([null, null])
    } else {
      setDates(null)
      const start = value![0]!.utc().startOf('month').unix()
      const end = value![1]!.utc().endOf('month').unix()
      if (timeRange.startTs === start && timeRange.endTs === end) {
        return
      }
      setTimeRange({
        startTs: start,
        endTs: end
      })
    }
  }
  return (
    <>
      <Row justify="end">
        <Col>
          <DatePicker.RangePicker
            picker="month"
            ranges={{
              'This Month': [
                moment().utc().startOf('month'),
                moment().utc().endOf('month')
              ],
              'Last 3 Months': [
                moment().utc().add(-2, 'month').startOf('month'),
                moment().utc().endOf('month')
              ],
              'Last 6 Months': [
                moment().utc().add(-5, 'month').startOf('month'),
                moment().utc().endOf('month')
              ],
              'Last 1 Year': [
                moment().utc().add(-11, 'month').startOf('month'),
                moment().utc().endOf('month')
              ]
            }}
            value={dates || value}
            disabledDate={disabledDate}
            onOpenChange={onOpenChange}
            onCalendarChange={(val) => {
              setDates(val)
            }}
            onChange={(val) => {
              setValue(val)
            }}
          />
        </Col>
      </Row>

      <Collapse ghost defaultActiveKey={['tcoc', 'eazybi']}>
        <Collapse.Panel header="TCOC" key="tcoc">
          <Row gutter={[16, 16]}>
            <OncallInfo timeRange={timeRange} />
          </Row>
        </Collapse.Panel>
        <Collapse.Panel header="EazyBI" key="eazybi">
          <Row gutter={[16, 16]}>
            <Col span={24}>
              <AspectRatio ratio={16 / 16}>
                <iframe
                  frameBorder="0"
                  src="https://aod.eazybi.com/accounts/119942/embed/dashboard/194515?embed_token=9qsndmu60jpao3qrng92zztpx3waoidgbcd60tkl5srkfeio0r8fwequ1mzj"
                ></iframe>
              </AspectRatio>
            </Col>
          </Row>
        </Collapse.Panel>
      </Collapse>
    </>
  )
}

export const OncallInfo: React.FC<
  React.PropsWithChildren<{ timeRange: TimeRange }>
> = ({ timeRange }) => {
  const [oncallInfo, setOncallInfo] = useState<DashboardCloudOncallInfoResp>({})
  const [loading, setLoading] = useState(false)
  useEffect(() => {
    async function fetchInfo() {
      try {
        setLoading(true)
        await getCloudOncallInfo({
          startTs: timeRange.startTs,
          endTs: timeRange.endTs
        })
          .then((resp) => {
            setOncallInfo(resp.data)
          })
          .catch((err) => {
            message.error({
              content: err.response?.data?.errmsg || 'Internal server error',
              key: 'overview'
            })
          })
      } finally {
        setLoading(false)
      }
    }

    fetchInfo()
  }, [timeRange])
  G2.registerInteraction('element-link', {
    start: [
      {
        trigger: 'interval:mouseenter',
        action: 'element-link-by-color:link'
      }
    ],
    end: [
      {
        trigger: 'interval:mouseleave',
        action: 'element-link-by-color:unlink'
      }
    ]
  })
  const componentsMonthlyTrendConfig = {
    data: oncallInfo.componentMonthlyTrend || [],
    xField: 'value',
    yField: 'month',
    seriesField: 'series',
    isStack: true,
    isPercent: true,
    height: 300,
    label: {
      style: {
        fill: '#fff'
      },
      content: (item: EntitySeriesMonthlyTrend) => {
        return item?.value?.toFixed(2) || ''
      }
    },
    interactions: [
      {
        type: 'element-highlight-by-color'
      },
      {
        type: 'element-link'
      }
    ]
  }
  const priorityMonthlyTrendConfig = {
    data: oncallInfo.priorityMonthlyTrends || [],
    xField: 'month',
    yField: 'value',
    seriesField: 'series',
    isStack: true,
    height: 200,
    label: {
      style: {
        fill: '#fff'
      }
    }
  }
  return (
    <>
      <Col span={8}>
        <Card title="Cloud Oncall Summary">
          {loading ? (
            <Spin></Spin>
          ) : (
            <>
              <Row gutter={[16, 16]}>
                <Col span={12}>
                  <Statistic
                    title={'Total'}
                    value={oncallInfo.total}
                    valueStyle={{
                      color: '#3f8600',
                      fontSize: '38px',
                      fontWeight: 600
                    }}
                  />
                </Col>
                <Col span={12}>
                  <Statistic
                    title={'Backlog'}
                    value={oncallInfo.backlogTotal}
                    valueStyle={{
                      color: '#3f8600',
                      fontSize: '38px',
                      fontWeight: 600
                    }}
                  />
                </Col>
                <Col span={12}>
                  <Statistic
                    title={'MTTR'}
                    value={oncallInfo.ttrInDays}
                    precision={1}
                    suffix={'day'}
                    valueStyle={{
                      color: '#3f8600',
                      fontSize: '38px',
                      fontWeight: 600
                    }}
                  />
                </Col>
              </Row>
            </>
          )}
        </Card>
      </Col>
      <Col span={16}>
        <Card title="Cloud Oncall Trends By Priority">
          {loading ? <Spin></Spin> : <Column {...priorityMonthlyTrendConfig} />}
        </Card>
      </Col>
      <Col span={24}>
        <Card title="Cloud Oncall Trends By Components">
          {loading ? <Spin></Spin> : <Bar {...componentsMonthlyTrendConfig} />}
        </Card>
      </Col>
      <Col span={24}>
        <Card title="Cloud Oncall Top Tenants">
          {loading ? (
            <Spin></Spin>
          ) : (
            <TopTenantTable
              tenants={oncallInfo.topTenants || []}
              renderAction={(_, record) => {
                return (
                  <Space split={<Divider type="vertical" />}>
                    {record.name ? (
                      <Link
                        to={`/orgs/${record.id}?name=${record.name}`}
                        target="_blank"
                      >
                        Tenant Detail
                      </Link>
                    ) : (
                      '-'
                    )}
                    <a
                      href={replaceJiraQuery(
                        'https://tidb.atlassian.net/issues/?jql=project%20%3D%20{PROJECT}%20AND%20%22Tenant%20ID%22%20~%20%22{TENANT_ID}%22%20AND%20created%20%3E%3D%20{TIMERANGE_START}%20AND%20created%20%3C%3D%20{TIMERANGE_END}%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC',
                        'TCOC',
                        record.id || '',
                        timeRange
                      )}
                      target="_blank"
                      rel="noreferrer"
                    >
                      Jira
                    </a>
                  </Space>
                )
              }}
            />
          )}
        </Card>
      </Col>
    </>
  )
}

export const replaceJiraQuery = (
  baseQuery: string,
  project: string,
  tenantId: string,
  timeRange: TimeRange
) => {
  let q: string
  q = baseQuery.replaceAll('{PROJECT}', `${project}`)
  q = q.replaceAll('{TENANT_ID}', `${tenantId}`)
  q = q.replaceAll(
    '{TIMERANGE_START}',
    `${moment.unix(timeRange.startTs).format('YYYY-MM-DD')}`
  )
  q = q.replaceAll(
    '{TIMERANGE_END}',
    `${moment.unix(timeRange.endTs).format('YYYY-MM-DD')}`
  )

  return q
}
