import { BrushEvent } from '@elastic/charts'
import TimeRangePicker from '@tidb-cloud-uikit/components/TimeRangePicker'
import { Box, Flex, Typography } from '@tidbcloud/uikit'
import { TimeRange, TimeRangeValue, toTimeRangeValue } from '@tidbcloud/uikit/biz'
import dayjs from 'dayjs'
import { observer } from 'mobx-react'
import { useEffect, useMemo, useRef, useState } from 'react'

import AutoRefreshButton, {
  AutoRefreshButtonRef,
  DEFAULT_AUTO_REFRESH_SECONDS
} from 'dbaas/screens/ClusterV2/components/AutoRefreshButton'
import { dbaasUrl } from 'dbaas/services/endpoint'

import { useDataApiContext } from '../../context'
import { OVERVIEW_QUICK_RANGES } from '../../utils'
import MetricsPanel from '../Usage/MetricsPanel'

import { configs } from './helper'
import Performance from './Performance'
import Status from './Status'

export const DEFAULT_TIME_RANGE: TimeRange = {
  type: 'relative',
  value: 30 * 60
}

export const UsagePanel: React.FC<React.PropsWithChildren<unknown>> = () => {
  const { orgId, projectId, editApp } = useDataApiContext()
  const [autoRefreshValue, setAutoRefreshValue] = useState<number>(DEFAULT_AUTO_REFRESH_SECONDS)
  const [isLoading, setIsLoading] = useState(false)
  const [timeRange, setTimeRange] = useState<TimeRange>(DEFAULT_TIME_RANGE)
  const autoRefreshRef = useRef<AutoRefreshButtonRef>(null)

  const [timeRangeValue, setTimeRangeValue] = useState<TimeRangeValue>(toTimeRangeValue(DEFAULT_TIME_RANGE))

  const sourceURI = `${dbaasUrl}/api/v1/dataservices/central/orgs/${orgId}/projects/${projectId}/apps/${editApp?.id}/metrics`
  const metricsConfig = useMemo(() => {
    return configs.map((it) => {
      return {
        ...it,
        url: `${sourceURI}/${it.url}?${it.params ?? ''}`,
        fixMinInterval: false,
        chartSettings: {
          xDomain: {
            minInterval: 60 * 1000,
            min: timeRangeValue[0] * 1000,
            max: timeRangeValue[1] * 1000
          },
          onBrushEnd: (v: BrushEvent) => {
            if (!v.x) {
              return
            }

            let value: [number, number]
            const tr = v.x.map((d) => (d as number) / 1000)
            const delta = tr[1] - tr[0]
            if (delta < 60) {
              const offset = Math.floor(delta / 2)
              value = [Math.ceil(tr[0] + offset - 30), Math.floor(tr[1] - offset + 30)]
            } else {
              value = [Math.ceil(tr[0]), Math.floor(tr[1])]
            }
            setTimeRangeValue(value)
          }
        }
      }
    })
  }, [sourceURI, timeRangeValue])

  useEffect(() => {
    setTimeRangeValue(toTimeRangeValue(DEFAULT_TIME_RANGE))
    setTimeRange(DEFAULT_TIME_RANGE)
  }, [editApp?.id])

  return (
    <Box mt={24}>
      <Flex gap={16} mt={16}>
        <TimeRangePicker
          value={timeRange}
          quickRanges={OVERVIEW_QUICK_RANGES}
          loading={isLoading}
          minDateTime={() => dayjs().subtract(30, 'day').toDate()}
          maxDateTime={() => dayjs().toDate()}
          onChange={(v) => {
            setTimeRange(v)
            setTimeRangeValue(toTimeRangeValue(v))
          }}
        />

        <AutoRefreshButton
          ref={autoRefreshRef}
          autoRefreshValue={autoRefreshValue}
          onAutoRefreshChange={(v) => {
            setAutoRefreshValue(v)
          }}
          onRefresh={() => {
            setTimeRangeValue(toTimeRangeValue(timeRange))
          }}
          loading={isLoading}
        />
      </Flex>

      <Status from={timeRangeValue[0]} to={timeRangeValue[1]} appId={editApp?.id ?? ''} />

      <Typography variant="title-lg" my={24}>
        Data App Metrics
      </Typography>

      <MetricsPanel
        metrics={metricsConfig}
        timeRangeValue={timeRangeValue}
        onLoading={(loading) => setIsLoading(loading)}
      />

      <Performance appId={editApp?.id ?? ''} start={timeRangeValue[0]} end={timeRangeValue[1]} timeRange={timeRange} />
    </Box>
  )
}

export default observer(UsagePanel)
