import { 
  Card, 
  FormControlLabel, 
  Grid, 
  Switch, 
  Typography, 
  useTheme 
} from "@mui/material";
import GrainDescriber from "grain/GrainDescriber";
import { Bin } from "models";
import { useEffect, useState } from "react";
import { Bar, BarChart, LabelList, ResponsiveContainer, XAxis, YAxis } from "recharts";
import { Props as LabelProps } from "recharts/types/component/Label";

interface GraphProps {
  bin: Bin;
  nameMap: Map<string, string>;
}

interface CompositionData {
  sourceName: string;
  value: number;
}

export default function BinCompositionGraph(props: GraphProps) {
  const { bin, nameMap } = props;
  const [originalSourceData, setOriginalSourceData] = useState<CompositionData[]>([]);
  const [objectSourceData, setObjectSourceData] = useState<CompositionData[]>([]);
  const [colour, setColour] = useState("");
  const [originalSource, setOriginalSource] = useState(true);
  const theme = useTheme();

  useEffect(() => {
    let originalSourceBarData: CompositionData[] = [];
    let objectSourceBarData: CompositionData[] = [];
    Object.keys(bin.status.grainComposition).forEach(key => {
      let roundedVal = Math.round(bin.status.grainComposition[key] * 100) / 100;
      if (roundedVal !== 0) {
        originalSourceBarData.push({
          sourceName: nameMap.get(key) ?? "Unknown",
          value: roundedVal
        });
      }
    });
    Object.keys(bin.status.objectSourceMap).forEach(key => {
      let roundedVal = Math.round(bin.status.objectSourceMap[key] * 100) / 100;
      if (roundedVal !== 0) {
        objectSourceBarData.push({
          sourceName: nameMap.get(key) ?? "Unknown",
          value: roundedVal
        });
      }
    });
    setOriginalSourceData(originalSourceBarData);
    setObjectSourceData(objectSourceBarData);
    setColour(GrainDescriber(bin.grain()).colour);
  }, [bin, nameMap]);

  const customizedLabel = (props: LabelProps) => {
    const { x, y, width, height, value } = props;
    let centerX = 0;
    let centerY = 0;

    let percent = "0%";
    if (bin.settings.inventory && value) {
      percent = "(" + ((+value / bin.settings.inventory.grainBushels) * 100).toFixed(2) + ")%";
    }

    if (x && width && y && height) {
      centerX = +x + +width / 2;
      centerY = +y + +height / 2;
    }
    return (
      <g>
        <text
          x={centerX}
          y={centerY}
          fill="white"
          stroke="white"
          strokeWidth={1.5}
          fontSize={20}
          textAnchor="middle">
          {value}
        </text>
        <text
          x={centerX}
          y={centerY + 20}
          fill="white"
          stroke="white"
          strokeWidth={1}
          fontSize={15}
          textAnchor="middle">
          {percent}
        </text>
      </g>
    );
  };

  const graphComponent = () => {
    return (
      <ResponsiveContainer width={"100%"} height={350}>
        <BarChart data={originalSource ? originalSourceData : objectSourceData}>
          <YAxis />
          <XAxis dataKey={"sourceName"} tick={{ fill: theme.palette.text.primary }} />
          <defs>
            <linearGradient id="gradientColour" x1="0" y1="1" x2="0" y2="0">
              <stop offset="0%" stopColor={colour} stopOpacity="0%" />
              <stop offset="100%" stopColor={colour} stopOpacity="90%" />
            </linearGradient>
          </defs>
          <Bar
            dataKey={"value"}
            fill={"url(#gradientColour)"}
            //barSize={barSize}
          >
            <LabelList
              fill={"white"}
              //dataKey="value"
              position="center"
              content={e => {
                return customizedLabel(e);
              }}
              style={{ fontWeight: 750, fontSize: 20 }}
            />
          </Bar>
        </BarChart>
      </ResponsiveContainer>
    );
  };

  return (
    <Card raised style={{ padding: 5 }}>
      <Grid container direction="row" justifyContent="space-between">
        <Grid item>
          <Typography style={{ fontSize: 25, fontWeight: 650, marginLeft: 20 }}>
            Grain Composition
          </Typography>
        </Grid>
        <Grid item>
          <FormControlLabel
            control={
              <Switch
                checked={originalSource}
                onChange={(_, checked) => {
                  setOriginalSource(checked);
                }}
                color="primary"
              />
            }
            label="Original Source"
          />
        </Grid>
      </Grid>
      {graphComponent()}
    </Card>
  );
}
