import {
  Box,
  Button,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid2 as Grid,
  Switch,
  TextField,
  Typography
} from "@mui/material";
import ColourPicker from "common/ColourPicker";
import ResponsiveDialog from "common/ResponsiveDialog";
import React from "react";
import { useState } from "react";
import { useEffect } from "react";
import { useFieldAPI, useGlobalState } from "providers";
import { pond } from "protobuf-ts/pond";
import { useSnackbar } from "hooks";
import { Field } from "models";
import { GrainOptions, ToGrainOption } from "grain";
import SearchSelect from "common/SearchSelect";
import { clone } from "lodash";
import GrainDescriber from "grain/GrainDescriber";

interface Props {
  selectedField?: Field;
  borders?: pond.Shape[];
  //holes?: pond.Shape[];
  open: boolean;
  onClose: () => void;
  updateFields?: (key: string, settings: pond.FieldSettings) => void;
  removeField?: (field: Field) => void;
}

export default function FieldSettings(props: Props) {
  const { selectedField, onClose, removeField, updateFields, borders } = props;
  const [{as}] = useGlobalState();
  const [fieldName, setFieldName] = useState("");
  const [acres, setAcres] = useState<number>(0);
  const [cropType, setCropType] = useState<pond.Grain>(pond.Grain.GRAIN_INVALID);
  const [grainSubtype, setGrainSubtype] = useState("");
  const [landLocation, setLandLocation] = useState("");
  const fieldAPI = useFieldAPI();
  const [featColor, setFeatColor] = useState("green");
  const { openSnack } = useSnackbar();
  const [isCustom, setIsCustom] = useState(false);
  const [customType, setCustomType] = useState("");
  const [bushelsPerTonne, setBushelsPerTonne] = useState("1");

  useEffect(() => {
    if (selectedField) {
      setFieldName(selectedField.fieldName());
      setCropType(selectedField.crop());
      setAcres(selectedField.settings.acres);
      setLandLocation(selectedField.landLoc() ? selectedField.landLoc() : "");
      setGrainSubtype(selectedField.subtype());
      setFeatColor(selectedField.settings.fieldGeoData?.colour ?? "green");
      setBushelsPerTonne(selectedField.bushelsPerTonne().toString());
      if (selectedField.grain() === pond.Grain.GRAIN_CUSTOM) {
        setIsCustom(true);
        setCustomType(selectedField.customType());
      } else {
        setIsCustom(false);
      }
    } else {
      setFieldName("");
      setCropType(0);
      setLandLocation("");
      setFeatColor("");
    }
  }, [selectedField]);

  const checkValidation = () => {
    return fieldName.length > 0 && cropType !== 0 ? false : true;
  };

  const submit = () => {
    if (selectedField) {
      //update existing field
      let settings = selectedField.settings;
      settings.fieldName = fieldName;
      settings.crop = cropType;
      if (settings.fieldGeoData) {
        settings.fieldGeoData.colour = featColor;
      }
      settings.customGrain = customType;
      settings.grainSubtype = grainSubtype;
      settings.landLocation = landLocation;
      settings.acres = acres;

      fieldAPI
        .updateField(selectedField.key(), settings, undefined, as)
        .then(resp => {
          let newField = clone(selectedField);
          newField.settings = settings;
          openSnack("Updated Field Settings");
          updateFields && updateFields(selectedField.key(), selectedField.settings);
          onClose();
        })
        .catch(err => {
          openSnack("Failed to Update Field Settings");
        });
    } else {
      //create new field
      let geo = pond.GeoData.create();
      let settings: pond.FieldSettings = pond.FieldSettings.create();

      //set the basic settings
      settings.fieldName = fieldName;
      settings.crop = cropType;
      settings.customGrain = customType;
      settings.grainSubtype = grainSubtype;
      settings.landLocation = landLocation;
      settings.acres = acres;
      //set the geodata
      geo.colour = featColor;
      geo.title = fieldName;
      if (borders) {
        geo.geoShape = borders.length > 1 ? "MultiPolygon" : "Polygon";
        geo.shapes = borders;
      }
      settings.fieldGeoData = geo;
      fieldAPI
        .addField(settings, as)
        .then(resp => {
          updateFields && updateFields(resp.data.field, settings);
          openSnack("New Field Created");
        })
        .catch(err => {
          openSnack("failed to add field");
        });
      onClose();
    }
  };

  const deleteField = () => {
    if (selectedField) {
      fieldAPI
        .removeField(selectedField?.key(), as)
        .then(resp => {
          openSnack("Field Mapping Deleted");
          //setActiveStep(0);
          removeField && removeField(selectedField);
          onClose();
        })
        .catch(err => {
          openSnack("Failed to delete field mapping");
        });
    }
  };

  const fieldInformation = () => {
    return (
      <Box>
        <Box>
          <DialogTitle>Field Information</DialogTitle>
          <TextField
            value={fieldName}
            margin="normal"
            color="primary"
            label="Field Name"
            type="text"
            fullWidth
            autoFocus
            onChange={e => setFieldName(e.target.value)}
          />
          <TextField
            value={acres}
            margin="normal"
            color="primary"
            label="Acres"
            type="number"
            fullWidth
            autoFocus
            //helperText="If you are unsure of the acres they will be calculated automatically based on the drawn field boundaries"
            onChange={e => setAcres(+e.target.value)}
          />
          {/* Select box for grain type */}
          <Grid container alignItems="center">
            <Grid>Supported Grain</Grid>
            <Grid>
              <Switch
                color="default"
                value={isCustom}
                checked={isCustom}
                onChange={(_, checked) => {
                  setIsCustom(checked);
                  if (checked) {
                    setCropType(pond.Grain.GRAIN_CUSTOM);
                  } else {
                    setCustomType("");
                  }
                }}
                name="storage"
              />
            </Grid>
            <Grid>Custom Grain</Grid>
          </Grid>
          {isCustom ? (
            <React.Fragment>
              <TextField
                label="Grain Type"
                margin="normal"
                style={{ marginTop: 0 }}
                type="text"
                fullWidth
                value={customType}
                color="primary"
                onChange={e => setCustomType(e.target.value)}
              />
              <TextField
                label="Bushels Per Tonne"
                margin="normal"
                style={{ marginTop: 0 }}
                type="number"
                fullWidth
                value={bushelsPerTonne}
                color="primary"
                onChange={e => setBushelsPerTonne(e.target.value)}
              />
            </React.Fragment>
          ) : (
            <SearchSelect
              label="Type"
              selected={ToGrainOption(cropType)}
              changeSelection={option => {
                if (option) {
                  let grainType = pond.Grain[option.value as keyof typeof pond.Grain];
                  setCropType(grainType);
                  setBushelsPerTonne(GrainDescriber(grainType).bushelsPerTonne.toString());
                }
              }}
              group
              options={GrainOptions()}
            />
          )}

          <TextField
            label="Grain Variant"
            margin="normal"
            type="text"
            fullWidth
            value={grainSubtype}
            color="primary"
            onChange={e => setGrainSubtype(e.target.value)}
          />
          <TextField
            label="Land Location"
            margin="normal"
            type="text"
            fullWidth
            value={landLocation}
            color="primary"
            onChange={e => setLandLocation(e.target.value)}
          />
          <Box marginTop={3}>
            Field Colour
            <ColourPicker onChange={color => setFeatColor(color)} />
          </Box>
        </Box>
        <DialogActions>
          <Grid container direction="row">
            <Grid>
              {selectedField && (
                <Button onClick={deleteField} variant="contained" style={{ background: "red" }}>
                  <Typography>Delete Field</Typography>
                </Button>
              )}
            </Grid>
            <Grid>
              <Button onClick={onClose} color="primary">
                Cancel
              </Button>
              <Button
                variant="contained"
                onClick={submit}
                disabled={checkValidation()}
                color="primary">
                Submit
              </Button>
            </Grid>
          </Grid>
        </DialogActions>
      </Box>
    );
  };

  return (
    <ResponsiveDialog fullWidth fullScreen={false} open={props.open} onClose={onClose}>
      <DialogContent>{fieldInformation()}</DialogContent>
    </ResponsiveDialog>
  );
}
