import { LineChart } from 'recharts/lib/chart/LineChart'
import { AreaChart } from 'recharts/lib/chart/AreaChart'
import { ComposedChart } from 'recharts/lib/chart/ComposedChart'
import { Line } from 'recharts/lib/cartesian/Line'
import { XAxis } from 'recharts/lib/cartesian/XAxis'
import { YAxis } from 'recharts/lib/cartesian/YAxis'
import { Area } from 'recharts/lib/cartesian/Area'
import { Bar } from 'recharts/lib/cartesian/Bar'
import { Tooltip } from 'recharts/lib/component/Tooltip'
import { Legend } from 'recharts/lib/component/Legend'
import { ResponsiveContainer } from 'recharts/lib/component/ResponsiveContainer'
import { PieChart } from 'recharts/lib/chart/PieChart'
import { Cell } from 'recharts/lib/component/Cell'
import { Pie } from 'recharts/lib/polar/Pie'
import { abbrNum } from '@/lib/format'
import { useRouter } from 'next/router'
import { timeUnitForRange } from '@/lib/time'

const dateFormatter = (when, from, to) => {
  const unit = xAxisName(when, from, to)
  return timeStr => {
    const date = new Date(timeStr)
    switch (unit) {
      case 'day':
      case 'week':
        return `${('0' + (date.getUTCMonth() % 12 + 1)).slice(-2)}/${date.getUTCDate()}`
      case 'month':
        return `${('0' + (date.getUTCMonth() % 12 + 1)).slice(-2)}/${String(date.getUTCFullYear()).slice(-2)}`
      default:
        return `${date.getHours() % 12 || 12}${date.getHours() >= 12 ? 'pm' : 'am'}`
    }
  }
}

const labelFormatter = (when, from, to) => {
  const unit = xAxisName(when, from, to)
  const dateFormat = dateFormatter(when, from, to)
  return timeStr => `${unit} ${dateFormat(timeStr)}`
}

function xAxisName (when, from, to) {
  if (from) {
    return timeUnitForRange([from, to])
  }
  switch (when) {
    case 'week':
    case 'month':
      return 'day'
    case 'year':
    case 'forever':
      return 'month'
    default:
      return 'hour'
  }
}

const transformData = data => {
  return data.map(entry => {
    const obj = { time: entry.time }
    entry.data.forEach(entry1 => {
      obj[entry1.name] = entry1.value
    })
    return obj
  })
}

const COLORS = [
  'var(--bs-secondary)',
  'var(--bs-info)',
  'var(--bs-success)',
  'var(--bs-boost)',
  'var(--theme-grey)',
  'var(--bs-danger)',
  'var(--bs-code-color)'
]

function getColor (i) {
  return COLORS[i % COLORS.length]
}

export function WhenAreaChart ({ data }) {
  const router = useRouter()
  if (!data || data.length === 0) {
    return null
  }
  // transform data into expected shape
  data = transformData(data)
  // need to grab when
  const when = router.query.when
  const from = router.query.from
  const to = router.query.to

  return (
    <ResponsiveContainer width='100%' height={300} minWidth={300}>
      <AreaChart
        data={data}
        margin={{
          top: 5,
          right: 5,
          left: 0,
          bottom: 0
        }}
      >
        <XAxis
          dataKey='time' tickFormatter={dateFormatter(when, from, to)} name={xAxisName(when, from, to)}
          tick={{ fill: 'var(--theme-grey)' }}
        />
        <YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
        <Tooltip labelFormatter={labelFormatter(when, from, to)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
        <Legend />
        {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) =>
          <Area key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={getColor(i)} fill={getColor(i)} />)}
      </AreaChart>
    </ResponsiveContainer>
  )
}

export function WhenLineChart ({ data }) {
  const router = useRouter()
  if (!data || data.length === 0) {
    return null
  }
  // transform data into expected shape
  data = transformData(data)
  // need to grab when
  const when = router.query.when
  const from = router.query.from
  const to = router.query.to

  return (
    <ResponsiveContainer width='100%' height={300} minWidth={300}>
      <LineChart
        data={data}
        margin={{
          top: 5,
          right: 5,
          left: 0,
          bottom: 0
        }}
      >
        <XAxis
          dataKey='time' tickFormatter={dateFormatter(when, from, to)} name={xAxisName(when, from, to)}
          tick={{ fill: 'var(--theme-grey)' }}
        />
        <YAxis tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
        <Tooltip labelFormatter={labelFormatter(when, from, to)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
        <Legend />
        {Object.keys(data[0]).filter(v => v !== 'time' && v !== '__typename').map((v, i) =>
          <Line key={v} type='monotone' dataKey={v} name={v} stroke={getColor(i)} fill={getColor(i)} />)}
      </LineChart>
    </ResponsiveContainer>
  )
}

export function WhenComposedChart ({
  data,
  lineNames = [], lineAxis = 'left',
  areaNames = [], areaAxis = 'left',
  barNames = [], barAxis = 'left', barStackId
}) {
  const router = useRouter()
  if (!data || data.length === 0) {
    return null
  }
  // transform data into expected shape
  data = transformData(data)
  // need to grab when
  const when = router.query.when
  const from = router.query.from
  const to = router.query.to

  return (
    <ResponsiveContainer width='100%' height={300} minWidth={300}>
      <ComposedChart
        data={data}
        margin={{
          top: 5,
          right: 5,
          left: 0,
          bottom: 0
        }}
      >
        <XAxis
          dataKey='time' tickFormatter={dateFormatter(when, from, to)} name={xAxisName(when, from, to)}
          tick={{ fill: 'var(--theme-grey)' }}
        />
        <YAxis yAxisId='left' orientation='left' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
        <YAxis yAxisId='right' orientation='right' allowDecimals={false} stroke='var(--theme-grey)' tickFormatter={abbrNum} tick={{ fill: 'var(--theme-grey)' }} />
        <Tooltip labelFormatter={labelFormatter(when, from, to)} contentStyle={{ color: 'var(--bs-body-color)', backgroundColor: 'var(--bs-body-bg)' }} />
        <Legend />
        {barNames?.map((v, i) =>
          <Bar yAxisId={barAxis} key={v} stackId={barStackId} type='monotone' dataKey={v} name={v} stroke={getColor(i)} fill={getColor(i)} />)}
        {areaNames?.map((v, i) =>
          <Area yAxisId={areaAxis} key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={getColor(barNames.length + i)} fill={getColor(barNames.length + i)} />)}
        {lineNames?.map((v, i) =>
          <Line yAxisId={lineAxis} key={v} type='monotone' dataKey={v} name={v} stackId='1' stroke={getColor(barNames.length + areaNames.length + i)} />)}
      </ComposedChart>
    </ResponsiveContainer>
  )
}

export function GrowthPieChart ({ data }) {
  const nonZeroData = data.filter(d => d.value > 0)

  return (
    <ResponsiveContainer width='100%' height={250} minWidth={200}>
      <PieChart margin={{ top: 5, right: 5, bottom: 5, left: 5 }}>
        <Pie
          dataKey='value'
          isAnimationActive={false}
          data={nonZeroData}
          cx='50%'
          cy='50%'
          minAngle={5}
          paddingAngle={0}
          outerRadius={80}
          fill='var(--bs-secondary)'
          label
        >
          {
            data.map((entry, index) => (
              <Cell key={`cell-${index}`} fill={getColor(index)} />
            ))
          }
        </Pie>
        <Tooltip />
      </PieChart>
    </ResponsiveContainer>
  )
}