import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'clsx';
import {
  Area,
  Bar,
  CartesianGrid,
  ComposedChart,
  Legend,
  Line,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from 'recharts';

import { PRIMARY_LEFT_Y_AXIS_ID } from '@/modules/marketplace/common/constants';

import CustomLogBar from './CustomLogBar';
import CustomTick from './CustomTick';
import CustomTooltip from './CustomTooltip';

import innerStyles from './CustomTooltip.module.scss';

const prepareParams = (params) => params.map((item) => ({ ...item, active: true }));

const renderLegendText = (value, entry) => {
  const { payload } = entry;

  return (
    <span
      className={classNames(innerStyles.Legend, {
        [innerStyles.Legend___active]: payload?.active,
      })}
    >
      {payload?.label ?? value}
    </span>
  );
};

function Chart({
  params = [],
  logParams = [],
  isNeedToResetParams = false,
  height = null,
  tooltipValueFormatter = null,
  ...props
}) {
  const allParams = [...params, ...(logParams ?? [])];

  const [params$, setParams$] = useState(prepareParams(allParams));
  const [showTooltip, setShowTooltip] = useState(true);

  useEffect(() => {
    setParams$(prepareParams(allParams));
  }, [isNeedToResetParams]);

  const handleLegendClick = (legend) => {
    const newParams = params$.map((item) => {
      if (item.value === legend.dataKey) {
        return {
          ...item,
          active: !item.active,
        };
      }

      return item;
    });

    setParams$(newParams);
  };

  const tooltipFormatter = (name, value) => [
    params$.find((param) => param.value === name)?.label ?? name,
    tooltipValueFormatter ? tooltipValueFormatter(name, value) : value,
  ];

  return (
    <ResponsiveContainer height={height || '100%'}>
      <ComposedChart data={props.chartData}>
        <XAxis dataKey="name" tick={<CustomTick />} tickFormatter={(tick) => tick.split('|')[1]} />

        {props.yAxis.map((axis) => (
          <YAxis
            key={axis.key}
            yAxisId={axis.id}
            orientation={axis.orientation}
            stroke={axis.stroke}
            tickFormatter={axis.tickFormatter}
            tick={{ fontSize: '14px' }}
            domain={axis.domain}
            hide={axis.hide ?? false}
          />
        ))}

        <CartesianGrid strokeDasharray="3 3" fill="var(--theme-palette-shades-100)" yAxisId={PRIMARY_LEFT_Y_AXIS_ID} />
        <Tooltip content={<CustomTooltip showTooltip={showTooltip} formatter={tooltipFormatter} />} />
        <Legend
          formatter={renderLegendText}
          onClick={handleLegendClick}
          wrapperStyle={{ bottom: -10 }}
          itemSorter="sortIndex"
        />

        {params$.map((item, index) => {
          if (item.type === 'bar') {
            return (
              <Bar
                key={`${index + 1}-${item.value}`}
                sortIndex={index + 1} // need for sorting in legend
                yAxisId={item.yAxisId}
                dataKey={item.value}
                fill={item.active ? item.color : 'transparent'}
                label={item.label}
                active={item.active}
              />
            );
          }

          if (item.type === 'line') {
            return (
              <Line
                key={`${index + 1}-${item.value}`}
                sortIndex={index + 1} // need for sorting in legend
                type="monotone"
                yAxisId={item.yAxisId}
                dataKey={item.value}
                stroke={item.active ? item.color : 'transparent'}
                dot={false}
                label={item.label}
                active={item.active}
              />
            );
          }

          if (item.type === 'area') {
            return (
              <Area
                key={`${index + 1}-${item.value}`}
                sortIndex={index + 1} // need for sorting in legend
                type="monotone"
                dataKey={item.value}
                fill={item.active ? item.color : 'transparent'}
                stroke={item.active ? item.color : 'transparent'}
                yAxisId={item.yAxisId}
                label={item.label}
                active={item.active}
              />
            );
          }

          if (item.type === 'log') {
            return (
              <Bar
                key={`${index + 1}-${item.value}`}
                sortIndex={index + 1} // need for sorting in legend
                yAxisId={item.yAxisId}
                dataKey={item.value}
                fill={item.active ? item.color : 'transparent'}
                label={item.label}
                active={item.active}
                shape={<CustomLogBar setShowTooltip={setShowTooltip} />}
              />
            );
          }

          return null;
        })}
      </ComposedChart>
    </ResponsiveContainer>
  );
}

Chart.propTypes = {
  yAxis: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  params: PropTypes.arrayOf(PropTypes.shape({})),
  logParams: PropTypes.arrayOf(PropTypes.shape({})),
  isNeedToResetParams: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  chartData: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  height: PropTypes.number,
  tooltipValueFormatter: PropTypes.func,
};

export default Chart;
