import styled from '@emotion/native';
import { ViewProps as ViewPropsBase } from 'react-native';
import { variant } from 'styled-system';
import { ColorName, ViewStyle } from '@emotion/react';
import { Container, Row, Col } from 'components/layout';
import { CheckMark, CloseThick } from 'icons';
import { Text } from 'components/text';
import { Fab, FabColorVariant } from 'components/fab';
import { IconColorVariantsType } from 'icons/types';
import { capitalize } from 'utils/text';
import { MotiView } from 'moti';
import { useReactiveVar } from '@apollo/client';
import { AlertOptionsVar, alertOptionsVar } from 'state-management/alert';
import { Visible } from 'components/visible';
import { metrics } from 'config';
import { useResponsiveLayout, useTheme } from 'hooks';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { FC, useCallback, useEffect, useRef, useState } from 'react';
const { Z_INDEX, STYLES, DURATION } = metrics;

const variants: Record<AlertVariant, ViewStyle> = {
  success: {
    borderColor: 'success',
    backgroundColor: 'success-02',
  },
  'success-dark': {
    borderColor: 'success',
    backgroundColor: 'success-08',
  },
  info: {
    borderColor: 'grey-02',
    backgroundColor: 'base-01',
  },
  'info-dark': {
    borderColor: 'grey-02',
    backgroundColor: 'base-01',
  },
  warning: {
    borderColor: 'primary',
    backgroundColor: 'primary-02',
  },
  'warning-dark': {
    borderColor: 'primary',
    backgroundColor: 'primary-08',
  },
  error: {
    borderColor: 'secondary',
    backgroundColor: 'secondary-02',
  },
  'error-dark': {
    borderColor: 'secondary',
    backgroundColor: 'secondary-08',
  },
};

const iconVariants: Record<AlertLightVariant, IconColorVariantsType> = {
  success: 'success',
  info: 'body',
  warning: 'primary',
  error: 'secondary',
};

export const LocalAlert = styled(Container)<LocalAlertProps>(
  variant({
    variants,
  }),
  variant({
    prop: 'shapeVariant',
    variants: {
      default: {
        p: 'xs',
        borderRadius: 'button',
        borderWidth: 1,
      },
    },
  })
);

LocalAlert.defaultProps = {
  shapeVariant: 'default',
};

export const AlertWrapper: FC<AlertWrapperProps> = ({
  alertVariantLocal,
  leftElementVar,
  iconColorVariant,
  contentVar,
  messageVar,
  variantVar,
  textColor,
  titleVar,
  closeAlert,
}) => {
  const { activeThemeMode } = useTheme();
  const closeColor = activeThemeMode === 'dark' ? 'white' : 'body';

  return (
    <Container backgroundColor="base" borderRadius={STYLES.radius.card}>
      <LocalAlert variant={alertVariantLocal}>
        <Row justifyContent="space-between">
          <Col mr="xs">{leftElementVar || <CheckMark colorVariant={iconColorVariant} />}</Col>
          <Col flexGrow={1} flexShrink={1}>
            {contentVar || (
              <>
                <Text variant="title">{capitalize(variantVar || titleVar)}</Text>
                <Text flexShrink={1} variant="body" color={textColor} mt="3xs">
                  {messageVar}
                </Text>
              </>
            )}
          </Col>
          <Col width={30}>
            <Fab
              position="absolute"
              top={-10}
              right={-10}
              variant="plain"
              sizeVariant="medium"
              colorVariant="transparent"
              hoverColorVariant={variantVar as FabColorVariant}
              onPress={closeAlert}
              centerElement={<CloseThick strokeWidth={5} colorVariant={closeColor} />}
            />
          </Col>
        </Row>
      </LocalAlert>
    </Container>
  );
};

export const Alert: React.FC = ({}) => {
  const [remainingTime, setRemainingTime] = useState(DURATION.alertStayTime);

  const {
    marginTopVar,
    messageVar,
    contentVar,
    leftElementVar,
    isOpenVar,
    variantVar,
  }: AlertOptionsVar = useReactiveVar(alertOptionsVar);
  const { isMobile, isTablet } = useResponsiveLayout();
  const { top } = useSafeAreaInsets();
  const { activeThemeMode } = useTheme();

  const timerRef = useRef<any>(null);

  const iconColorVariant = activeThemeMode === 'dark' ? 'white' : iconVariants[variantVar];
  const textColor = activeThemeMode === 'dark' ? 'white' : 'body';
  const marginTop = Number(marginTopVar) > 0 ? marginTopVar : top + STYLES.topBarHeight;
  const marginTopBefore = Number(marginTop) + 100;
  const tabletLeftRight = isTablet ? '25%' : '30%';
  const leftRight = isMobile ? 10 : tabletLeftRight;
  const alertVariantLocal =
    activeThemeMode === 'dark' ? (`${variantVar}-dark` as AlertDarkVariant) : variantVar;

  const resetTimer = useCallback(() => {
    setRemainingTime(DURATION.alertStayTime);
  }, []);

  const startTimer = useCallback(() => {
    timerRef.current = setInterval(() => {
      setRemainingTime((time) => time - 1);
    }, 1000);
    return () => {
      clearInterval(timerRef.current);
      resetTimer();
    };
  }, [resetTimer]);

  const closeAlert = useCallback(() => {
    resetTimer();
    alertOptionsVar({ isOpenVar: false, variantVar: 'info' });
    clearInterval(timerRef.current);
  }, [resetTimer]);

  useEffect(() => {
    if (remainingTime <= 0) {
      resetTimer();
      alertOptionsVar({ isOpenVar: false, variantVar: 'info' });
      clearInterval(timerRef.current);
    }
  }, [remainingTime, resetTimer]);

  useEffect(() => {
    if (isOpenVar) {
      startTimer();
    }
  }, [isOpenVar, startTimer]);

  return (
    <Visible if={isOpenVar}>
      <MotiView
        animate={{
          top: marginTop,
          opacity: 1,
        }}
        from={{
          top: -marginTopBefore,
          opacity: 1,
        }}
        style={{
          position: 'absolute',
          left: leftRight,
          right: leftRight,
          zIndex: Z_INDEX.alert,
        }}
      >
        <AlertWrapper
          closeAlert={closeAlert}
          alertVariantLocal={alertVariantLocal}
          variantVar={variantVar}
          leftElementVar={leftElementVar}
          textColor={textColor}
          contentVar={contentVar}
          messageVar={messageVar}
          iconColorVariant={iconColorVariant}
        />
      </MotiView>
    </Visible>
  );
};

export type AlertVariant = AlertLightVariant | AlertDarkVariant;

export type AlertLightVariant = 'success' | 'info' | 'warning' | 'error';

export type AlertDarkVariant = 'success-dark' | 'info-dark' | 'warning-dark' | 'error-dark';

export interface LocalAlertProps extends ViewPropsBase {
  variant?: AlertVariant;
  shapeVariant?: 'default';
  body?: string | number;
}
export interface AlertWrapperProps {
  alertVariantLocal: AlertVariant;
  leftElementVar?: JSX.Element;
  contentVar?: JSX.Element;
  titleVar?: string;
  messageVar?: string;
  variantVar: AlertLightVariant;
  iconColorVariant: ColorName;
  textColor: ColorName;
  closeAlert: () => void;
}
