import {
  Box,
  Breadcrumbs,
  Chip,
  IconButton,
  Link,
  LinkProps,
  Skeleton,
  Theme,
  Tooltip,
  Typography,
  useTheme
} from "@mui/material";
import { Replay } from "@mui/icons-material";
import { useMobile } from "hooks";
import { ReactNode } from "react";
import { useLocation } from "react-router";
import { Link as RouterLink } from "react-router-dom";
import { or } from "utils/types";
import { makeStyles } from "@mui/styles";
import { getThemeType } from "theme/themeType";

const useStyles = makeStyles((theme: Theme) => {
  // const isMobile = useMobile()
  return ({
    chip: {
      maxWidth: "150px",
      [theme.breakpoints.up("md")]: {
        maxWidth: "200px"
      },
      color: "inherit",
      textDecoration: "none",
      '&:hover': {
        color: "inherit"
      }
    },
    textOverflow: {
      whiteSpace: "nowrap",
      overflow: "hidden",
      textOverflow: "ellipsis",
      textTransform: "capitalize",
      textDecoration: "none"
    }
  });
});

interface Props {
  deviceName?: string;
  componentName?: string;
  groupName?: string;
  binName?: string;
  teamName?: string;
  reportTarget?: string;
  loading?: boolean;
  reload?: () => void;
  padding?: number;
  paddingLeft?: number;
  paddingRight?: number;
  paddingTop?: number;
  paddingBottom?: number;
  prependPaths?: string[];
  state?: any;
}

interface LinkRouterProps extends LinkProps {
  to: string;
  replace?: boolean;
  state?: any;
}

const LinkRouter = (props: LinkRouterProps) => <Link {...props} component={RouterLink as any} />;

