import {
  Box,
  Divider,
  Drawer,
  Grid2 as Grid,
  IconButton,
  Tab,
  Tabs,
  Theme,
  Typography
} from "@mui/material";
import { Notes } from "@mui/icons-material";
import DisplayDrawer from "common/DisplayDrawer";
import HarvestPlanDisplay from "harvestPlan/HarvestPlanDisplay";
import { Field, fieldScope, HarvestPlan, teamScope } from "models";
import React, { useEffect, useState } from "react";
import TaskViewer from "tasks/TaskViewer";
import Weather from "weather/weather";
import { getThemeType } from "theme";
import GrainDescriber from "grain/GrainDescriber";
import Chat from "chat/Chat";
import { pond } from "protobuf-ts/pond";
import { useMobile } from "hooks";
import { useGlobalState, useHarvestPlanAPI, useUserAPI } from "providers";
import { makeStyles } from "@mui/styles";
import FieldActions from "field/FieldActions";

interface TabPanelProps {
  children?: React.ReactNode;
  index: any;
  value: any;
}

function TabPanelMine(props: TabPanelProps) {
  const { children, value, index, ...other } = props;

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      aria-labelledby={`simple-tab-${index}`}
      style={{ height: "94%", paddingTop: "15px" }}
      {...other}>
      {value === index && <React.Fragment>{children}</React.Fragment>}
    </div>
  );
}
interface Props {
  open: boolean;
  closeDrawer: () => void;
  selectedFieldKey: string;
  fields: Map<string, Field>;
  openSettings: (fieldKey: string) => void;
  moveMap: (long: number, lat: number) => void;
}

const useStyles = makeStyles((theme: Theme) => ({
    avatar: {
      color: getThemeType() === "light" ? theme.palette.common.black : theme.palette.common.white,
      backgroundColor: "transparent",
      width: theme.spacing(5),
      height: theme.spacing(5),
      border: "1px solid",
      borderColor: theme.palette.divider
    },
    dark: {
      backgroundColor: getThemeType() === "light" ? "rgb(245, 245, 245)" : "rgb(50, 50, 50)",
      padding: 5
    },
    light: {
      backgroundColor: getThemeType() === "light" ? "rgb(235, 235, 235)" : "rgb(60, 60, 60)",
      padding: 5
    }
  
}));

