import * as React from 'react';

export type HistogramBucket = {
   id: number;
   from: number;
   to: number;
   count: number;
};

/**
 * Create SVG path from histogram.
 */
function createPath(buckets: HistogramBucket[], scaleToX: number, scaleToY: number) {
   // Log10 vypadá líp. Je to pokus, kdyžtak odebrat. Když je pak v sekci
   // v jednom intervalu miliarda produktů a v ostatních intervalech pár,
   // tak bez log scale ty ostatní kopečky nejsou skoro vidět, jak jsou malý.
   buckets = buckets.map(bucket => {
      return {
         ...bucket,
         count: bucket.count > 0 ? Math.log10(bucket.count) : 0,
      };
   });

   // y = 0; v svg jsou souřadnice obráceně:
   //    y = 0 je úplně nahoře,
   //    y = max je úplně dole.
   const Y0 = scaleToY;

   const rangeMin = buckets[0].from;
   const rangeMax = buckets[buckets.length - 1].to;

   const rangeWidth = rangeMax - rangeMin;
   const scaleY = scaleToY / Math.max(...buckets.map(bucket => bucket.count));
   const scaleX = scaleToX / rangeWidth;

   const maxDistanceWithoutAnyPoints = rangeWidth * 0.1;

   const points: { x: number, y: number }[] = [];

   let lastBucketTo= -1;
   for (const bucket of buckets) {
      let key = bucket.id;

      if (bucket.id === buckets[0].id) {
         key = bucket.from;
      } else if (bucket.id === buckets[buckets.length - 1].id) {
         key = bucket.to;
      }

      // Přidej nulovej předchozí a aktuální interval,
      // pokud je vzdálenost mezi nimi větší než maxDistanceWithoutAnyPoints.
      if (lastBucketTo !== -1 && (lastBucketTo + maxDistanceWithoutAnyPoints) <= bucket.from) {
         points.push({
            x: (lastBucketTo + (bucket.from - lastBucketTo) / 2 - rangeMin) * scaleX,
            y: Y0,
         });
      }

      const y = Y0 - (bucket.count * scaleY);
      const x = (key - rangeMin) * scaleX;

      points.push({ x, y });
      lastBucketTo = bucket.to;
   }

   const firstPoint = points.shift();
   if (!firstPoint) {
      return '';
   }
   let dPath = `M ${firstPoint.x} ${firstPoint.y}`;

   for (const { x, y } of points) {
      dPath += ` L ${x} ${y}`;
   }

   return `${dPath} L ${scaleToX} ${scaleToY} L ${firstPoint.x} ${scaleToY} Z`;
}

export type HistogramProps = React.ComponentProps<'svg'> & {
   buckets: HistogramBucket[];
   width?: number;
   height?: number;

   pathProps?: Omit<React.ComponentProps<'path'>, 'd'>;
};

const aspectRatio = 6;

const scaleHeight = 200;
const scaleWidth = scaleHeight * aspectRatio;

export function Histogram(props: HistogramProps) {
   const {
      buckets,
      pathProps = { fill: 'currentColor' },
      ...restProps
   } = props;

   const d = React.useMemo(() => createPath(buckets, scaleWidth, scaleHeight), [buckets]);

   return (
      <svg xmlns="http://www.w3.org/2000/svg" viewBox={`0 0 ${scaleWidth} ${scaleHeight}`} {...restProps}>
         <path d={d} {...pathProps}></path>
      </svg>
   );
}
