import React, { useEffect, useRef, useState } from 'react'
import Plot from 'react-plotly.js'
import Plotly from 'plotly.js-dist-min'

function PlotFigure({
  figure,
  indexedFigure = null,
  onRequestIndexedFigure = null,
  title,
  subtitle = '',
  forceHideLegend = false,
  className = '',
  lazy = false,
  showPointIndexToggle = false,
  headerActions = null,
  trailingHeaderActions = null,
  revisionKey = '',
}) {
  const containerRef = useRef(null)
  const [shouldRenderPlot, setShouldRenderPlot] = useState(() => !lazy)
  const [showPointIndices, setShowPointIndices] = useState(false)
  const [loadingIndexedFigure, setLoadingIndexedFigure] = useState(false)
  const figureResetKey = revisionKey ? String(revisionKey) : figure

  useEffect(() => {
    if (!lazy) {
      setShouldRenderPlot(true)
      return undefined
    }
    if (shouldRenderPlot) return undefined
    if (typeof window === 'undefined' || !('IntersectionObserver' in window)) {
      setShouldRenderPlot(true)
      return undefined
    }
    const target = containerRef.current
    if (!target) return undefined
    const observer = new IntersectionObserver(
      (entries) => {
        const isVisible = entries.some((entry) => entry.isIntersecting || entry.intersectionRatio > 0)
        if (isVisible) {
          setShouldRenderPlot(true)
          observer.disconnect()
        }
      },
      { rootMargin: '240px 0px', threshold: 0.01 },
    )
    observer.observe(target)
    return () => observer.disconnect()
  }, [lazy, shouldRenderPlot])

  useEffect(() => {
    setShowPointIndices(false)
    setLoadingIndexedFigure(false)
  }, [figureResetKey])

  if (!figure) {
    return <div className="empty-box">Grafico indisponivel.</div>
  }

  const hasIndexedFigure = Boolean(indexedFigure)
  const canRequestIndexedFigure = typeof onRequestIndexedFigure === 'function'
  const canToggleIndices = hasIndexedFigure || canRequestIndexedFigure
  const activeFigure = showPointIndices && hasIndexedFigure ? indexedFigure : figure
  const safeFigure = activeFigure || { data: [], layout: {} }
  const baseLayout = safeFigure.layout || {}
  const { width: _ignoreWidth, ...layoutNoWidth } = baseLayout
  const safeAnnotations = Array.isArray(baseLayout.annotations)
    ? baseLayout.annotations.map((annotation) => {
        const { ax, ay, axref, ayref, arrowhead, arrowsize, arrowwidth, arrowcolor, standoff, ...clean } = annotation || {}
        return { ...clean, showarrow: false }
      })
    : baseLayout.annotations

  const data = (safeFigure.data || []).map((trace) => (
    forceHideLegend ? { ...trace, showlegend: false } : { ...trace }
  ))
  const layout = {
    ...layoutNoWidth,
    autosize: true,
    annotations: Array.isArray(safeAnnotations) ? safeAnnotations : [],
    margin: baseLayout.margin || { t: 40, r: 20, b: 50, l: 50 },
  }
  if (forceHideLegend) {
    layout.showlegend = false
  }

  const plotHeight = layout.height ? `${layout.height}px` : '100%'
  const plotRevision = `${showPointIndices && hasIndexedFigure ? 'indices' : 'base'}:${String(revisionKey || '')}`
  const cardClassName = `plot-card ${className}`.trim()

  async function handleToggleChange(event) {
    const checked = Boolean(event.target.checked)
    if (!checked) {
      setShowPointIndices(false)
      return
    }
    if (hasIndexedFigure) {
      setShowPointIndices(true)
      return
    }
    if (!canRequestIndexedFigure || loadingIndexedFigure) return
    setLoadingIndexedFigure(true)
    try {
      const loadedFigure = await onRequestIndexedFigure()
      setShowPointIndices(Boolean(loadedFigure))
    } catch {
      setShowPointIndices(false)
    } finally {
      setLoadingIndexedFigure(false)
    }
  }

  const toggleTitle = loadingIndexedFigure
    ? 'Carregando INDICES dos pontos...'
    : hasIndexedFigure
      ? 'Exibir INDICES dos pontos'
      : canRequestIndexedFigure
        ? 'Carregar INDICES dos pontos sob demanda'
        : 'Este gráfico não trouxe uma versão com INDICES.'

  return (
    <div ref={containerRef} className={cardClassName}>
      {title || subtitle || showPointIndexToggle || headerActions || trailingHeaderActions ? (
        <div className="plot-card-head">
          <div className="plot-card-head-main">
            {title ? <h4 className="plot-card-title">{title}</h4> : null}
            {subtitle ? <div className="plot-card-subtitle">{subtitle}</div> : null}
          </div>
          <div className="plot-card-head-actions">
            {headerActions}
            {showPointIndexToggle ? (
              <label className={`plot-card-toggle${canToggleIndices ? '' : ' is-disabled'}`}>
                <input
                  type="checkbox"
                  checked={showPointIndices}
                  disabled={!canToggleIndices || loadingIndexedFigure}
                  onChange={handleToggleChange}
                  title={toggleTitle}
                />
                {loadingIndexedFigure ? 'Carregando...' : 'INDICES'}
              </label>
            ) : null}
            {trailingHeaderActions}
          </div>
        </div>
      ) : null}
      {shouldRenderPlot ? (
        <div className="plot-card-body">
          <Plot
            data={data}
            layout={layout}
            revision={plotRevision}
            config={{ responsive: true, displaylogo: false }}
            style={{ width: '100%', height: plotHeight, minHeight: '320px' }}
            useResizeHandler
            plotly={Plotly}
          />
        </div>
      ) : (
        <div className="plot-lazy-placeholder">Carregando gráfico...</div>
      )}
    </div>
  )
}

export default PlotFigure