export default function SmartBreadcrumb(props: Props) {
  const prependPaths = props.prependPaths;
  const theme = useTheme();
  const location = useLocation();
  const isMobile = useMobile();
  const classes = useStyles();
  const { loading, reload, state } = props;

  const groupID = (): string => {
    let index = prependPaths?.indexOf("groups")
    if (index !== undefined && index > -1) {
      if (prependPaths && prependPaths[index+1]) {
        return prependPaths[index+1]
      }
    }
    const regexMatch = or(location.pathname.match(/\/groups\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const deviceID = (): string => {
    const regexMatch = or(location.pathname.match(/\/devices\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const mineKey = (): string => {
    const regexMatch = or(location.pathname.match(/\/mines\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const jobsiteKey = (): string => {
    const regexMatch = or(location.pathname.match(/\/jobs\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const componentID = (): string => {
    const regexMatch = or(location.pathname.match(/\/components\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const reportID = (): string => {
    const regexMatch = or(location.pathname.match(/\/reports\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const binID = (): string => {
    const regexMatch = or(location.pathname.match(/\/bins\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const teamKey = (): string => {
    const regexMatch = or(location.pathname.match(/\/teams\/([^/]+)/), [])
    return or(regexMatch[1], "0").toString();
  };

  const reportIDShort = (): string => {
    return reportID().split("-")[0];
  };

  // Paths

  const dashboardPath = (): string => {
    return "/";
  };

  const groupsPath = (): string => {
    return "/groups";
  };

  const groupPath = (): string => {
    return groupsPath() + "/" + groupID();
  };

  const devicesPath = (): string => {
    return "/devices";
  };

  const devicePath = (): string => {
    return devicesPath() + "/" + deviceID();
  };

  const minesPath = (): string => {
    return "/mines";
  };

  const minePath = (): string => {
    return minesPath() + "/" + mineKey();
  };

  const jobsitesPath = (): string => {
    return "/jobsites";
  };

  const jobsitePath = (): string => {
    return jobsitesPath() + "/" + jobsiteKey();
  };

  const componentsPath = (): string => {
    return "/components";
  };

  const componentPath = (): string => {
    return componentsPath() + "/" + componentID();
  };

  const securityPath = (): string => {
    return "/security";
  };

  const reportPath = (): string => {
    return securityPath() + "/" + reportID();
  };

  const groupDevicesPath = (): string => {
    return groupPath() + devicesPath();
  };

  const groupDevicePath = (): string => {
    return groupPath() + devicePath();
  };

  const groupComponentsPath = (): string => {
    return groupPath() + componentsPath();
  };

  const groupComponentPath = (): string => {
    return groupPath() + componentPath();
  };

  const historyPath = (): string => {
    return "/history";
  };

  const deviceHistoryPath = (): string => {
    return devicePath() + historyPath();
  };

  const groupDeviceHistoryPath = (): string => {
    return groupDevicePath() + historyPath();
  };

  const firmwarePath = (): string => {
    return "/firmware";
  };

  const usersPath = (): string => {
    return "/users";
  };

  const binsPath = (): string => {
    return "/bins";
  };

  const binPath = (): string => {
    return binsPath() + "/" + binID();
  };

  const teamsPath = (): string => {
    return "/teams";
  }

  const teamPath = (): string => {
    return "/teams" + "/" + teamKey();
  }

  const getBreadcrumbMap = (): { [key: string]: string } => {
    const { groupName, deviceName, componentName, reportTarget, binName } = props;
    const deviceLabel: string = deviceName ? deviceName : "Device " + deviceID();
    const componentLabel: string = componentName ? componentName : "Component " + componentID();
    const binLabel: string = binName ?? "Bin " + binID();
    const mineLabel: string = "Mine Site";
    const jobsiteLabel: string = "Job Site";
  
    let lastTeamName = props.teamName;
    if (props.teamName) {
      localStorage.setItem('lastTeamName-'+teamKey(), props.teamName);
    } else {
      lastTeamName = or(localStorage.getItem('lastTeamName-'+teamKey()), undefined);
    }

    return {
      [dashboardPath()]: "Dashboard",
      [groupsPath()]: "Groups",
      [groupPath()]: groupName ? groupName : "Group " + groupID(),
      [devicesPath()]: "Devices",
      [devicePath()]: deviceLabel,
      [minesPath()]: "Mines",
      [minePath()]: mineLabel,
      [jobsitesPath()]: "Job Sites",
      [jobsitePath()]: jobsiteLabel,
      [componentsPath()]: "Components",
      [componentPath()]: componentLabel,
      [securityPath()]: "Security",
      [reportPath()]: "Report " + reportIDShort() + (reportTarget ? " (" + reportTarget + ")" : ""),
      [groupDevicePath()]: deviceLabel,
      [groupComponentPath()]: componentLabel,
      [deviceHistoryPath()]: "History",
      [groupDeviceHistoryPath()]: "History",
      [firmwarePath()]: "Firmware",
      [usersPath()]: "Users",
      [binsPath()]: "Bins",
      [binPath()]: binLabel,
      [teamsPath()]: "Teams",
      [teamPath()]: lastTeamName ? lastTeamName : "Team " + teamKey(),
    };
  };

  const breadcrumbBlacklist = (): string[] => {
    return [dashboardPath(), componentsPath(), groupDevicesPath(), groupComponentsPath()];
  };

  const breadcrumbLinks = (): ReactNode[] => {
    const breadcrumbMap = getBreadcrumbMap();

    let links: ReactNode[] = [];
    let pathnames = location.pathname.split("/").filter((x: any) => x);
    const blacklist = breadcrumbBlacklist();

    if (pathnames.length < 1) {
      return [linkComponent("/", "Dashboard", true)];
    }
    
    if (prependPaths) pathnames.splice(pathnames.length - 1, 0, ...prependPaths);

    pathnames.forEach((value: any, index: any) => {
      
      const lastPath = index === pathnames.length - 1;
      const to = `/${pathnames.slice(0, index + 1).join("/")}`;
      let label = breadcrumbMap[to];
      let result = to.split("/").filter(str => str !== "");
      if (!label) {
        if (result.length > 1) {
          if (result[result.length - 1] !== "components") {
            label = breadcrumbMap["/" + result[result.length - 1]];
          }
        }
        if (!label && result[result.length - 1] !== "components") {
          label = breadcrumbMap["/" + result[result.length - 2] + "/" + result[result.length - 1]];
        }
      }

      if (!blacklist.includes(to) && label) {
        links.push(linkComponent(to, label, lastPath));
      }

      if (value === "support") {
        links.push(
          <Chip
            key={"support-chip"}
            variant={"filled"}
            label={
              <Typography variant="subtitle1" color="textPrimary">
                Support
              </Typography>
            }
            className={classes.chip}
          />
        )
      }

    });
    return links;
  };

  const linkComponent = (to: string, label: string, lastPath: boolean) => {
    return (
      <Tooltip title={label} key={"breadcrumb-"+to}>
        <Chip
          variant={lastPath ? "filled" : "outlined"}
          label={
            <LinkRouter
              color={lastPath ? "textPrimary" : "textSecondary"}
              variant="subtitle1"
              to={to}
              state={state}
              sx={{ '&:hover': { color: getThemeType() === "dark" ? 'white' : "black" }}}
              className={classes.textOverflow}>
              {label}
            </LinkRouter>
          }
          className={classes.chip}
        />
      </Tooltip>
    );
  };

  const localReload = () => {
    if (reload) {
      reload();
    } else {
    }
  };

  if (loading === true) return <Skeleton variant="text" width="100%" />;

  return (
    <Box 
      display="flex"
      padding={props.padding}
      paddingLeft={props.paddingLeft}
      paddingRight={props.paddingRight}
      paddingTop={props.paddingTop}
      paddingBottom={props.paddingBottom}
    >
      <Breadcrumbs
        maxItems={isMobile ? 1 : 3}
        itemsBeforeCollapse={0}
        aria-label="Location Breadcrumb">
        {breadcrumbLinks()}
      </Breadcrumbs>
      {reload && (
        <IconButton
          color="inherit"
          size="small"
          style={{ marginLeft: theme.spacing(1) }}
          onClick={localReload}>
          <Replay />
        </IconButton>
      )}
    </Box>
  );
}
