import {
  Box,
  Button,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid2 as Grid,
  InputAdornment,
  MenuItem,
  Tab,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Tabs,
  TextField,
  Theme,
  Tooltip,
  Typography
} from "@mui/material";
import { makeStyles } from "@mui/styles";
import ResponsiveDialog from "common/ResponsiveDialog";
import { useMobile, useSnackbar } from "hooks";
import { Field, HarvestPlan, Task } from "models";
import moment from "moment";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useHarvestPlanAPI, useTaskAPI } from "providers";
import React, { useCallback, useEffect, useState } from "react";
import TaskSettings from "tasks/TaskSettings";

interface Props {
  open: boolean;
  close: (reload?: boolean, updatedPlan?: HarvestPlan) => void;
  field: Field;
  update?: boolean;
  plan?: HarvestPlan;
}

const cropOptions = [
  {
    value: 2,
    label: "Barley"
  },
  {
    value: 4,
    label: "Canola"
  },
  {
    value: 5,
    label: "Corn"
  },
  {
    value: 6,
    label: "Oats"
  },
  {
    value: 7,
    label: "Peanuts"
  },
  {
    value: 8,
    label: "Rapeseed"
  },
  {
    value: 9,
    label: "Long Grain Rice"
  },
  {
    value: 10,
    label: "Medium Grain Rice"
  },
  {
    value: 11,
    label: "Short Grain Rice"
  },
  {
    value: 12,
    label: "Sorghum"
  },
  {
    value: 13,
    label: "Soybeans"
  },
  {
    value: 14,
    label: "Sunflower"
  },
  {
    value: 3,
    label: "Buckwheat"
  },
  {
    value: 15,
    label: "Durum Wheat"
  },
  {
    value: 16,
    label: "Hard Red Wheat"
  },
  {
    value: 17,
    label: "Unretted Flax"
  },
  {
    value: 18,
    label: "Dew Retted Flax"
  },
  {
    value: 19,
    label: "Yellow Peas"
  },
  {
    value: 20,
    label: "Robin Lentils"
  },
  {
    value: 21,
    label: "Redberry Lentils"
  },
  {
    value: 22,
    label: "Blaze Lentils"
  }
];

const useStyles = makeStyles((theme: Theme) => ({
    stepper: {
      padding: theme.spacing(0.5)
    },
    secondaryColor: {
      color: theme.palette.secondary.main
    },
    textSecondaryColor: {
      color: theme.palette.text.secondary
    },
    bottomSpacing: {
      marginBottom: theme.spacing(1)
    },
    tabs: {
      width: "100%",
      boxSizing: "border-box",
      flexShrink: 1
    },
    tabSmall: {
      width: "100%",
      boxSizing: "border-box",
      flexShrink: 1,
      minWidth: "48px"
    },
    tab: {
      width: "16%",
      minWidth: "16%"
    },
    buttonSpacing: {
      margin: 5
    }
  }));

const steps = ["Pre-Seeding", "Seeding", "Post-Seeding", "Harvest", "Fall"];

