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

import { Column } from '@ant-design/plots'
import { Table } from 'antd'
import { ColumnsType } from 'antd/lib/table'
import { useParams } from 'react-router-dom'
import useSWR from 'swr'

import { getReport } from '~/api'

import './index.css'

export interface SlowLogMetricDetail {
  timestamp: number
  value: number
  digest: string
}

export interface SlowLogMetric {
  digest_mem_max: SlowLogMetricDetail[]
  digest_query_time: SlowLogMetricDetail[]
  digest_process_time: SlowLogMetricDetail[]
  digest_total_keys: SlowLogMetricDetail[]
}

export interface SlowLogCount {
  timestamp: number
  value: number
}

export interface SlowLogDetail {
  digest: string
  db: string
  count: number
  count_ratio: string
  query_time_total: number
  query_time_avg: string
  query_time_ratio: string
  process_time_total: string
  process_time_avg: string
  process_time_ratio: string
  mem_max_total: string
  mem_max_avg: string
  result_rows_total: number
  failure_count: number
  sql_statement: string
}

export interface SlowLogStates {
  metrics_detail: SlowLogMetric
  slowlog_count: SlowLogCount[]
  slowlog_detail: SlowLogDetail[]
}

const SlowLogVisPage: React.FC = () => {
  const { orgId, cid, rid } = useParams<'orgId' | 'cid' | 'rid'>()
  const { data: reportRes } = useSWR(`/reports/slowlog-visual/${rid}`, () =>
    getReport(orgId!, cid!, rid!)
  )
  const states = useMemo<SlowLogStates>(() => {
    const ms = reportRes?.data?.data as any as SlowLogStates
    if (!ms) {
      return {
        metrics_detail: {
          digest_mem_max: [],
          digest_query_time: [],
          digest_total_keys: [],
          digest_process_time: []
        },
        slowlog_count: [],
        slowlog_detail: []
      }
    }
    return ms
  }, [reportRes])

  const metricConfig = (metric: SlowLogMetricDetail[]) => {
    return {
      data: metric.map((v) => {
        return {
          timestamp: toTime(v.timestamp),
          value: Number(v.value.toFixed(3)),
          digest: v.digest
        }
      }),
      xField: 'timestamp',
      yField: 'value',
      seriesField: 'digest',
      isStack: true,
      legend: { itemWidth: 50 },
      height: 200,
      label: {
        style: {
          fill: '#fff'
        }
      }
    }
  }

  const slowLogCountConfig = {
    data: states.slowlog_count.map((v) => {
      return {
        timestamp: toTime(v.timestamp),
        value: v.value
      }
    }),
    xField: 'timestamp',
    yField: 'value',
    isStack: true,
    height: 200,
    label: {
      style: {
        fill: '#fff'
      }
    }
  }

  const columnsApprovalTask: ColumnsType<SlowLogDetail> = [
    {
      title: 'Digest',
      render: (_: any, record) => {
        return record.digest
      },
      ellipsis: true
    },
    {
      title: 'DB',
      render: (_: any, record) => {
        return record.db
      },
      ellipsis: true
    },
    {
      title: 'Count',
      render: (_: any, record) => {
        return record.count
      }
    },
    {
      title: 'Count_ratio',
      render: (_: any, record) => {
        return record.count_ratio
      }
    },
    {
      title: 'Query_time_total',
      render: (_: any, record) => {
        return record.query_time_total
      }
    },
    {
      title: 'Query_time_ratio',
      render: (_: any, record) => {
        return record.query_time_ratio
      }
    },
    {
      title: 'Query_time_avg',
      render: (_: any, record) => {
        return record.query_time_avg
      }
    },
    {
      title: 'Process_time_total',
      render: (_: any, record) => {
        return record.process_time_total
      }
    },
    {
      title: 'Process_time_avg',
      render: (_: any, record) => {
        return record.process_time_avg
      }
    },
    {
      title: 'Mem_max_total',
      render: (_: any, record) => {
        return record.mem_max_total
      }
    },
    {
      title: 'Mem_max_avg',
      render: (_: any, record) => {
        return record.mem_max_avg
      }
    },
    {
      title: 'Result_rows_sum',
      render: (_: any, record) => {
        return record.result_rows_total
      }
    },
    {
      title: 'Failed count',
      render: (_: any, record) => {
        return record.failure_count
      }
    },
    {
      title: 'Sql Statement',
      render: (_: any, record) => {
        return record.sql_statement
      },
      ellipsis: true
    }
  ]

  const [currentPage, setCurrentPage] = useState(1)
  const pageSize = 10
  const handleChangePage = (page: number) => {
    setCurrentPage(page)
  }

  const startIndex = (currentPage - 1) * pageSize
  const endIndex = startIndex + pageSize
  const currentPageData = states.slowlog_detail.slice(startIndex, endIndex)

  return reportRes ? (
    <div style={{ padding: 40 }}>
      <h1>Slow Log Visualization</h1>
      <b>Mem Max (GB)</b>
      <Column
        {...metricConfig(
          states.metrics_detail.digest_mem_max.sort((a, b) =>
            a.timestamp === b.timestamp
              ? b.value - a.value
              : a.timestamp - b.timestamp
          )
        )}
      ></Column>
      <br></br>
      <b>Query Time (s)</b>
      <Column
        {...metricConfig(
          states.metrics_detail.digest_query_time.sort((a, b) =>
            a.timestamp === b.timestamp
              ? b.value - a.value
              : a.timestamp - b.timestamp
          )
        )}
      ></Column>
      <br></br>
      <b>Process Time (s)</b>
      <Column
        {...metricConfig(
          states.metrics_detail.digest_process_time.sort((a, b) =>
            a.timestamp === b.timestamp
              ? b.value - a.value
              : a.timestamp - b.timestamp
          )
        )}
      ></Column>
      <br></br>
      <b>Total Keys</b>
      <Column
        {...metricConfig(
          states.metrics_detail.digest_total_keys.sort((a, b) =>
            a.timestamp === b.timestamp
              ? b.value - a.value
              : a.timestamp - b.timestamp
          )
        )}
      ></Column>
      <br></br>
      <b>Slow Log Count</b>
      <Column {...slowLogCountConfig}></Column>
      <br></br>

      <b>Slow Log Detail</b>
      <div className='slow-log-viz-table-container'>
        <Table<SlowLogDetail>
          columns={columnsApprovalTask}
          rowKey='id'
          dataSource={currentPageData}
          size='small'
          pagination={{
            total: states.slowlog_detail.length,
            pageSize: pageSize,
            current: currentPage,
            onChange: handleChangePage
          }}
        ></Table>
      </div>
    </div>
  ) : (
    <div>
      <h1>Loading Data...</h1>
    </div>
  )
}

export const toTime = (ts: number) => {
  const date = new Date(ts * 1000)

  const hours = ('0' + date.getHours()).slice(-2)
  const minutes = ('0' + date.getMinutes()).slice(-2)
  const seconds = ('0' + date.getSeconds()).slice(-2)

  const time = `${hours}:${minutes}:${seconds}`

  return time
}

export default SlowLogVisPage
