import React from 'react';

import type { SxProps } from '@mui/joy/styles/types';
import { Box, Button, Step, stepClasses, StepIndicator, stepIndicatorClasses, Stepper, Typography } from '@mui/joy';
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
import ArrowForwardRoundedIcon from '@mui/icons-material/ArrowForwardRounded';
import CheckRoundedIcon from '@mui/icons-material/CheckRounded';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';

import { ScaledTextBlockRenderer } from '~/modules/blocks/ScaledTextBlockRenderer';

import { BigAgiSquircleIcon } from '~/common/components/icons/big-agi/BigAgiSquircleIcon';
import { ChatBeamIcon } from '~/common/components/icons/ChatBeamIcon';
import { ShortcutKey, useGlobalShortcuts } from '~/common/components/shortcuts/useGlobalShortcuts';
import { animationTextShadowLimey } from '~/common/util/animUtils';
import { hasGoogleAnalytics, sendGAEvent } from '~/common/components/3rdparty/GoogleAnalytics';
import { useIsMobile } from '~/common/components/useMatchMedia';
import { useUIContentScaling } from '~/common/stores/store-ui';


// configuration
const colorButtons = 'neutral' as const;
const colorStepper = 'neutral' as const;


// Steps - the top stepper

interface ExplainerStep {
  stepDigits: string,
  stepName: string,
}

const stepSequenceSx: SxProps = {
  // width: '100%',
  [`& .${stepClasses.completed}::after`]: {
    bgcolor: `${colorStepper}.500`,
  },
  [`& .${stepClasses.active} .${stepIndicatorClasses.root}`]: {
    borderColor: `${colorStepper}.500`,
  },
  [`& .${stepClasses.root}:has(+ .${stepClasses.active})::after`]: {
    color: `${colorStepper}.500`,
    backgroundColor: 'transparent',
    backgroundImage: 'radial-gradient(currentColor 2px, transparent 2px)',
    backgroundSize: '7px 7px',
    backgroundPosition: 'center left',
  },
};

const buttonBaseSx: SxProps = {
  justifyContent: 'space-between',
  minHeight: '2.5rem',
  minWidth: 120,
};

const buttonNextSx: SxProps = {
  ...buttonBaseSx,
  boxShadow: `0 8px 24px -4px rgb(var(--joy-palette-${colorButtons}-mainChannel) / 20%)`,
  minWidth: 180,
};


function AllStepsStepper(props: {
  steps: ExplainerStep[],
  activeIndex: number,
  isMobile: boolean,
  onStepClicked: (stepIndex: number) => void,
}) {
  return (
    <Stepper sx={stepSequenceSx}>
      {props.steps.map(((step, stepIndex) => {
        const completed = props.activeIndex > stepIndex;
        const active = props.activeIndex === stepIndex;
        return (
          <Step
            key={'step-' + stepIndex}
            orientation='vertical'
            completed={completed}
            active={active}
            indicator={
              <StepIndicator
                variant={(completed || active) ? 'solid' : 'outlined'}
                color={colorStepper}
                onClick={() => props.onStepClicked(stepIndex)}
                sx={{ cursor: 'pointer' }}
              >
                {completed ? <CheckRoundedIcon sx={{ fontSize: 'md' }} /> : active ? <KeyboardArrowDownIcon sx={{ fontSize: 'lg' }} /> : undefined}
              </StepIndicator>
            }
          >
            <Typography
              fontSize={props.isMobile ? 'sm' : undefined}
              fontWeight='xl'
              endDecorator={
                step.stepName && <Typography fontSize='sm' fontWeight='normal' sx={{ mr: 0.5 }}>{step.stepName}</Typography>
              }
            >{step.stepDigits ?? null}</Typography>
          </Step>
        );
      }))}
    </Stepper>
  );
}


// The Explainer - Carousel of pages

export interface ExplainerPage extends ExplainerStep {
  titlePrefix?: string,
  titleSquircle?: boolean,
  titleSpark?: string,
  titleSuffix?: string,
  mdContent: string
}