export default function HarvestSettings(props: Props) {
  const { open, plan, close, field, update } = props;
  const [{as}] = useGlobalState()
  const [planKey, setPlanKey] = useState<string>();
  const [newPlan, setNewPlan] = useState(HarvestPlan.create());
  const [activeStep, setActiveStep] = useState(0);
  const isMobile = useMobile();
  const classes = useStyles();
  const [planTasks, setPlanTasks] = useState<Task[]>([]);
  const taskAPI = useTaskAPI();
  const harvestPlanAPI = useHarvestPlanAPI();
  const [title, setTitle] = useState("");
  const [cropType, setCropType] = useState(0);
  const [customCropType, setCustomCropType] = useState("");
  const [useCustom, setUseCustom] = useState(false);
  const [variety, setVariety] = useState("");
  const [harvestYear, setHarvestYear] = useState(new Date().getFullYear());
  const [targetYield, setTargetYield] = useState(0);
  const [price, setPrice] = useState("");
  const [newTaskDialog, setNewTaskDialog] = useState(false);
  const [type, setType] = useState("");
  const [taskToEdit, setTaskToEdit] = useState<Task>();
  const { openSnack } = useSnackbar();
  const [deleteOpen, setDeleteOpen] = useState(false);

  const loadTasks = useCallback(() => {
    if (planKey) {
      taskAPI.getMultiTasks([planKey], as).then(resp => {
        setPlanTasks(resp.data.tasks.map(t => Task.any(t)));
      });
    }
  }, [taskAPI, planKey, as]);

  useEffect(() => {
    loadTasks();
  }, [loadTasks]);

  useEffect(() => {
    if (!plan || (plan && plan.permissions.includes(pond.Permission.PERMISSION_WRITE))) {
      setActiveStep(0);
    } else {
      setActiveStep(1);
    }
    setPlanKey(undefined);
    setTitle("");
    setVariety("");
    setHarvestYear(new Date().getFullYear());
    setTargetYield(0);
    setPrice("");
    if (update && plan) {
      setPlanKey(plan.key());
      setTitle(plan.settings.title);
      setCropType(plan.cropType());
      setCustomCropType(plan.customCropType());
      setVariety(plan.grainType());
      setHarvestYear(plan.harvestYear());
      setTargetYield(plan.yieldTarget());
      setPrice(plan.settings.bushelPrice.toFixed(2).toString());
    } else {
      setCropType(field.crop());
      setCustomCropType(field.customType());
      setUseCustom(field.crop() === pond.Grain.GRAIN_CUSTOM);
    }
  }, [plan, field, update]);

  const closeDialog = (reload?: boolean, updatedPlan?: HarvestPlan) => {
    close(reload, updatedPlan);
  };

  const showTasks = (type: string) => {
    let tasks: Task[] = [];
    let costTotal = 0;
    let secondaryCostTotal = 0;
    planTasks.forEach(task => {
      if (task.settings.type === type) {
        tasks.push(task);
        costTotal += task.cost();
        secondaryCostTotal += task.secondaryCost();
      }
    });

    let frag = (
      <React.Fragment>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>Title</TableCell>
              <TableCell>Description</TableCell>
              {!isMobile && <TableCell>Material Cost(acre)</TableCell>}
              {!isMobile && <TableCell>Equipment Cost(acre)</TableCell>}
              <TableCell>Total(acre)</TableCell>
              {!isMobile && <TableCell>Start -End</TableCell>}
              <TableCell>Edit</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {tasks.map((task, i) => (
              <TableRow key={i}>
                <TableCell>{task.title()}</TableCell>
                <TableCell>{task.description()}</TableCell>
                {!isMobile && <TableCell>${task.cost().toFixed(2)}</TableCell>}
                {!isMobile && <TableCell>${task.secondaryCost().toFixed(2)}</TableCell>}
                <TableCell>
                  ${(Math.round((task.cost() + task.secondaryCost()) * 100) / 100).toFixed(2)}
                </TableCell>
                {!isMobile && (
                  <TableCell>
                    {task.start()} {task.end()}
                  </TableCell>
                )}
                <TableCell>
                  <Button
                    color="primary"
                    onClick={() => {
                      setTaskToEdit(task);
                      setNewTaskDialog(true);
                    }}>
                    Edit
                  </Button>
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
        <Box>
          <Typography>
            Total: $
            {(Math.round((costTotal + secondaryCostTotal) * field.acres() * 100) / 100).toFixed(2)}
          </Typography>
        </Box>
      </React.Fragment>
    );
    return frag;
  };

  const savePlan = () => {
    let newPlanSettings = pond.HarvestPlanSettings.create({
      title: title,
      field: field.key(),
      createDate: moment.now(),
      cropType: cropType,
      grainType: variety,
      harvestYear: harvestYear,
      yieldTarget: targetYield,
      bushelPrice: !isNaN(parseFloat(price)) ? Math.round(parseFloat(price) * 100) / 100 : 0
    });
    setNewPlan(HarvestPlan.create(pond.HarvestPlan.fromObject({ settings: newPlanSettings })));

    harvestPlanAPI.addHarvestPlan(newPlanSettings, as).then(resp => {
      setPlanKey(resp.data.harvestPlan);
      openSnack("Plan Created");
    });
  };

  const updatePlan = () => {
    //material costs per acre
    let preseedMatCost = 0;
    let seedMatCost = 0;
    let postseedMatCost = 0;
    let harvestMatCost = 0;
    let fallMatCost = 0;

    //equipment costs per acre
    let preseedEqCost = 0;
    let seedEqCost = 0;
    let postseedEqCost = 0;
    let harvestEqCost = 0;
    let fallEqCost = 0;
    planTasks.forEach(task => {
      switch (task.settings.type) {
        case "preseed":
          preseedMatCost += task.cost();
          preseedEqCost += task.secondaryCost();
          break;
        case "seed":
          seedMatCost += task.cost();
          seedEqCost += task.secondaryCost();
          break;
        case "postseed":
          postseedMatCost += task.cost();
          postseedEqCost += task.secondaryCost();
          break;
        case "harvest":
          harvestMatCost += task.cost();
          harvestEqCost += task.secondaryCost();
          break;
        default:
          fallMatCost += task.cost();
          fallEqCost += task.secondaryCost();
          break;
      }
    });
    let tempPlan = plan ?? newPlan;
    tempPlan.settings.cropType = cropType;
    tempPlan.settings.field = field.key();
    tempPlan.settings.title = title;
    tempPlan.settings.grainType = variety;
    tempPlan.settings.harvestYear = harvestYear;
    tempPlan.settings.yieldTarget = targetYield;
    tempPlan.settings.bushelPrice = !isNaN(parseFloat(price))
      ? Math.round(parseFloat(price) * 100) / 100
      : 0;
    tempPlan.settings.preSeedMaterials = preseedMatCost;
    tempPlan.settings.preSeedEquipment = preseedEqCost;
    tempPlan.settings.seedMaterials = seedMatCost;
    tempPlan.settings.seedEquipment = seedEqCost;
    tempPlan.settings.postSeedMaterials = postseedMatCost;
    tempPlan.settings.postSeedEquipment = postseedEqCost;
    tempPlan.settings.harvestMaterials = harvestMatCost;
    tempPlan.settings.harvestEquipment = harvestEqCost;
    tempPlan.settings.fallMaterials = fallMatCost;
    tempPlan.settings.fallEquipment = fallEqCost;
    if (planKey) {
      harvestPlanAPI
        .updateHarvestPlan(planKey, tempPlan.settings, undefined, as)
        .then(resp => openSnack("Plan Updated"));
    }
    closeDialog(true, tempPlan);
  };

  const deletePlan = () => {
    if (planKey) {
      harvestPlanAPI.removeHarvestPlan(planKey, as).then(resp => {
        openSnack("Plan Deleted");
      });
    }
    setDeleteOpen(false);
    closeDialog(true);
  };

  const handleNextStep = () => {
    setActiveStep(prevStep => prevStep + 1);
  };
  const handleBack = () => {
    setActiveStep(prevActiveStep => prevActiveStep - 1);
  };

  const stepper = () => {
    return (
      <Box display="flex" justifyContent="center" width="100%">
        <Tabs
          value={activeStep}
          onChange={(_, value) => setActiveStep(value)}
          indicatorColor="primary"
          textColor="primary"
          variant="fullWidth"
          aria-label="bin tabs"
          classes={{ root: classes.tabs }}>
          <Tab
            key={0}
            classes={{ root: classes.tab }}
            disabled={
              !planKey || !(plan && plan.permissions.includes(pond.Permission.PERMISSION_WRITE))
            }
            label={"General"}
            aria-label={"general"}
          />
          {steps.map((label, i) => (
            <Tab
              key={i + 1}
              classes={{ root: classes.tab }}
              disabled={!planKey}
              label={label}
              aria-label={label}
            />
          ))}
        </Tabs>
      </Box>
    );
  };

  const general = () => {
    return (
      <Box>
        <TextField
          fullWidth
          margin="normal"
          type="text"
          label="Title"
          value={title}
          onChange={e => setTitle(e.target.value)}
        />
        {useCustom ? (
          <TextField
            margin="normal"
            fullWidth
            label="Crop"
            value={customCropType}
            onChange={e => setCustomCropType(e.target.value)}
            color="primary"
          />
        ) : (
          <TextField
            margin="normal"
            fullWidth
            select
            label="Crop"
            value={cropType}
            onChange={e => setCropType(+e.target.value)}
            color="primary">
            {cropOptions.map(option => (
              <MenuItem key={option.value} value={option.value}>
                {option.label}
              </MenuItem>
            ))}
          </TextField>
        )}
        <TextField
          fullWidth
          margin="normal"
          type="text"
          label="Variety"
          value={variety}
          onChange={e => setVariety(e.target.value)}
        />
        <TextField
          fullWidth
          margin="normal"
          type="number"
          label="Year"
          value={harvestYear}
          onChange={e => {
            !isNaN(+e.target.value) && setHarvestYear(+e.target.value);
          }}
        />
        <TextField
          fullWidth
          margin="normal"
          type="number"
          label="Target Yield per acre"
          value={targetYield}
          onChange={e => {
            !isNaN(+e.target.value) && setTargetYield(+e.target.value);
          }}
        />
        <TextField
          margin="dense"
          id="bushPrice"
          label="Estimated sale price per bushel"
          type="text"
          fullWidth
          helperText="Must be a valid number*"
          value={price}
          error={isNaN(+price) && price !== ""}
          InputProps={{
            startAdornment: <InputAdornment position="start">$</InputAdornment>
          }}
          onChange={e => {
            setPrice(e.target.value);
          }}
        />
      </Box>
    );
  };

  const preSeed = () => {
    return (
      <Box textAlign="center">
        <Button
          color="primary"
          onClick={() => {
            setType("preseed");
            setNewTaskDialog(true);
          }}>
          Add Crop Activity
        </Button>
        <Typography>Planned Activities</Typography>
        {showTasks("preseed")}
      </Box>
    );
  };

  const seed = () => {
    return (
      <Box textAlign="center">
        <Button
          color="primary"
          onClick={() => {
            setType("seed");
            setNewTaskDialog(true);
          }}>
          Add Crop Activity
        </Button>
        <Typography>Planned Activities</Typography>
        {showTasks("seed")}
      </Box>
    );
  };

  const postSeed = () => {
    return (
      <Box textAlign="center">
        <Button
          color="primary"
          onClick={() => {
            setType("postseed");
            setNewTaskDialog(true);
          }}>
          Add Crop Activity
        </Button>
        <Typography>Planned Activities</Typography>
        {showTasks("postseed")}
      </Box>
    );
  };

  const harvest = () => {
    return (
      <Box textAlign="center">
        <Button
          color="primary"
          onClick={() => {
            setType("harvest");
            setNewTaskDialog(true);
          }}>
          Add Crop Activity
        </Button>
        <Typography>Planned Activities</Typography>
        {showTasks("harvest")}
      </Box>
    );
  };

  const fall = () => {
    return (
      <Box textAlign="center">
        <Button
          color="primary"
          onClick={() => {
            setType("fall");
            setNewTaskDialog(true);
          }}>
          Add Crop Activity
        </Button>
        <Typography>Planned Activities</Typography>
        {showTasks("fall")}
      </Box>
    );
  };

  const stepperContent = (step: number) => {
    switch (step) {
      case 1:
        return preSeed();
      case 2:
        return seed();
      case 3:
        return postSeed();
      case 4:
        return harvest();
      case 5:
        return fall();
      default:
        return general();
    }
  };

  const deleteDialog = () => {
    return (
      <ResponsiveDialog open={deleteOpen}>
        <DialogContent>
          Are you sure you wish to delete plan? This action is irreversible.
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteOpen(false)}>Cancel</Button>
          <Button onClick={deletePlan}>
            <Typography color="error">Delete</Typography>
          </Button>
        </DialogActions>
      </ResponsiveDialog>
    );
  };

  return (
    <React.Fragment>
      <ResponsiveDialog open={open} onClose={() => closeDialog()} maxWidth="lg">
        <DialogTitle>Create New Crop Plan</DialogTitle>
        <DialogContent>
          {stepper()}
          {stepperContent(activeStep)}
        </DialogContent>
        <DialogActions>
          <Grid container direction="row">
            <Grid>
              {planKey && plan && field.permissions.includes(pond.Permission.PERMISSION_WRITE) && (
                <Button
                  variant="contained"
                  style={{ color: "black", backgroundColor: "red" }}
                  onClick={() => setDeleteOpen(true)}>
                  Delete
                </Button>
              )}
            </Grid>
            <Grid>
              <Button
                className={classes.buttonSpacing}
                variant="contained"
                color="primary"
                onClick={() => closeDialog()}>
                Cancel
              </Button>
              {activeStep === 0 && !planKey && (
                <React.Fragment>
                  <Button
                    className={classes.buttonSpacing}
                    variant="contained"
                    onClick={() => {
                      savePlan();
                    }}
                    color="primary">
                    Create Plan
                  </Button>
                </React.Fragment>
              )}
              {activeStep > 0 && (
                <Button
                  className={classes.buttonSpacing}
                  variant="contained"
                  onClick={handleBack}
                  color="primary">
                  Back
                </Button>
              )}
              {activeStep < 5 && (activeStep > 0 || planKey) && (
                <Button
                  className={classes.buttonSpacing}
                  variant="contained"
                  onClick={handleNextStep}
                  color="primary">
                  Next
                </Button>
              )}
              {(planKey || activeStep > 0) && (
                <Tooltip title="Finish Harvest Plan">
                  <Button
                    className={classes.buttonSpacing}
                    variant="contained"
                    color="primary"
                    onClick={updatePlan}>
                    Confirm
                  </Button>
                </Tooltip>
              )}
            </Grid>
          </Grid>
        </DialogActions>
      </ResponsiveDialog>
      {deleteDialog()}
      <TaskSettings
        task={taskToEdit}
        hasCost
        costTitle="Material Cost(acres)"
        secondaryCostTitle="Equipment Cost(acre)"
        objectKey={planKey}
        type={type}
        open={newTaskDialog}
        onClose={r => {
          setType("");
          setTaskToEdit(undefined);
          setNewTaskDialog(false);
          if (r) {
            loadTasks();
          }
        }}
      />
    </React.Fragment>
  );
}
