import { Avatar, Box, Button, Card, Grid2 as Grid, Switch, Tab, Tabs, Tooltip, Typography } from "@mui/material";
import { Group } from "@mui/icons-material";
//import MaterialTable from "material-table";
import { Site, User } from "models";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useSiteAPI } from "providers";
import React, { useCallback, useEffect, useState } from "react";
import PageContainer from "./PageContainer";
//import { getTableIcons } from "common/ResponsiveTable";
//import { useHistory } from "react-router";
import { useMobile } from "hooks";
import JobsiteIcon from "products/Construction/JobSiteIcon";
import ResponsiveTable, { Column } from "common/ResponsiveTable";
import { useNavigate } from "react-router-dom";
import { cloneDeep } from "lodash";

interface SiteWithData {
  site: Site;
  users: User[];
  heaterData: pond.ObjectHeaterData[];
}

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

export default function Sites() {
  const siteAPI = useSiteAPI();
  const [loading, setLoading] = useState(false);
  const [{ as }] = useGlobalState();
  //const history = useHistory();
  const navigate = useNavigate()
  const [sites, setSites] = useState<SiteWithData[]>([]);
  const isMobile = useMobile();
  const [currentTab, setCurrentTab] = useState(0);
  const [tablePage, setTablePage] = useState(0);
  const [pageSize, setPageSize] = useState(10);
  const [total, setTotal] = useState(0)

  const loadSites = useCallback(() => {
    if (loading) return;
    setLoading(true);
    //make a site api that gets an array of objects that contain the site, its devices, and teams
    siteAPI
      .listSitesPageData(pageSize, tablePage * pageSize, "asc", "siteName", undefined, as)
      .then(resp => {
        setTotal(resp.data.total);
        setSites(buildTableData(resp.data.sites));
      })
      .finally(() => {
        setLoading(false);
      });
  }, [as, siteAPI, pageSize, tablePage]); //eslint-disable-line react-hooks/exhaustive-deps

  const buildTableData = (siteData: pond.SiteData[]) => {
    let data: SiteWithData[] = [];
    siteData.forEach(site => {
      if (site.site?.settings?.siteName) {
        let newTableData: SiteWithData = {
          site: Site.any(site.site),
          users: [],
          heaterData: []
        };
        if (site.users) {
          newTableData.users = site.users.map(u => User.any(u));
        }
        if (site.heaterData) {
          newTableData.heaterData = site.heaterData;
        }
        data.push(newTableData);
      }
    });
    return data;
  };

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

  const siteInfoDisplay = (site: SiteWithData) => {
    return (
      <Grid container direction="column">
        <Grid>
          <Typography style={{ fontWeight: 650 }}>{site.site.siteName()}</Typography>
        </Grid>
        <Grid>
          {site.heaterData.length + (site.heaterData.length > 1 ? " Heaters" : " Heater")}
        </Grid>
      </Grid>
    );
  };

  const goToSite = (jobsite: SiteWithData) => {
    // let path = "/jobsites/" + jobsite.site.settings.key;
    // history.push(path, {});
    let path = "/jobsites/" + jobsite.site.key();
    navigate(path, { state: jobsite.site })
  };

  const updateActive = (active: boolean, site: Site) => {
    site.settings.active = active;
    siteAPI
      .updateSite(site.key(), site.settings, undefined, as)
      .then(resp => {})
      .catch(err => {});
    setSites([...sites]);
  };

  const desktopColumns = (): Column<SiteWithData>[] => {
    return ([
      {
        title: "Site",
        render: row => (
          <Box padding={2}>
            <Typography>
              {row.site.siteName()}
            </Typography>
          </Box>
        )
      },
      {
        title: "Heaters",
        render: row => (
          <Grid container spacing={1}>
            {row.heaterData.map((hd: pond.ObjectHeaterData) => (
              <Grid key={hd.heater?.key}>
                {hd.heater?.name}
              </Grid>
            ))}
          </Grid>
        )
      },
      {
        title: "Users",
        render: row => (
          <Grid container spacing={1}>
            {row.users.map((user: User) => (
              <Grid key={user.id()}>
                <Tooltip title={user.name()}>
                  {user.settings.avatar ? (
                    <Avatar alt={user.settings.name} src={user.settings.avatar} />
                  ) : (
                    <Avatar alt={user.settings.name}>
                      <Group />
                    </Avatar>
                  )}
                </Tooltip>
              </Grid>
            ))}
          </Grid>
        )
      },
      {
        title: "Active",
        render: row => (
          <React.Fragment>
            <Switch
              checked={row.site.settings.active}
              onClick={e => {
                e.stopPropagation();
              }}
              onChange={e => {
                updateActive(e.target.checked, row.site);
              }}
            />
          </React.Fragment>
        ),
      }
    ])
  }

  const handleTablePage = (event: any) => {
    setPageSize(event.target.value);
  };

  const desktopView = () => {
  return (
    <ResponsiveTable<SiteWithData>
      title={"Jobsites"}
      page={tablePage}
      pageSize={pageSize}
      columns={desktopColumns}
      setPage={(newPage) => {setTablePage(newPage)}}
      total={total}
      rows={sites}
      handleRowsPerPageChange={handleTablePage}
      onRowClick={goToSite}
      loadMore={()=>{
        let current = cloneDeep(sites)
        setLoading(true);
        siteAPI
          .listSitesPageData(pageSize, current.length, "asc", "siteName", undefined, as)
          .then(resp => {
            let newData = buildTableData(resp.data.sites);
            setSites(current.concat(newData))
          })
          .finally(() => {
            setLoading(false);
          });
      }}
    />
    )
  };

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

    return (
      <div
        role="tabpanel"
        hidden={value !== index}
        aria-labelledby={`simple-tab-${index}`}
        {...other}>
        {value === index && <React.Fragment>{children}</React.Fragment>}
      </div>
    );
  }

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

  const loadMore = () => {
    let current = cloneDeep(sites)
    setLoading(true);
    siteAPI
      .listSitesPageData(pageSize, current.length, "asc", "siteName", undefined, as)
      .then(resp => {
        let newData = buildTableData(resp.data.sites);
        setSites(current.concat(newData))
      })
      .finally(() => {
        setLoading(false);
      });
  }

  const mobileView = () => {
    return (
      <React.Fragment>
        <Tabs
          value={currentTab}
          indicatorColor="primary"
          textColor="primary"
          onChange={handleChange}
          centered
          style={{
            marginLeft: "auto"
          }}>
          <Tab label="Active" />
          <Tab label="Inactive" />
        </Tabs>
        <TabPanelMine value={currentTab} index={0}>
          {sites.map(site => {
            let siteCards: JSX.Element[] = [];
            if (site.site.settings.active) {
              siteCards.push(
                <Card
                  key={site.site.key()}
                  style={{ margin: 10, padding: 5 }} 
                  onClick={() => {
                    goToSite(site);
                  }}>
                  <Grid container alignContent="center" alignItems="center">
                    <Grid size={2} style={{ textAlign: "center" }}>
                      <JobsiteIcon size={50} />
                    </Grid>
                    <Grid size={7}>
                      {/* information (site name, number of devices, teams in site) */}
                      {siteInfoDisplay(site)}
                    </Grid>
                    <Grid size={3}>
                      <Switch
                        defaultChecked={site.site.settings.active}
                        onClick={e => {
                          e.stopPropagation();
                        }}
                        onChange={e => {
                          updateActive(e.target.checked, site.site);
                        }}
                      />
                    </Grid>
                  </Grid>
                </Card>
              );
            }
            return siteCards;
          })}
        </TabPanelMine>
        <TabPanelMine value={currentTab} index={1}>
          {sites.map(site => {
            let siteCards: JSX.Element[] = [];
            if (!site.site.settings.active) {
              siteCards.push(
                <Card
                  key={site.site.key()}
                  style={{ margin: 10, padding: 5 }}
                  onClick={() => {
                    goToSite(site);
                  }}>
                  <Grid container alignContent="center" alignItems="center">
                    <Grid size={2} style={{ textAlign: "center" }}>
                      <JobsiteIcon size={50} />
                    </Grid>
                    <Grid size={7}>
                      {/* information (site name, number of devices, teams in site) */}
                      {siteInfoDisplay(site)}
                    </Grid>
                    <Grid size={3}>
                      <Switch
                        defaultChecked={site.site.settings.active}
                        onClick={e => {
                          e.stopPropagation();
                        }}
                        onChange={e => {
                          updateActive(e.target.checked, site.site);
                        }}
                      />
                    </Grid>
                  </Grid>
                </Card>
              );
            }
            return siteCards;
          })}
        </TabPanelMine>
        {sites.length < total &&
          <Button onClick={loadMore} variant="contained" color="primary" fullWidth>Load More</Button>
        }
      </React.Fragment>
    );
  };

  return <PageContainer>{isMobile ? mobileView() : desktopView()}</PageContainer>;
}
