import { Field, fieldScope, HarvestPlan, teamScope } from "models";
import { useFieldAPI, useGlobalState, useHarvestPlanAPI } from "providers";
import React, { useCallback, useEffect, useState } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import PageContainer from "./PageContainer";
import { useMobile, useSnackbar, useUserAPI } from "hooks";
import { Box, Card, Grid2, IconButton, Tab, Tabs, Theme, Typography, darken } from "@mui/material";
import FieldActions from "field/FieldActions";
import { Settings } from "@mui/icons-material";
import { pond } from "protobuf-ts/pond";
import FieldMinimap from "field/Fieldminimap";
import Weather from "weather/weather";
import TaskViewer from "tasks/TaskViewer";
import HarvestPlanDisplay from "harvestPlan/HarvestPlanDisplay";
import { cloneDeep } from "lodash";
import HarvestPlanTable from "harvestPlan/HarvestPlanTable";
import { makeStyles } from "@mui/styles";
import FieldSettings from "field/FieldSettings";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    card: {
      height: "100%", 
      bgcolor: darken(theme.palette.background.paper, 0.05),
    },
    sectionHeader: {
      fontSize: 35,
      fontWeight: 650
    }
  })
})

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

function TabPanel(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>
  );
}

export default function FieldPage() {
    const { state } = useLocation();
    //const [{ as }] = useGlobalState()
    const classes = useStyles();
    const fieldAPI = useFieldAPI();
    const userAPI = useUserAPI();
    const [{as, user}] = useGlobalState();
    const {openSnack} = useSnackbar();
    const fieldID = useParams<{ fieldID: string }>()?.fieldID ?? "";
    const [field, setField] = useState<Field>(state?.field ? Field.create(state.field) : Field.create())
    const [permissions, setPermissions] = useState<pond.Permission[]>(state?.permissions ? state.permissions : [])
    const isMobile = useMobile()
    const [openFieldSettings, setOpenFieldSettings] = useState(false)
    const [planLoading, setPlanLoading] = useState(false)
    const [hPlan, setHPlan] = useState<HarvestPlan>(HarvestPlan.create());
    const [loading, setLoading] = useState(false)
    const hPlanAPI = useHarvestPlanAPI();
    const [tabVal, setTabVal] = useState(0)
    const navigate = useNavigate()

    const loadField = useCallback(() => {
      if(state.field){
        fieldAPI.getField(state.field).then(resp => {
          setField(Field.create(resp.data))
        }).catch(err => {
          
        })
      }
    },[as])

    const goTo = () => {
      navigate("/fields");
    }

    useEffect(()=>{
      // if already loading do nothing
      if(loading) return
      //if the field is passed through in the state just use it
      if(state?.field){
        let field = Field.create(state.field)
        field.permissions = state.permissions
        setField(field)
        setPermissions(state.permissions)
        return
      }
      //otherwise load the field
      setLoading(true)
      fieldAPI.getField(fieldID, as).then(resp => {
        setField(Field.create(resp.data))

      }).catch(err => {
        openSnack("Failed to load Field")
      }).finally(() => {
        setLoading(false)
      })
      //also get the permissions
      let scope = fieldScope(fieldID);
      if (as) {
        scope = teamScope(as)
      }
      userAPI.getUser(user.id(), scope).then(resp => {
        let f = cloneDeep(field) 
        f.permissions = resp.permissions
        setField(f)
        setPermissions(resp.permissions);
      });
    },[loadField, fieldID, as])

    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 fieldActions = () => {
      return (
        <Grid2 container direction={"row"} justifyContent="space-between" alignContent="center" alignItems="center">
          <Grid2>
            <Typography className={classes.sectionHeader}>
              {field.name()}
            </Typography>
          </Grid2>
          <Grid2>
            <IconButton 
              onClick={() => {
                setOpenFieldSettings(true)
              }}><Settings /></IconButton>
            <FieldActions field={field} permissions={permissions} refreshCallback={()=>{}}/>
          </Grid2>
        </Grid2>
      )
    }

    const map = () => {
      return (
        <Box minHeight={550} height="100%">
          <FieldMinimap field={field} borderSpacing={0.001} squared/>
        </Box>
      )
    }

    const weather = () => {
            return (<Weather longitude={field.center().longitude} latitude={field.center().latitude} />)
    }

    const harvestPlans = () => {
      return (
        <HarvestPlanDisplay
          plan={hPlan}
          permissions={permissions}
          planField={field}
          loading={planLoading}
          changePlan={updatedPlan => {
            if (updatedPlan) {
              setHPlan(updatedPlan);
            }
          }}
        />)
    }

    const tasks = () => {
      let taskLoadKeys: string[] = [];
      if (!planLoading) {
        field.key() !== "" && taskLoadKeys.push(field.key());
        //hPlan.key() !== "" && taskLoadKeys.push(hPlan.key());
      }
      return (<TaskViewer drawerView objectKey={field.key()} loadKeys={taskLoadKeys} overlayButton={isMobile}/>)
    }

    const desktopView = () => {
      return (
        <React.Fragment>
        <Box>
        <Grid2 container spacing={1}>
          <Grid2 size={4}>
            <Card raised className={classes.card}>
              {map()}
            </Card>
          </Grid2>
          <Grid2 size={3}>
            <Card raised className={classes.card}>
              {weather()}
            </Card>
          </Grid2>
          <Grid2 size={5}>
            <Card raised className={classes.card}>
              {tasks()}
            </Card>
          </Grid2>
        </Grid2>
        </Box>
        <Box>
          <Typography className={classes.sectionHeader}>
            Harvest Overview
          </Typography>
        <Grid2 container spacing={1}>
          <Grid2 size={4}>
            <Card raised className={classes.card}>
              {harvestPlans()}
            </Card>
          </Grid2>
          <Grid2 size={8}>
            <Card raised>
              <HarvestPlanTable field={field} planSelected={(plan) => {setHPlan(plan)}}/>
            </Card>
          </Grid2>
        </Grid2>
        </Box>
        </React.Fragment>
      )
    }

    const mobileView = () => {
      return (
        <React.Fragment>
          <Tabs
            value={tabVal}
            onChange={(_, val) => {
              setTabVal(val)
            }}
            TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
            <Tab label="Overview" />
            <Tab label="Activities" />
            <Tab label="Harvest" />
          </Tabs>
          <TabPanel value={tabVal} index={0}>
            <Grid2 container spacing={2} direction="column">
              <Grid2 size={12}>
                <Card raised sx={{height: "50vh"}}>
                  {map()}
                </Card>
              </Grid2>
              <Grid2 size={12}>
                <Card raised>
                  {weather()}
                </Card>
              </Grid2>
            </Grid2>
          </TabPanel>
          <TabPanel value={tabVal} index={1}>
            <Card raised>
            {tasks()}
            </Card>
          </TabPanel>
          <TabPanel value={tabVal} index={2}>
            <Grid2>
              <Grid2 size={12}>
                <Card raised className={classes.card}>
                  {harvestPlans()}
                </Card>
              </Grid2>
              <Grid2>
                <HarvestPlanTable field={field} planSelected={(plan) => {setHPlan(plan)}}/>
              </Grid2>
            </Grid2>
          </TabPanel>
        </React.Fragment>
      )
    }

    const fieldSettings = () => {
      return (
        <FieldSettings 
          open={openFieldSettings}
          onClose={() => {
            setOpenFieldSettings(false)
          }}
          selectedField={field}
          updateFields={() => {
            loadField()
          }}
          removeField={()=>{
            goTo()
          }}
        />
      )
    }

    return (
      <PageContainer>
        <Box padding={2}>
        {fieldActions()}
        {isMobile ? mobileView() : desktopView()}
        </Box>
        {fieldSettings()}
      </PageContainer>
    )
}