import styled from '@emotion/styled';
import clsx from 'clsx';
import { PropsWithChildren, useCallback, useRef, useState } from 'react';
import { twMerge } from 'tailwind-merge';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import SpinnerSVG from '@/components/svg/SpinnerSVG';
import { Tooltip } from '@/components/tooltip/Tooltip';
import { CreateIcon, TrashIcon } from '@/icons';
import {
  TransactionLogger,
  createTransactionLogger,
} from '@/logging/logWebUserEvent';

import useCreateFormLogging from '../../v2/useCreateFormLogging';

type WrapperProps = {
  className?: string;
};

const Wrapper = ({
  className = '',
  children,
}: PropsWithChildren<WrapperProps>) => (
  <div
    className={twMerge(
      'flex items-center justify-stretch gap-4 bg-background-primary p-4',
      className
    )}
  >
    {children}
  </div>
);

const CreateButton = styled(Button, {
  shouldForwardProp: (prop) => prop !== 'justClicked',
})<{ justClicked: boolean }>`
  position: relative;
  overflow: hidden;
  transform: scale(${(props) => (props.justClicked ? '0.98' : '1')});
  transition: ${({ justClicked }) =>
    justClicked ? 'transform 0s' : 'transform 0.2s ease-out'};
`;

const Overlay = styled.div<{ isVisible: boolean }>`
  position: absolute;
  top: -15px;
  left: -15px;
  right: -15px;
  bottom: -15px;
  border-radius: 50px;
  box-shadow: inset 0 0 30px rgba(255, 255, 255, 1);
  background: rgba(255, 255, 255, 0.25);
  opacity: ${(props) => (props.isVisible ? 1 : 0)};
  transition: ${({ isVisible }) =>
    isVisible ? 'opacity 0s' : 'opacity 0.2s ease-out'};
  pointer-events: none;
  z-index: 1;
`;

export default function CreateFooter({
  className,
  canClear,
  onCreateClick,
  onClearClick,
  isGenerating,
  generateBlockingErrorMessage,
  buttonText = 'Create',
  isOutOfCredits = false,
  onMobileCreate,
}: {
  className?: string;
  canClear: boolean;
  onCreateClick: (transactionLogger: TransactionLogger) => void;
  onClearClick: () => void;
  isGenerating: boolean;
  generateBlockingErrorMessage?: string | null;
  buttonText?: string;
  isOutOfCredits?: boolean;
  onMobileCreate?: () => void;
}) {
  const [justClicked, setJustClicked] = useState(false);
  const generateDisabled = !!generateBlockingErrorMessage || isOutOfCredits;
  const finalButtonText = isOutOfCredits ? 'Out of Credits' : buttonText;

  const getTooltipContent = useCallback(() => {
    if (generateBlockingErrorMessage) return generateBlockingErrorMessage;
    if (isOutOfCredits) return 'Upgrade to Pro';
    return '';
  }, [generateBlockingErrorMessage, isOutOfCredits]);

  const getButtonVariant = useCallback(() => {
    if (isOutOfCredits) return ButtonVariant.Aura;
    if (!generateDisabled) return ButtonVariant.Aura;
    return ButtonVariant.Standard;
  }, [generateDisabled, isOutOfCredits]);

  const getButtonClassName = useCallback(() => {
    let baseClass = 'flex-grow p-3 transition-all duration-200';

    if (generateDisabled) {
      baseClass += ' bg-background-tertiary text-foreground-inactive';
    }

    if (isOutOfCredits) {
      baseClass +=
        ' bg-accent-error/10 border-accent-error/20 text-accent-error hover:bg-accent-error/20';
    }

    return baseClass;
  }, [generateDisabled, isOutOfCredits]);

  const justClickedTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const handleCreateClick = useCallback(
    (transactionLogger: TransactionLogger) => {
      if (justClickedTimeoutRef.current) {
        clearTimeout(justClickedTimeoutRef.current);
        justClickedTimeoutRef.current = null;
      }
      setJustClicked(true);
      justClickedTimeoutRef.current = setTimeout(() => {
        setJustClicked(false);
        justClickedTimeoutRef.current = null;
      }, 200);

      onCreateClick(transactionLogger);
      onMobileCreate?.();
    },
    [onCreateClick, onMobileCreate]
  );

  const { logGenerateButtonClicked } = useCreateFormLogging();

  return (
    <Wrapper className={className}>
      <Button
        icon={<TrashIcon className='h-4 w-4' />}
        aria-label='Clear all form inputs'
        className={clsx('p-4 transition-all duration-300 ease-in-out', {
          'opacity-0': !canClear,
          '-ml-16': !canClear,
        })}
        shape={ButtonShape.Pill}
        size={ButtonSize.Large}
        onClick={onClearClick}
        disabled={!canClear}
      />
      <Tooltip
        label={getTooltipContent()}
        placement='top'
        isDisabled={!getTooltipContent()}
      >
        <CreateButton
          justClicked={justClicked}
          disabled={generateDisabled}
          className={getButtonClassName()}
          variant={getButtonVariant()}
          shape={ButtonShape.Pill}
          size={ButtonSize.Large}
          aria-label='Create song'
          onClick={() => {
            const transactionLogger = createTransactionLogger();

            logGenerateButtonClicked(transactionLogger);
            handleCreateClick(transactionLogger);
          }}
        >
          <Overlay isVisible={justClicked} />
          {isGenerating ? (
            <SpinnerSVG className='h-5 w-5' />
          ) : (
            <CreateIcon className='h-5 w-5' />
          )}
          {finalButtonText}
        </CreateButton>
      </Tooltip>
    </Wrapper>
  );
}
