import { useState, useEffect, useRef, useEffectEvent } from 'react'
import { Box, Button, Link, Typography } from '@mui/material'
import type { WidgetNoteProps } from './types'
import { styles } from './style'
import ReactMarkdown, { type Components } from 'react-markdown'

const DEFAULT_LABELS = {
  showMore: 'Show More',
  showLess: 'Show Less',
} as const

const DEFAULT_P = ({ children }: { children?: React.ReactNode }) => (
  <Typography paragraph color='inherit' variant='caption'>
    {children}
  </Typography>
)

const COMPONENTS: Components = {
  h1: DEFAULT_P,
  h2: DEFAULT_P,
  h3: DEFAULT_P,
  p: DEFAULT_P,
  a: ({ children, href, target = '_blank', rel = 'noopener noreferrer' }) => (
    <Link
      href={href}
      target={target}
      rel={rel}
      color='text.primary'
      underline='always'
    >
      {children}
    </Link>
  ),
  img: () => null,
  ul: DEFAULT_P,
  ol: DEFAULT_P,
  li: DEFAULT_P,
}

/**
 * Displays text content with markdown support and automatic show more/less functionality for long content. Automatically detects content exceeding 3 lines and shows an expand/collapse button.
 *
 * @example
 * ```tsx
 * <WidgetNote>
 *   {"**Important:** This data is from Q4 2024."}
 * </WidgetNote>
 * ```
 */
export function WidgetNote({
  children,
  labels = DEFAULT_LABELS,
}: WidgetNoteProps) {
  const [isExpanded, setIsExpanded] = useState(false)
  const [shouldShowToggle, setShouldShowToggle] = useState(false)
  const contentRef = useRef<HTMLDivElement>(null)

  const checkOverflow = useEffectEvent(() => {
    if (contentRef.current) {
      // Check if content overflows 3 lines
      const isOverflowing =
        contentRef.current.scrollHeight > contentRef.current.clientHeight
      setShouldShowToggle(isOverflowing)
    }
  })

  useEffect(() => {
    checkOverflow()
  }, [children])

  useEffect(() => {
    const element = contentRef.current
    if (!element) return

    const resizeObserver = new ResizeObserver(() => {
      checkOverflow()
    })

    resizeObserver.observe(element)

    return () => {
      resizeObserver.disconnect()
    }
  }, [])

  if (!children) {
    return null
  }

  const handleToggle = () => {
    setIsExpanded(!isExpanded)
  }

  const mergedLabels = { ...DEFAULT_LABELS, ...labels }

  return (
    <Box>
      <Box
        ref={contentRef}
        sx={{
          ...styles.root,
          ...(isExpanded ? styles.expanded : styles.clamped),
        }}
      >
        <ReactMarkdown components={COMPONENTS}>{children}</ReactMarkdown>
      </Box>
      {(shouldShowToggle || isExpanded) && (
        <Button
          onClick={handleToggle}
          variant='text'
          color='primary'
          sx={styles.linkButton}
          aria-expanded={isExpanded}
          aria-label={
            isExpanded ? mergedLabels.showLess : mergedLabels.showMore
          }
          aria-controls='note-content'
        >
          {isExpanded ? mergedLabels.showLess : mergedLabels.showMore}
        </Button>
      )}
    </Box>
  )
}
