import { Button, Grid2 as Grid, InputAdornment, TextField } from "@mui/material";
import SearchSelect, { Option } from "common/SearchSelect";
import { GrainOptions } from "grain";
import { pond } from "protobuf-ts/pond";
import { useBinAPI, useGlobalState, useSnackbar } from "providers";
import React, { useState } from "react";
import { fahrenheitToCelsius, getDistanceUnit, getTemperatureUnit } from "utils";

interface Props {
  selectedBins: pond.Bin[];
  refreshCallback: (reLoad: boolean) => void;
  extraButtons?: JSX.Element[]
}

export default function BulkBinSettings(props: Props) {
  const { selectedBins, refreshCallback, extraButtons } = props;
  const binAPI = useBinAPI();
  const { openSnack } = useSnackbar();
  const gridItemWidth = 3;
  // bin settings variables
  const [name, setName] = useState<string | undefined>();
  const [{as}] = useGlobalState();
  const [grainType, setGrainType] = useState<pond.Grain | undefined>();
  const [grainOption, setGrainOption] = useState<Option | null>();
  const [height, setHeight] = useState<number | undefined>();
  const [diameter, setDiameter] = useState<number | undefined>();
  const [customGrain, setCustomGrain] = useState<string | undefined>();
  const [variant, setVariant] = useState<string | undefined>();
  const [bushels, setBushels] = useState<number | undefined>();
  const [capacity, setCapacity] = useState<number | undefined>();
  const [highTemp, setHighTemp] = useState<number | undefined>();
  const [lowTemp, setLowTemp] = useState<number | undefined>();

  const convertedDistance = (enteredDistance: number) => {
    if (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_METERS) {
      return enteredDistance * 100;
    }
    if (getDistanceUnit() === pond.DistanceUnit.DISTANCE_UNIT_FEET) {
      return enteredDistance * 30.48;
    }
    return enteredDistance;
  };

  const convertedTemp = (enteredTemp: number) => {
    let t = enteredTemp;
    if (getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT) {
      t = fahrenheitToCelsius(enteredTemp);
    }
    return t;
  };

  const updateBins = () => {
    let binsToEdit: pond.BinSettings[] = [];
    selectedBins.forEach(bin => {
      if (bin.settings) {
        if (bin.settings.inventory) {
          if (grainType) bin.settings.inventory.grainType = grainType;
          if (bushels) bin.settings.inventory.grainBushels = bushels;
          if (customGrain) bin.settings.inventory.customTypeName = customGrain;
          if (variant) bin.settings.inventory.grainSubtype = variant;
        }
        if (bin.settings.specs) {
          if (height) bin.settings.specs.heightCm = convertedDistance(height);
          if (diameter) bin.settings.specs.diameterCm = convertedDistance(diameter);
          if (capacity) bin.settings.specs.bushelCapacity = capacity;
        }
        if (name) bin.settings.name = name;
        if (highTemp) bin.settings.highTemp = convertedTemp(highTemp);
        if (lowTemp) bin.settings.lowTemp = convertedTemp(lowTemp);
        binsToEdit.push(bin.settings);
      }
    });
    binAPI
      .bulkBinUpdate(binsToEdit, as)
      .then(resp => {
        if (resp.data.successfull > 0) {
          refreshCallback(true);
          openSnack("Successfully updated " + resp.data.successfull + " bins");
        }
      })
      .catch(_err => {
        openSnack("Failed to update bins");
      });
  };

  return (
    <React.Fragment>
      <Grid width={"100%"} container direction="row" spacing={2} alignContent="center" alignItems="center">
        {/* first row */}
        {/* <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Bin Name"
            value={name ?? ""}
            onChange={e => {
              setName(e.target.value);
            }}
          />
        </Grid> */}
        <Grid size={{ xs: gridItemWidth }}>
          <SearchSelect
            label="Grain Type"
            selected={grainOption}
            changeSelection={option => {
              let newGrainType = option
                ? pond.Grain[option.value as keyof typeof pond.Grain]
                : pond.Grain.GRAIN_INVALID;
              setGrainType(newGrainType);
              setGrainOption(option);
            }}
            group
            options={GrainOptions()}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Grain Variant"
            value={variant ?? ""}
            onChange={e => {
              setVariant(e.target.value);
            }}
          />
        </Grid>
        {/* second row */}
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Custom Grain"
            value={customGrain ?? ""}
            onChange={e => {
              setCustomGrain(e.target.value);
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Bushels"
            type="number"
            value={bushels ?? ""}
            onChange={e => {
              setBushels(parseFloat(e.target.value));
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Capacity"
            type="number"
            value={capacity ?? ""}
            onChange={e => {
              setCapacity(parseFloat(e.target.value));
            }}
          />
        </Grid>
        {/* last row */}
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Bin Height"
            type="number"
            value={height ?? ""}
            onChange={e => {
              setHeight(parseFloat(e.target.value));
            }}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  {getDistanceUnit() !== pond.DistanceUnit.DISTANCE_UNIT_FEET ? "m" : "ft"}
                </InputAdornment>
              )
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Bin Diameter"
            type="number"
            value={diameter ?? ""}
            onChange={e => {
              setDiameter(parseFloat(e.target.value));
            }}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  {getDistanceUnit() !== pond.DistanceUnit.DISTANCE_UNIT_FEET ? "m" : "ft"}
                </InputAdornment>
              )
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="High Temp Warning"
            type="number"
            value={highTemp ?? ""}
            onChange={e => {
              setHighTemp(parseFloat(e.target.value));
            }}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  {getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT
                    ? "°F"
                    : "°C"}
                </InputAdornment>
              )
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <TextField
            fullWidth
            label="Low Temp Warning"
            type="number"
            value={lowTemp ?? ""}
            onChange={e => {
              setLowTemp(parseFloat(e.target.value));
            }}
            InputProps={{
              endAdornment: (
                <InputAdornment position="end">
                  {getTemperatureUnit() === pond.TemperatureUnit.TEMPERATURE_UNIT_FAHRENHEIT
                    ? "°F"
                    : "°C"}
                </InputAdornment>
              )
            }}
          />
        </Grid>
        <Grid size={{ xs: gridItemWidth }}>
          <Button
            variant="contained"
            color="primary"
            onClick={() => {
              updateBins();
            }}>
            Update selected Bins
          </Button>
        </Grid>
        {extraButtons?.map((button, index) => (
          <Grid key={"exButton" + index} size={{ xs: gridItemWidth }}>
            {button}
          </Grid>
        ))}
      </Grid>
    </React.Fragment>
  );
}
