import { ReloadOutlined } from '@ant-design/icons'
import { Bar, Column, Pie } from '@ant-design/plots'
import MarkdownPreview from '@uiw/react-markdown-preview'
import {
  Button,
  Card,
  notification,
  Space,
  Spin,
  Tag,
  Anchor,
  Layout
} from 'antd'
import Title from 'antd/lib/typography/Title'
import { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom'

import { reportGetReport } from 'apiClient/services/aiops'
import {
  Report,
  Block,
  BlockType,
  ChartType,
  Heading
} from 'apiClient/services/aiops/interface'

type HeadingWithID = Heading & { id: string }

export default function ReportDetail() {
  const { report_id } = useParams<{ report_id: string }>()
  const [report, setReport] = useState<Report>()
  const [loading, setLoading] = useState(true)
  const [reload, setReload] = useState(false)
  const [headings, setHeadings] = useState<HeadingWithID[]>([])

  async function fetch() {
    setLoading(true)
    setReport(undefined)
    setHeadings([])

    try {
      const data = (await reportGetReport(Number(report_id))).data
      setReport(data)

      // After fetching data, extract all heading blocks to build the menu
      if (data.content?.blocks) {
        const extractedHeadings: HeadingWithID[] = data.content.blocks
          .map((block, index) => {
            if (block.type === BlockType.heading && block.heading) {
              return {
                ...block.heading,
                id: `heading-${index}`
              }
            }
            return undefined
          })
          .filter((item): item is HeadingWithID => item !== undefined)

        setHeadings(extractedHeadings)
      }
    } catch (error: any) {
      notification.error({
        message: 'Failed',
        description: 'Failed to fetch report',
        placement: 'topRight'
      })
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    fetch()
  }, [reload, report_id])

  if (loading) {
    return (
      <div
        style={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          height: '300px'
        }}
      >
        <Spin tip="Loading..." />
      </div>
    )
  }

  return (
    <Card
      title={<Title level={4}>{`Report '${report?.metadata.name}'`}</Title>}
      extra={
        <Space>
          {report?.metadata.tags &&
            Object.entries(report.metadata.tags).map(([key, value]) => (
              <Tag key={key}>
                {key}:{value}
              </Tag>
            ))}
          <Button
            onClick={() => {
              setReload((pre) => !pre)
            }}
            icon={<ReloadOutlined />}
          ></Button>
        </Space>
      }
    >
      <Layout style={{ background: 'transparent' }}>
        <Layout.Content>
          {report?.content?.blocks.map((block, index) => (
            <div key={index} style={{ marginBottom: '24px' }}>
              <ReportBlockRender block={block} index={index} />
            </div>
          ))}
        </Layout.Content>

        <Layout.Sider
          width={200}
          theme="light"
          style={{
            position: 'sticky', // Make the sidebar stick on scroll
            height: 'calc(100vh - 48px)',
            overflow: 'auto',
            background: '#fff',
            marginLeft: '16px'
          }}
        >
          `<Title level={5}>Contents</Title>
          <Anchor>
            {headings.map((heading, index) => (
              <div style={{ paddingLeft: `${(heading.level - 1) * 12}px` }}>
                <Anchor.Link
                  key={heading.id}
                  href={`#${heading.id}`}
                  title={heading.content}
                />
              </div>
            ))}
          </Anchor>
        </Layout.Sider>
      </Layout>
    </Card>
  )
}

function ReportBlockRender({ block, index }: { block: Block; index: number }) {
  switch (block.type) {
    case BlockType.heading:
      var level = block.heading?.level || 4
      if (![1, 2, 3, 4, 5].includes(level)) {
        level = 4
      }
      return (
        <Title id={`heading-${index}`} level={level as 1 | 2 | 3 | 4 | 5}>
          {block.heading?.content}
        </Title>
      )

    case BlockType.paragraph:
      const source = block.paragraph?.content || ''
      return (
        <MarkdownPreview
          source={source}
          style={{ padding: 16, fontSize: 15 }}
          wrapperElement={{
            'data-color-mode': 'light' // 强制亮色模式，防止受系统深色模式影响
          }}
        />
      )

    case BlockType.chart:
      switch (block.chart?.chart_type) {
        case ChartType.column:
          const columnConfig = {
            data: block.chart?.column?.data || [],
            xField: block.chart?.column?.x_field || '',
            yField: block.chart?.column?.y_field || '',
            seriesField: block.chart?.column?.series_field || undefined,
            isStack: block.chart?.column?.is_stack || false,
            label: {
              style: {
                fill: '#fff'
              }
            },
            height: 300
          }

          return (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Card
                title={block.chart?.title || ''}
                size="small"
                style={{ width: '80%' }}
              >
                <Column {...columnConfig} />
              </Card>
            </div>
          )

        case ChartType.line:
          const lineConfig = {
            data: block.chart?.line?.data || [],
            xField: block.chart?.line?.x_field || '',
            yField: block.chart?.line?.y_field || '',
            label: {
              style: {
                fill: '#fff'
              }
            },
            height: 300
          }

          return (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Card
                title={block.chart?.title || ''}
                size="small"
                style={{ width: '80%' }}
              >
                <Bar {...lineConfig} />
              </Card>
            </div>
          )

        case ChartType.pie:
          const pieConfig = {
            data: block.chart?.pie?.data || [],
            angleField: block.chart?.pie?.angle_field || '',
            colorField: block.chart?.pie?.color_field || '',
            label: {
              type: 'outside',
              content: '{name}'
            },
            height: 300 // 控制高度，单位为像素
          }

          return (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Card
                title={block.chart?.title || ''}
                size="small"
                style={{ width: '80%' }}
              >
                <Pie {...pieConfig} />
              </Card>
            </div>
          )

        case ChartType.bar:
          const barConfig = {
            data: block.chart?.bar?.data || [],
            xField: block.chart?.bar?.x_field || '',
            yField: block.chart?.bar?.y_field || '',
            seriesField: block.chart?.bar?.series_field || undefined,
            isStack: block.chart?.bar?.is_stack || false,
            label: {
              style: {
                fill: '#fff'
              }
            },
            height: 300
          }

          return (
            <div
              style={{
                display: 'flex',
                justifyContent: 'center',
                alignItems: 'center'
              }}
            >
              <Card
                title={block.chart?.title || ''}
                size="small"
                style={{ width: '80%' }}
              >
                <Bar {...barConfig} />
              </Card>
            </div>
          )

        default:
          return <div>Unknown Chart Type</div>
      }
    default:
      return <div>Unknown Block Type</div>
  }
}
