import {
  Grid2 as Grid,
  Button,
  Typography,
  DialogTitle,
  DialogContent,
  DialogActions,
  Select,
  MenuItem,
  Switch,
  FormControlLabel,
  RadioGroup,
  Radio,
  Box
} from "@mui/material";
import { blue } from "@mui/material/colors";
import ResponsiveDialog from "common/ResponsiveDialog";
import React, { useState, useEffect } from "react";
import fans from "fans/fans_client.json";
import SearchSelect, { Option } from "common/SearchSelect";
import { pond } from "protobuf-ts/pond";
import { getFanIcon } from "pbHelpers/Fan";

interface Props {
  fanID?: number;
  useCardView?: boolean;
  updateFan: (fanID: number) => void;
}

interface Fan {
  id: number;
  name: string;
  kind: string;
  horsepower: number;
}

export default function FanPicker(props: Props) {
  const { fanID, useCardView, updateFan } = props;
  const [openSelector, setOpenSelector] = useState(false);
  const [fanMap, setFanMap] = useState<Map<number, Fan>>(new Map<number, Fan>());
  const [genericFans, setGenericFans] = useState<Fan[]>([]);
  const [hpOptions, setHPOptions] = useState<number[]>([]);
  const [currentHP, setCurrentHP] = useState<number>(0);
  const [fanTypes, setFanTypes] = useState<string[]>([]);
  const [genericTypes, setGenericTypes] = useState<string[]>([]);
  const [currentType, setCurrentType] = useState<string>("");
  const [useAdvanced, setUseAdvanced] = useState(false);
  const [fanOptions, setFanOptions] = useState<Option[]>([]);
  const [selectedFan, setSelectedFan] = useState<Option | null>();
  const [displayFan, setDisplayFan] = useState<string>("");

  useEffect(() => {
    let newMap: Map<number, Fan> = new Map<number, Fan>();
    let initialTypes: string[] = [];
    let initialHP: number[] = [];
    let initialFanOptions: Option[] = [];
    fans["bulk"].forEach(fan => {
      newMap.set(fan.id, fan);
      initialFanOptions.push({
        value: fan.id,
        label:
          fan.name +
          (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") +
          " " +
          fan.horsepower +
          "Hp " +
          fan.kind
      });
      if (!initialTypes.includes(fan.kind) && fan.kind !== "axial" && fan.kind !== "centrifugal") {
        initialTypes.push(fan.kind);
      }
      if (!initialHP.includes(fan.horsepower)) {
        initialHP.push(fan.horsepower);
      }
    });
    //set the options for the advanced selector
    setFanMap(newMap);
    initialHP.sort((a, b) => a - b);
    setHPOptions(initialHP);
    setFanOptions(initialFanOptions);
    setFanTypes(initialTypes);

    setGenericFans(fans["generic"]);
    let gTypes: string[] = [];
    fans["generic"].forEach(fan => {
      if (!gTypes.includes(fan.kind)) {
        gTypes.push(fan.kind);
      }
    });
    //set the options for the simple picker NOTE: horsepower options are determined when a fan option is selected
    setGenericTypes(gTypes);

    if (fanID) {
      let fanName = newMap.get(fanID)?.name;
      setDisplayFan(fanName ? fanName : "No Fan Selected");
    }
  }, [fanID]);

  //if we are using card view there will be no confirm button so when the selected fan changes call the update fan function
  useEffect(() => {
    if (useCardView) {
      updateFan(selectedFan?.value);
      //setDisplayFan(selectedFan?.label ?? "No Fan Selected");
    }
  }, [selectedFan, useCardView, updateFan]);

  const closeSelector = () => {
    setUseAdvanced(false);
    setOpenSelector(false);
  };

  const determineBaseType = (type: string) => {
    if (type === "axial(high speed)" || type === "axial(low speed)") {
      return "axial";
    } else {
      return "centrifugal";
    }
  };

  const findHPOptions = (type: string, generic?: boolean) => {
    let ops: number[] = [];
    let baseType = determineBaseType(type);
    let list = Array.from(fanMap.values());
    if (generic) {
      list = genericFans;
    }
    list.forEach(fan => {
      if ((fan.kind === type || fan.kind === baseType) && !ops.includes(fan.horsepower)) {
        ops.push(fan.horsepower);
      }
    });
    setHPOptions(ops);
  };

  //feel like there is a better way to do this but cant think of it at the moment
  const filterOptions = (type: string, hp: number) => {
    let filteredOps: Option[] = [];
    let baseType = determineBaseType(type);
    if (hp > 0 && type === "") {
      fans["bulk"].forEach(fan => {
        if (fan.horsepower === hp) {
          filteredOps.push({
            value: fan.id,
            label: fan.name + (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") + " " + fan.kind
          });
        }
      });
    } else if (hp === 0 && type !== "") {
      fans["bulk"].forEach(fan => {
        if (fan.kind === type || fan.kind === baseType) {
          filteredOps.push({
            value: fan.id,
            label:
              fan.name +
              (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "") +
              " " +
              fan.horsepower +
              "Hp"
          });
        }
      });
    } else {
      fans["bulk"].forEach(fan => {
        if ((fan.kind === type || fan.kind === baseType) && fan.horsepower === hp) {
          filteredOps.push({
            value: fan.id,
            label: fan.name + (fan.rpm !== 0 ? " " + fan.rpm + " rpm " : "")
          });
        }
      });
    }

    setFanOptions(filteredOps);
  };

  const findGenericFan = (hp: number) => {
    genericFans.forEach(fan => {
      if (fan.horsepower === hp && fan.kind === currentType) {
        setSelectedFan({ label: fan.name, value: fan.id });
      }
    });
  };

  const determineFanIcon = (type: string) => {
    if (type === "axial(high speed)" || type === "axial(low speed)") {
      return getFanIcon(pond.FanType.FAN_TYPE_CENTRIFUGAL_INLINE);
    } else {
      return getFanIcon(pond.FanType.FAN_TYPE_CENTRIFUGAL_HIGH_SPEED);
    }
  };

  const simpleSelector = () => {
    return (
      <React.Fragment>
        <RadioGroup
          value={currentType}
          onChange={(_, value) => {
            setCurrentType(value);
            findHPOptions(value, true);
          }}>
          {genericTypes.map(type => (
            <Grid
              alignItems="center"
              container
              direction="row"
              key={type}
              style={{ marginTop: 20 }}>
              <Grid>
                <FormControlLabel value={type} control={<Radio />} label={type} />
              </Grid>
              <Grid>
                <img width={100} height={100} src={determineFanIcon(type)} alt="fanimg" />
              </Grid>
            </Grid>
          ))}
        </RadioGroup>
        <Select
          id="horsepower"
          fullWidth
          label="Horsepower"
          displayEmpty
          value={currentHP}
          onChange={e => {
            let value = e.target.value as number;
            setCurrentHP(value);
            findGenericFan(value);
          }}>
          <MenuItem key={0} value={0}>
            Select Horsepower
          </MenuItem>
          {hpOptions.map(op => (
            <MenuItem key={op} value={op}>
              {op} Hp
            </MenuItem>
          ))}
        </Select>
      </React.Fragment>
    );
  };

  const advancedSelector = () => {
    return (
      <React.Fragment>
        <Grid
          container
          direction="row"
          style={{ marginBottom: 10, marginTop: 10 }}>
          <Grid size={{xs:5}}>
            <Select
              id="fantype"
              fullWidth
              label="Fan Type"
              displayEmpty
              value={currentType}
              onChange={e => {
                let value = e.target.value as string;
                setCurrentType(value);
                filterOptions(value, currentHP);
                findHPOptions(value);
              }}>
              <MenuItem key={""} value={""}>
                Select Fan Type
              </MenuItem>
              {fanTypes.map(op => (
                <MenuItem key={op} value={op}>
                  {op}
                </MenuItem>
              ))}
            </Select>
          </Grid>
          <Grid size={{xs:5}}>
            <Select
              id="horsepower"
              fullWidth
              label="Horsepower"
              displayEmpty
              value={currentHP}
              onChange={e => {
                let value = e.target.value as number;
                setCurrentHP(value);
                filterOptions(currentType, value);
              }}>
              <MenuItem key={0} value={0}>
                Select Horsepower
              </MenuItem>
              {hpOptions.map(op => (
                <MenuItem key={op} value={op}>
                  {op} Hp
                </MenuItem>
              ))}
            </Select>
          </Grid>
        </Grid>
        <SearchSelect
          selected={selectedFan}
          changeSelection={(option: Option | null) => {
            setSelectedFan(option);
          }}
          options={fanOptions}
          label="Fan"
          loading={false}
        />
      </React.Fragment>
    );
  };

  const selector = () => {
    return (
      <ResponsiveDialog
        open={openSelector}
        onClose={() => {
          closeSelector();
        }}
        fullWidth>
        <DialogTitle>
          <Grid container direction="row">
            <Grid>Select Fan</Grid>
            <Grid>
              <FormControlLabel
                control={
                  <Switch
                    value={useAdvanced}
                    title="Use Advance Selector"
                    onClick={() => {
                      setUseAdvanced(!useAdvanced);
                      setCurrentType("");
                      setCurrentHP(0);
                      setSelectedFan(null);
                    }}
                  />
                }
                label="Use Advanced Selector"
                labelPlacement="start"
              />
            </Grid>
          </Grid>
        </DialogTitle>
        <DialogContent>{useAdvanced ? advancedSelector() : simpleSelector()}</DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              closeSelector();
            }}>
            Cancel
          </Button>
          <Button
            onClick={() => {
              updateFan(selectedFan?.value);
              setDisplayFan(selectedFan?.label ?? "No Fan Selected");
              closeSelector();
            }}>
            Confirm
          </Button>
        </DialogActions>
      </ResponsiveDialog>
    );
  };

  const dialogView = () => {
    return (
      <React.Fragment>
        {selector()}
        <Grid container direction="row" alignItems="center">
          <Grid size={{xs:3}}>
            <Button
              onClick={() => {
                setOpenSelector(true);
              }}
              style={{ background: blue["500"] }}
              variant="contained">
              FanPicker
            </Button>
          </Grid>
          <Grid size={{xs:9}}>
            <Typography>{displayFan}</Typography>
          </Grid>
        </Grid>
      </React.Fragment>
    );
  };

  const cardView = () => {
    return (
      <React.Fragment>
        <Box padding={2}>
          <Typography style={{ fontSize: 15 }}>Current Fan</Typography>
          <Typography style={{ fontWeight: 650, fontSize: 20 }}>{displayFan}</Typography>
          <Grid container direction="row-reverse">
            <Grid>
              <FormControlLabel
                control={
                  <Switch
                    value={useAdvanced}
                    title="Use Advance Selector"
                    onClick={() => {
                      setUseAdvanced(!useAdvanced);
                      setCurrentType("");
                      setCurrentHP(0);
                      setSelectedFan(null);
                    }}
                  />
                }
                label="Use Advanced Selector"
                labelPlacement="start"
              />
            </Grid>
          </Grid>
          {useAdvanced ? advancedSelector() : simpleSelector()}
        </Box>
      </React.Fragment>
    );
  };

  return useCardView ? cardView() : dialogView();
}
