import { useRef, useEffect } from 'react'
import * as Plot from '@observablehq/plot'

const SpeakerPlot = ({ data, width = 750, height = 500 }) => {
  const containerRef = useRef()
  const allSpeakers = data.language_table.reduce(
    (sum, curr) => sum + curr.speakers,
    0
  )
  const languages = data.language_table
    .sort((a, b) => b.speakers - a.speakers)
    .slice(0, 100)
    .reduce((acc, d) => {
      acc.push({
        ...d,
        rank: acc.length + 1,
        cumSpeakers:
          acc.reduce((sum, curr) => sum + curr.speakers, 0) + d.speakers,
        cumSpeakersPercent:
          (acc.reduce((sum, curr) => sum + curr.speakers, 0) + d.speakers) /
          allSpeakers
      })
      return acc
    }, [])

  useEffect(() => {
    const plot = Plot.plot({
      width: width,
      height: height,
      subtitle: 'Number of languages vs speakers covered',
      x: {
        label: 'Languages',
        ticks: []
      },
      y: {
        label: 'Number of Speakers (millions)'
      },
      color: {
        legend: true,
        domain: ['Speakers', 'Cumulative Speakers'],
        range: ['green', 'lightgrey']
      },
      marks: [
        Plot.barY(languages, {
          x: 'rank',
          y: d => d.cumSpeakers / 1e6,
          fill: d => 'Cumulative Speakers',
          sort: { x: 'y' },
          title: d =>
            `The ${
              d.rank
            } most spoken languages cover\n${d.cumSpeakersPercent.toLocaleString(
              'en-US',
              { style: 'percent' }
            )} of all speakers`,
          tip: true // {y: d => d.cumSpeakers / 1e6 * 2}
        }),
        Plot.barY(languages, {
          x: 'rank',
          y: d => d.speakers / 1e6,
          title: d =>
            `${d.language_name}\n(${d.speakers.toLocaleString('en-US', {
              notation: 'compact',
              compactDisplay: 'long'
            })} speakers)`,
          tip: true,
          fill: d => 'Speakers',
          sort: { x: '-y' }
        }),
        Plot.crosshairX(languages, {
          x: 'rank',
          y: d => d.cumSpeakers / 1e6,
          textStrokeOpacity: 0,
          textFillOpacity: 0
        }),
        Plot.tip(['The 40 most spoken languages cover 80% of all speakers.'], {
          x: 40,
          y: languages[39].cumSpeakers / 1e6
        })
      ]
    })
    containerRef.current.append(plot)
    return () => plot.remove()
  }, [languages, width, height])

  return (
    <div
      ref={containerRef}
      style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center'
      }}
    />
  )
}

export default SpeakerPlot