import Joyride, { Step, CallBackProps, STATUS, TooltipRenderProps, Locale, ACTIONS, EVENTS } from "react-joyride";
import {
  Button,
  Card,
  CardContent,
  CardHeader,
  CardActions,
  Grid2 as Grid,
  MobileStepper,
  Tooltip,
  IconButton,
  Theme,
  useTheme,
} from "@mui/material";
import { KeyboardArrowLeft, KeyboardArrowRight, Close as CloseIcon } from "@mui/icons-material";
import classNames from "classnames";
import { grey } from "@mui/material/colors";
import { makeStyles } from "@mui/styles";
import { CSSProperties } from "react";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    stepContainer: {
      width: "60vw",
      [theme.breakpoints.only("sm")]: {
        width: "50vw"
      },
      [theme.breakpoints.only("md")]: {
        width: "40vw"
      },
      [theme.breakpoints.only("lg")]: {
        width: "30vw"
      },
      [theme.breakpoints.only("xl")]: {
        width: "20vw"
      }
    },
    spacing: {
      padding: theme.spacing(1),
      [theme.breakpoints.up("sm")]: {
        padding: theme.spacing(2)
      }
    },
    stepper: {
      width: "100%"
    }
  })
});

export interface TourStep extends Step {
  onNext?: () => void; // Define onNext as an optional function
}

const StepContainer = (props: TooltipRenderProps, numSteps: number, skip: () => void) => {
  const {
    continuous,
    index,
    step,
    backProps,
    isLastStep,
    closeProps,
    primaryProps,
    tooltipProps
  } = props;
  const theme = useTheme();
  const classes = useStyles();

  return (
    <Card {...tooltipProps} className={classes.stepContainer}>
      <CardHeader
        title={step.title}
        action={
          <Tooltip title="Skip Tutorial">
            <IconButton aria-label="Skip Tutorial" onClick={skip}>
              <CloseIcon />
            </IconButton>
          </Tooltip>
        }
        className={classes.spacing}
      />

      {step.content && <CardContent className={classes.spacing}>{step.content}</CardContent>}

      {!step.hideFooter &&
        (continuous ? (
          <MobileStepper
            className={classNames(classes.stepper, classes.spacing)}
            variant="text"
            steps={numSteps}
            position="static"
            activeStep={index}
            backButton={
              <Button size="small" {...backProps} disabled={index === 0}>
                {theme.direction === "rtl" ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
                Back
              </Button>
            }
            nextButton={
              <Button size="small" {...primaryProps}>
                {isLastStep ? "Finish" : "Next"}
                {theme.direction === "rtl" ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
              </Button>
            }
          />
        ) : (
          !step.hideCloseButton && (
            <CardActions>
              <Grid container justifyContent="flex-end">
                <Button size="small" {...closeProps}>
                  Close
                </Button>
              </Grid>
            </CardActions>
          )
        ))}
    </Card>
  );
};

interface Props {
  run: boolean;
  steps: TourStep[];
  endTourCallback: () => void;
  spotlightStyle?: CSSProperties,
  setStepIndex?: React.Dispatch<React.SetStateAction<number>>,
}

export default function Tour(props: Props) {
  const { run, steps, endTourCallback, setStepIndex, spotlightStyle } = props;
  const theme = useTheme();

  const handleTourCallback = (data: CallBackProps) => {
    const { action, index, status, type } = data;
    const finishedStatuses: string[] = [STATUS.FINISHED, STATUS.SKIPPED];

    if (setStepIndex) setStepIndex(index)

    if (action === ACTIONS.NEXT && type === EVENTS.STEP_AFTER) {
      // Safely access the step and call onNext if it exists
      const currentStep = steps[index];
      if (currentStep.onNext) {
        currentStep.onNext();
      }
    }

    if (finishedStatuses.includes(status)) {
      endTourCallback();
    }
  };

  return (
    <Joyride
      run={run}
      steps={steps}
      continuous
      scrollToFirstStep={true}
      showProgress={true}
      showSkipButton={true}
      callback={handleTourCallback}
      tooltipComponent={props => StepContainer(props, steps.length, endTourCallback)}
      locale={{ back: "Back", close: "Close", last: "Done", next: "Next", skip: "Skip" } as Locale}
      styles={{
        options: {
          arrowColor: theme.palette.mode === "light" ? grey["100"] : grey["800"],
          backgroundColor: theme.palette.background.default,
          overlayColor: "rgba(0, 0, 0, 0.5)",
          primaryColor: theme.palette.primary.main,
          textColor: theme.palette.text.primary,
          zIndex: theme.zIndex.modal
        },
        spotlight: {
          ...spotlightStyle
        }
      }}
    />
  );
}
