import { Tooltip, TooltipData } from '../../common/Tooltip';
import { LegendGradient } from '../../common/LegendComponent';
import {
  ChartContainer,
  WithLegendContainerProps,
} from '../../common/ChartContainer';
import { yearsRange } from './calendar';
import { call } from '../../utils';
import { ChartData, labelSelector, valueSelector } from '../../utils/data';
import { useTooltip } from '../../hooks/useTooltip';

import CalendarChartSVG, { CalendarChartSVGProps } from './CalendarChartSVG';

type CalendarChartWithTooltipProps = CalendarChartSVGProps & {
  showTooltip?: boolean;
  tooltipComponent?: (data: TooltipData) => JSX.Element;
};

export const CalendarChartWithTooltip = (
  props: CalendarChartWithTooltipProps
) => {
  const { showTooltip, tooltipComponent, ...chartProps } = props;
  const { bindTooltip, renderTooltip } = useTooltip<ChartData>(
    Boolean(showTooltip)
  );

  return (
    <>
      <CalendarChartSVG bindTooltip={bindTooltip} {...chartProps} />
      {renderTooltip(tooltipComponent)}
    </>
  );
};

CalendarChartWithTooltip.defaultProps = {
  showTooltip: true,
  tooltipComponent: (data) => <Tooltip data={data} />,
} as CalendarChartWithTooltipProps;

type CalendarChartProps = WithLegendContainerProps<CalendarChartWithTooltipProps>;

export const CalendarChart = (props: CalendarChartProps) => {
  const { legendPlacement, legendComponent, ...chartProps } = props;

  return (
    <ChartContainer
      chart={({ width, height }) => {
        if (width === 0) return null;
        if (props.data.length) {
          const years = yearsRange(props.data, labelSelector);
          const otherProps = Object.assign({}, { width }, chartProps);
          return years.map((year) => (
            <CalendarChartWithTooltip year={year} {...otherProps} key={year} />
          ));
        } else {
          return null;
        }
      }}
      legendComponent={call(legendComponent, chartProps)}
      legendPlacement={legendPlacement}
    />
  );
};

CalendarChart.defaultProps = {
  legendPlacement: 'bottom',
  legendComponent: (props) => {
    const min = Math.min(0, ...props.data.map(valueSelector));
    const max = Math.max(0, ...props.data.map(valueSelector));
    return (
      <div
        style={{
          display: 'flex',
          justifyContent: 'center',
        }}
      >
        <LegendGradient
          min={min}
          max={max}
          style={{
            width: '50%',
            minWidth: 200,
          }}
        />
      </div>
    );
  },
} as Partial<CalendarChartProps>;
