import { useTheme } from "@mui/material";
import { teal, orange } from "@mui/material/colors";
import moment from "moment";
import { useEffect, useState } from "react";
import {
  Area,
  ComposedChart,
  Legend,
  Line,
  ReferenceArea,
  ResponsiveContainer,
  Tooltip,
  TooltipProps,
  XAxis,
  YAxis
} from "recharts";
import MaterialChartTooltip from "./MaterialChartTooltip";

export interface DataPoint {
  timestamp: number;
  moisture: [number, number];
}

export interface TrendPoint {
  timestamp: number;
  trend: number;
}

interface Props {
  data: DataPoint[];
  trend: TrendPoint[];
  newXDomain?: number[] | string[];
  multiGraphZoom?: (domain: number[] | string[]) => void;
  multiGraphZoomOut?: boolean;
}

interface ComposedData {
  timestamp: number;
  trend?: number;
  moisture?: [number, number];
}

export default function TrendingChart(props: Props) {
  const { data, trend, newXDomain, multiGraphZoom } = props;
  const theme = useTheme();
  const now = moment();
  const [composedData, setComposedData] = useState<ComposedData[]>([]);
  const [xDomain, setXDomain] = useState<string[] | number[]>(["dataMin", "dataMax"]);
  const [refLeft, setRefLeft] = useState<number | undefined>();
  const [refRight, setRefRight] = useState<number | undefined>();

  useEffect(() => {
    if (newXDomain) {
      setXDomain(newXDomain);
    }
  }, [newXDomain]);

  useEffect(() => {
    let newData: ComposedData[] = [];
    data.forEach(d => {
      newData.push({
        timestamp: d.timestamp,
        moisture: d.moisture
      });
    });
    trend.forEach(t => {
      newData.push({
        timestamp: t.timestamp,
        trend: Math.round(t.trend * 100) / 100
      });
    });

    setComposedData([...newData]);
  }, [data, trend]);

  const zoom = () => {
    let newDomain: number[] | string[] = ["dataMin", "dataMax"];
    if (refLeft && refRight && refLeft !== refRight) {
      refLeft < refRight ? (newDomain = [refLeft, refRight]) : (newDomain = [refRight, refLeft]);
      setRefLeft(undefined);
      setRefRight(undefined);
      if (multiGraphZoom) {
        multiGraphZoom(newDomain);
      } else {
        setXDomain(newDomain);
      }
    }
  };

  //just commenting this out as this charts zoom will likely never be controlled from inside
  // const zoomOut = () => {
  //   setXDomain(["dataMin", "dataMax"]);
  // };

  if (composedData.length <= 1) {
    return null;
  }
  return (
    <ResponsiveContainer width={"100%"} height={270}>
      <ComposedChart
        data={composedData}
        onMouseDown={(e: any) => {
          if (e) {
            setRefLeft(e.activeLabel);
          }
        }}
        onMouseMove={(e: any) => {
          if (e) {
            setRefRight(e.activeLabel);
          }
        }}
        onMouseUp={() => {
          setRefLeft(undefined);
          setRefRight(undefined);
          zoom();
        }}>
        <Legend
          verticalAlign="top"
          payload={[
            { value: "Grain Moisture", type: "square", id: "gMoist", color: teal[500] },
            { value: "Plenum Moisture", type: "square", id: "pMoist", color: orange[500] }
          ]}
        />
        <Tooltip
          animationEasing="ease-out"
          cursor={{ fill: theme.palette.text.primary, opacity: "0.15" }}
          labelFormatter={timestamp => moment(timestamp).format("lll")}
          content={(props: TooltipProps<any, any>) => (
            <MaterialChartTooltip {...props} valueFormatter={val => `${val}`} />
          )}
        />
        <XAxis
          allowDataOverflow
          dataKey="timestamp"
          domain={xDomain}
          name="Time"
          tickFormatter={timestamp => {
            let t = moment(timestamp);
            return now.isSame(t, "day") ? t.format("LT") : t.format("MMM DD");
          }}
          scale="time"
          type="number"
          tick={{ fill: theme.palette.text.primary }}
          stroke={theme.palette.divider}
          interval="preserveStartEnd"
        />
        <YAxis
          domain={["auto", "auto"]}
          tickFormatter={moisture => {
            let val = moisture + "%";
            return val;
          }}
          // label={{
          //   value: "Moisture (%)",
          //   angle: -90,
          //   position: "insideLeft",
          //   fill: theme.palette.text.primary
          // }}
          tick={{ fill: theme.palette.text.primary }}
          interval="preserveStartEnd"
        />
        <Area
          type="monotone"
          dataKey={"moisture"}
          name="Moisture"
          stroke={"transparent"}
          fill={teal[500]}
        />
        {refLeft && refRight ? (
          <ReferenceArea x1={refLeft} x2={refRight} strokeOpacity={0.3} />
        ) : null}
        <Line dataKey="trend" stroke={orange[500]} strokeWidth={2} dot={false} />
      </ComposedChart>
    </ResponsiveContainer>
  );
}