export function ExplainerCarousel(props: {
  explainerId: string,
  steps: ExplainerPage[],
  footer?: React.ReactNode,
  noStepper?: boolean,
  onFinished: () => any,
}) {

  // state
  const [stepIndex, setStepIndex] = React.useState(0);

  // external state
  const isMobile = useIsMobile();
  const contentScaling = useUIContentScaling();

  // derived state
  const { onFinished } = props;
  const isFirstPage = stepIndex === 0;
  const isLastPage = stepIndex === props.steps.length - 1;
  const activeStep = props.steps[stepIndex] ?? null;

  // handlers

  const mdText = activeStep?.mdContent ?? null;

  const handlePrevPage = React.useCallback(() => {
    setStepIndex(step => step > 0 ? step - 1 : step);
  }, []);

  const handleNextPage = React.useCallback(() => {
    if (isLastPage) {
      hasGoogleAnalytics && sendGAEvent('event', 'tutorial_complete', { tutorial_id: props.explainerId });
      onFinished();
    } else
      setStepIndex(step => step < props.steps.length - 1 ? step + 1 : step);
  }, [isLastPage, onFinished, props.explainerId, props.steps.length]);

  React.useEffect(() => {
    const recordTutorialBegun = () => {
      hasGoogleAnalytics && sendGAEvent('event', 'tutorial_begin', { tutorial_id: props.explainerId });
    };

    const timeoutId = setTimeout(recordTutorialBegun, 500);
    return () => clearTimeout(timeoutId);
  }, [props.explainerId]);


  useGlobalShortcuts('ExplainerCarousel', React.useMemo(() => [
    { key: ShortcutKey.Left, action: handlePrevPage },
    { key: ShortcutKey.Right, action: handleNextPage },
  ], [handleNextPage, handlePrevPage]));


  // [effect] restart from 0 if steps change
  // React.useEffect(() => {
  //   setStepIndex(0);
  // }, [props.steps]);


  return (
    <Box sx={{
      flex: 1,
      mx: 'auto',
      width: { sm: '92%', md: '86%' }, /* Default to 80% width */
      maxWidth: '820px',    /* But don't go over 900px */

      // content
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'space-evenly',
      gap: 2,
    }}>


      {/* Page Title */}
      <Typography
        level='h1'
        component='h1'
        sx={{
          fontSize: isMobile ? '2rem' : '2.5rem',
          fontWeight: 'md',
          textAlign: 'center',
          whiteSpace: 'balance',
        }}>
        {activeStep?.titlePrefix}{' '}
        {!!activeStep?.titleSquircle && <BigAgiSquircleIcon inverted sx={{ color: 'white', fontSize: isMobile ? '1.55rem' : '2.04rem', borderRadius: 'md' }} />}
        {!!activeStep?.titleSquircle && '-'}
        {!!activeStep?.titleSpark && <Box component='span' sx={{
          fontWeight: 'lg',
          color: 'neutral.softColor',
          animation: `${animationTextShadowLimey} 5s infinite`,
          /*, animation: `${animationTextShadowLimey} 15s linear infinite`*/
        }}>
          {activeStep.titleSpark}
        </Box>}{activeStep?.titleSuffix}
      </Typography>


      {/* Page Message */}
      <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1 }}>

        {/* Main Card with the markdown body */}
        {!!mdText && (
          <Box sx={{
            minHeight: '24rem',
            backgroundColor: 'background.popup',
            borderRadius: 'lg',
            boxShadow: '0 60px 32px -60px rgb(var(--joy-palette-primary-darkChannel) / 0.14)',
            mb: 2,
            px: { xs: 1, md: 2 },
            py: 2,

            // customize the embedded GitHub Markdown for transparent images
            ['.markdown-body img']: {
              '--color-canvas-default': 'transparent!important',
            },
          }}>
            <ScaledTextBlockRenderer
              text={mdText}
              contentScaling={contentScaling /* was: 'md' */}
              textRenderVariant='markdown'
            />
          </Box>
        )}

        {/* Advance Button */}
        <Button
          variant='solid'
          color={colorButtons}
          onClick={handleNextPage}
          endDecorator={isLastPage ? <ChatBeamIcon /> : <ArrowForwardRoundedIcon />}
          sx={buttonNextSx}
        >
          {isLastPage ? 'Start' : 'Next'}
        </Button>

        {/* Back Button */}
        <Button
          variant='plain'
          color={colorButtons}
          disabled={isFirstPage}
          onClick={handlePrevPage}
          startDecorator={<ArrowBackRoundedIcon />}
          sx={buttonBaseSx}
        >
          Previous
        </Button>

      </Box>


      {/* All Steps */}
      {props.noStepper ? null : (
        <AllStepsStepper
          steps={props.steps}
          activeIndex={stepIndex}
          isMobile={isMobile}
          onStepClicked={setStepIndex}
        />
      )}


      {/* Final words of wisdom (also perfect for centering the other components) */}
      {props.footer}

    </Box>
  );
}