export default function FieldDrawer(props: Props) {
  const { open, closeDrawer, selectedFieldKey, fields, moveMap } = props;
  const [field, setField] = useState<Field>(Field.create());
  const [hPlan, setHPlan] = useState<HarvestPlan>(HarvestPlan.create());
  const [value, setValue] = useState(0);
  const classes = useStyles();
  const [openNote, setOpenNote] = useState(false);
  const isMobile = useMobile();
  const [{ as, user }] = useGlobalState();
  const hPlanAPI = useHarvestPlanAPI();
  const [planLoading, setPlanLoading] = useState(false);
  const userAPI = useUserAPI();
  const [permissions, setPermissions] = useState<pond.Permission[]>([]);

  useEffect(() => {
    let field = fields.get(selectedFieldKey);
    if (field) {
      setField(field);
    }
  }, [selectedFieldKey, fields]);

  useEffect(() => {
    let scope;
    if (as) {
      //if they are viewing as a team regardless of whether the field is adaptive or external (from JD or CNH) get the users permission to the team
      scope = teamScope(as);
    } else if (
      field.settings.fieldGeoData &&
      field.settings.fieldGeoData.origin === pond.DataOrigin.DATA_ORIGIN_ADAPTIVE
    ) {
      //if they are viewing as a user and the field is an adaptive field get the users permission to the field
      scope = fieldScope(field.key());
    }

    //if the scope was set get the permissions the user has in that scope
    if (scope) {
      userAPI.getUser(user.id(), scope).then(resp => {
        field.permissions = resp.permissions;
        setPermissions(resp.permissions);
      });
    } else {
      //if scope wasn't set that means that they are viewing an external field as a user and so will have full permissions
      //because they would have full permissions to the organization that the field is linked to since users cannot share organizations
      //and they are only linked to team/user combinations during creation and cannot be shared afterward
      let perms = [
        pond.Permission.PERMISSION_READ,
        pond.Permission.PERMISSION_WRITE,
        pond.Permission.PERMISSION_SHARE,
        pond.Permission.PERMISSION_USERS
      ];
      field.permissions = perms;
      setPermissions(perms);
    }
  }, [as, user, userAPI, field]); //eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => {
    if (field.key() !== "") {
      hPlanAPI
        .listHarvestPlans(1, 0, "desc", "createDate", field.key(), as)
        .then(resp => {
          if (resp.data.harvestPlan.length > 0) {
            let plan = resp.data.harvestPlan[0];
            setHPlan(HarvestPlan.any(plan));
          } else {
            setHPlan(HarvestPlan.create());
          }
          setPlanLoading(false);
        })
        .catch(err => {
          //openSnack("Failed to load plan");
        });
    }
  }, [field, as, hPlanAPI]);

  const handleChange = (event: React.ChangeEvent<{}>, newValue: number) => {
    setValue(newValue);
  };

  const displayNext = () => {
    let arr = Array.from(fields.values());
    let index = arr.indexOf(field);
    let found = false;
    do {
      if (index === arr.length - 1) {
        index = 0;
      } else {
        index++;
      }
      let nextField = arr[index];
      let location = nextField.center();
      if (
        location !== null &&
        location !== undefined &&
        location.longitude !== 0 &&
        location.longitude !== 0
      ) {
        setField(nextField);
        moveMap(location.longitude, location.latitude);
        found = true;
      }
    } while (!found);
  };

  const displayPrev = () => {
    let arr = Array.from(fields.values());
    let index = arr.indexOf(field);
    let found = false;
    do {
      if (index === 0) {
        index = arr.length - 1;
      } else {
        index--;
      }
      let nextField = arr[index];
      let location = nextField.center();
      if (
        location !== null &&
        location !== undefined &&
        location.longitude !== 0 &&
        location.longitude !== 0
      ) {
        setField(nextField);
        moveMap(location.longitude, location.latitude);
        found = true;
      }
    } while (!found);
  };

  const drawerBody = () => {
    let taskLoadKeys: string[] = [];
    if (!planLoading) {
      field.key() !== "" && taskLoadKeys.push(field.key());
      hPlan.key() !== "" && taskLoadKeys.push(hPlan.key());
    }
    return (
      <React.Fragment>
        <Tabs
          style={{ position: "sticky" }}
          value={value}
          centered
          onChange={handleChange}
          TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
          <Tab label="Field Overview" />
          <Tab label="Weather" />
          <Tab label="Field Activities" />
        </Tabs>
        <TabPanelMine value={value} index={0}>
          <Box paddingLeft={2} paddingRight={2} paddingBottom={5}>
            <IconButton className={classes.avatar} onClick={() => setOpenNote(true)}>
              <Notes />
            </IconButton>
            <Box>
              <Typography variant="h5" style={{ fontWeight: 700 }}>
                {field.fieldName()} Details
              </Typography>
            </Box>
            <Grid container direction="column" alignItems="center" width="100%">
              <Grid container direction="row" justifyContent="space-between" width="100%" className={classes.dark}>
                <Grid>Approximate Area:</Grid>
                <Grid>{field.acres()}ac</Grid>
              </Grid>
              <Grid container direction="row" justifyContent="space-between" width="100%" className={classes.light}>
                <Grid>Grain:</Grid>
                <Grid>
                  {field.grain() === pond.Grain.GRAIN_CUSTOM
                    ? field.customType()
                    : GrainDescriber(field.crop()).name}
                </Grid>
              </Grid>
              <Grid container direction="row" justifyContent="space-between" width="100%" className={classes.dark}>
                <Grid>Grain Variant:</Grid>
                <Grid>{field.settings.grainSubtype}</Grid>
              </Grid>
              <Grid container direction="row" justifyContent="space-between" width="100%" className={classes.light}>
                <Grid>Land Location:</Grid>
                <Grid>{field.landLoc()}</Grid>
              </Grid>
            </Grid>
            <Box padding={3}>
              <Divider style={{ padding: 2 }} />
            </Box>
            <HarvestPlanDisplay
              plan={hPlan}
              permissions={permissions}
              planField={field}
              loading={planLoading}
              fieldList={Array.from(fields.values())}
              changePlan={updatedPlan => {
                if (updatedPlan) {
                  setHPlan(updatedPlan);
                }
              }}
            />
          </Box>
        </TabPanelMine>
        <TabPanelMine value={value} index={1}>
          <Weather longitude={field.center().longitude} latitude={field.center().latitude} />
        </TabPanelMine>
        <TabPanelMine value={value} index={2}>
          <TaskViewer drawerView objectKey={field.key()} loadKeys={taskLoadKeys} />
        </TabPanelMine>
      </React.Fragment>
    );
  };

  const noteDrawer = () => {
    return (
      <Drawer
        anchor={isMobile ? "bottom" : "right"}
        open={openNote}
        onClose={() => setOpenNote(false)}>
        <Box height={isMobile ? "50vh" : "100vh"} padding={2}>
          <Typography style={{ fontWeight: 650 }}>Notes</Typography>
          <Chat type={pond.NoteType.NOTE_TYPE_FIELD} objectKey={field.key()} />
        </Box>
      </Drawer>
    );
  };

  return (
    <React.Fragment>
      <DisplayDrawer
        open={open}
        onClose={closeDrawer}
        displayNext={displayNext}
        displayPrev={displayPrev}
        title={field.name()}
        width={"40vw"}
        drawerBody={drawerBody()}
        updateElement={
          field.settings.fieldGeoData &&
          field.settings.fieldGeoData.origin === pond.DataOrigin.DATA_ORIGIN_ADAPTIVE
            ? () => {
                props.openSettings(selectedFieldKey);
              }
            : undefined
        }
        objectActions={
          field.settings.fieldGeoData &&
          field.settings.fieldGeoData.origin === pond.DataOrigin.DATA_ORIGIN_ADAPTIVE ? (
            <FieldActions field={field} permissions={permissions} refreshCallback={() => {}} />
          ) : (
            undefined
          )
        }
      />
      {noteDrawer()}
    </React.Fragment>
  );
}
