import {
  Accordion,
  AccordionDetails,
  AccordionSummary,
  Box,
  Button,
  Grid2,
  IconButton,
  Stack,
  Tab,
  Tabs,
  Typography
} from "@mui/material";
import React, { useCallback, useEffect, useState } from "react";
import { useMobile, useSnackbar } from "hooks";
import { useGlobalState, useFieldAPI, useJohnDeereProxyAPI, useCNHiProxyAPI } from "providers";
//import HarvestTable from "harvestPlan/HarvestTable";
import { Field } from "models";
import GrainDescriber from "grain/GrainDescriber";
import ResponsiveTable, { Column } from "common/ResponsiveTable";
import FieldMinimap from "./Fieldminimap";
import FieldActions from "./FieldActions";
import FieldSettings from "./FieldSettings";
import { ArrowForward, ExpandMore, Settings } from "@mui/icons-material";
import { cloneDeep } from "lodash";
import ShareAllFields from "./ShareAllFields";
import EventBlocker from "common/EventBlocker";
import { useNavigate } from "react-router-dom";

export default function FieldList() {
  const [{ as }] = useGlobalState();
  const isMobile = useMobile();
  const fieldAPI = useFieldAPI();
  const jdAPI = useJohnDeereProxyAPI();
  const cnhAPI = useCNHiProxyAPI();
  const { openSnack } = useSnackbar();
  const [tabValue, setTabValue] = React.useState(0);
  // const [fieldForPlan, setFieldForPlan] = useState(Field.create());
  const [fields, setFields] = useState<Field[]>([]);
  const [total, setTotal] = useState(0)
  const [rowsPerPage, setRowsPerPage] = useState(5)
  const [page, setPage] = useState(0)
  const [selectedField, setSelectedField] = useState<Field>()
  const [openFieldSettings, setOpenFieldSettings] = useState(false)
  const [shareOpen, setShareOpen] = useState(false)
  const navigate = useNavigate();

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

  const loadAdaptiveFields = useCallback(() => {
    fieldAPI
      .listFields(rowsPerPage, page*rowsPerPage, "asc", "fieldName", undefined, as)
      .then(resp => {
        setFields(resp.data.fields.map(f => Field.create(f)));
        setTotal(resp.data.total)
      })
      .catch(err => {
        openSnack("Failed to load Fields");
      });
  }, [fieldAPI, as, openSnack, page, rowsPerPage]);

  const loadJDFields = useCallback(() => {
    jdAPI.listFields(rowsPerPage, page*rowsPerPage, as)
    .then(resp => {
      resp.data.fields ? setFields(resp.data.fields.map(f => Field.create(f))) : setFields([])
    }).catch(err => {
        openSnack("Failed to load John Deere Fields");
    })
  },[jdAPI, as, openSnack, page, rowsPerPage])

  const loadCNHFields = useCallback(() => {
    cnhAPI.listFields(rowsPerPage, page*rowsPerPage, as)
    .then(resp => {
      resp.data.fields ? setFields(resp.data.fields.map(f => Field.create(f))) : setFields([])
    }).catch(err => {
        openSnack("Failed to load John Deere Fields");
    })
  },[cnhAPI, as, openSnack, page, rowsPerPage])

  useEffect(() => {
    //based on the current tab load the correct fields
    switch(tabValue){
      case 0:
        loadAdaptiveFields();
        break;
      case 1:
        loadJDFields();
        break;
      case 2:
        loadCNHFields();
        break;
    }
  }, [loadAdaptiveFields, loadJDFields, loadCNHFields, tabValue]);

  const goTo = (field: Field) => {
    let path = field.key();
    navigate(path, { state: {field: field, permissions: field.permissions} });
  }

  const fieldActions = (field: Field) => {
    return (
      <EventBlocker>
        <IconButton 
          onClick={() => {
            setSelectedField(field)
            setOpenFieldSettings(true)
          }}><Settings /></IconButton>
        <FieldActions field={field} permissions={field.permissions} refreshCallback={()=>{}}/>
        {isMobile && <IconButton onClick={() => {goTo(field)}}><ArrowForward /></IconButton>}
      </EventBlocker>
    )
  }

const columns: Column<Field>[] = [
  {
    title: "View",
    render: row => {
      return (
        <Box margin={1} height={200} width={200}>
          <FieldMinimap field={row} squared borderSpacing={0.001}/>
        </Box>
      )
    }
  },
  {
    title: "Field Name",
    render: row => {
      return <Typography paddingLeft={2}>{row.name()}</Typography>
    }
  },
  {
    title: "Current Crop",
    render: row => {
      return <Typography paddingLeft={2}>{GrainDescriber(row.crop()).name}</Typography>
    }
  },
  {
    title: "Acres",
    render: row => {
      return <Typography paddingLeft={2}>{row.acres()}</Typography>
    }
  },
  {
    title: "Actions",
    hidden: tabValue > 0,
    render: row => fieldActions(row)
  }
]

  const fieldTable = (fields: Field[]) => {
    return (
      <ResponsiveTable<Field>
        columns={columns}
        rows={fields}
        onRowClick={(row) => {
          !isMobile && goTo(row)
        }}
        setPage={(newPage)=>{
          setPage(newPage)
        }}
        handleRowsPerPageChange={(e)=>{setRowsPerPage(e.target.value)}}
        page={page}
        pageSize={rowsPerPage}
        total={total}
        resizeable
        loadMore={() => {
          let currentFields = cloneDeep(fields)
          switch(tabValue){
            case 0:
              fieldAPI.listFields(rowsPerPage, currentFields.length, "asc", "fieldName", undefined, as).then(resp => {
                setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f))))
              }).catch(err => {
                openSnack("Failed to load more fields")
              })
              break;
            case 1:
              jdAPI.listFields(rowsPerPage, currentFields.length, as).then(resp => {
                resp.data.fields ? setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f)))) : setFields([])
              }).catch(err => {
                openSnack("Failed to load more fields")
              })
              break;
            case 2:
              cnhAPI.listFields(rowsPerPage, currentFields.length, as).then(resp => {
                resp.data.fields ? setFields(currentFields.concat(resp.data.fields.map(f => Field.create(f)))) : setFields([])
              }).catch(err => {
                openSnack("Failed to load more fields")
              })
              break;
          }
        }}
        renderMobile={(row, index) => {
          return (
            <Accordion>
              <AccordionSummary expandIcon={<ExpandMore />}>
                <Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap">
                  <Grid2>
                    <Typography textAlign="center">
                      {row.name()}
                    </Typography>
                  </Grid2>
                  <Grid2>
                    {fieldActions(row)}
                  </Grid2>
                </Grid2>
              </AccordionSummary>
              <AccordionDetails>
                <Grid2 alignItems="center" width="100%" container direction={"row"} justifyContent="space-between" wrap="nowrap">
                  <Grid2 size={6}>
                    <Box height={150} width="100%">
                      <FieldMinimap field={row} borderSpacing={0.001} squared />
                    </Box>
                  </Grid2>
                  <Grid2 size={6}>
                    <Stack spacing={2}>
                      <Typography textAlign="center">{row.grainName()}</Typography>
                      <Typography textAlign="center">{row.acres()} Acres</Typography>
                    </Stack>
                    <Button variant="contained" color="primary" fullWidth onClick={() => goTo(row)}>Go</Button>
                  </Grid2>
                </Grid2>
              </AccordionDetails>
            </Accordion>
          )
        }}
      />
    )
  }

  return (
    <Box>
        <Button
          onClick={()=>{setShareOpen(true)}}
          variant="contained"
          color="primary">
            Share All
        </Button>
      <Tabs
        value={tabValue}
        onChange={handleChange}
        TabIndicatorProps={{ style: { background: "rgba(255,255,0,255)" } }}>
        <Tab label="Adaptive" />
        <Tab label="John Deere" />
        <Tab label="Case New Holland" />
      </Tabs>
      {fieldTable(fields)}
      {/* <HarvestSettings
        open={openHarvestSettings}
        close={() => setOpenHarvestSettings(false)}
        field={fieldForPlan}
      /> */}
      <FieldSettings
        selectedField={selectedField}
        removeField={() => {
          //will need to re-load the fields after one is deleted
          loadAdaptiveFields()
        }}
        open={openFieldSettings}
        onClose={() => {
          setOpenFieldSettings(false);
        }}
      />
      <ShareAllFields open={shareOpen} close={() => {setShareOpen(false)}}/>
    </Box>
  );
}