import styled from '@emotion/styled';
import React, { useCallback } from 'react';

import useHasStudioContext from '@/components/studio/useHasStudioContext';
import CaretDownIcon from '@/icons/generated/CaretDownIcon';

import ExpandableWrapper from './ExpandableWrapper';
import PopoutWrapper from './PopoutWrapper';
import { bigButton, bigSpace, smallSpace } from './themes';

interface CreateCardProps {
  disabled?: boolean;
  header?: React.ReactNode;
  title?: React.ReactNode;
  children: React.ReactNode;
  headerContent?: React.ReactNode;
  expanded?: boolean;
  setExpanded?: React.Dispatch<React.SetStateAction<boolean>>;
  collapsible?: boolean;
  headerContentHidden?: boolean;
  className?: string;
  style?: React.CSSProperties;
  popout?: boolean;
  nested?: boolean;
  popoutRounded?: boolean;
  transparentBackground?: boolean;
}

const Header = styled.div`
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: ${bigSpace}px;
  min-height: ${(props) => bigButton(props) + 2 * bigSpace(props)}px;
  transition:
    height 0.3s ease-in-out,
    opacity 0.3s ease-in-out;
  overflow: hidden;
  gap: ${smallSpace}px;
  color: var(--color-foreground-primary);
`;

// not position: relative for now.
// this lets us make the title element full width when the header content is hidden.
const HeaderLeft = styled.div`
  display: flex;
  align-items: center;
  gap: ${smallSpace}px;
  font-size: 14px;
  cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
  user-select: none;
  outline: none;
  flex-grow: 1;
  overflow: hidden;
  &:before {
    content: '';
    display: ${({ onClick }) => (onClick ? 'block' : 'none')};
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
  }
`;

const CaretWrapper = styled.span<{ expanded: boolean; offLeft?: boolean }>`
  display: flex;
  align-items: center;
  transition:
    transform 0.2s ease-in-out,
    margin-right 0.2s ease-in-out,
    opacity 0.3s ease-in-out;
  transform: rotate(${({ expanded }) => (expanded ? '0deg' : '-90deg')});
  margin-right: ${(props) =>
    props.offLeft ? -1 * (2.5 * smallSpace(props) + 6) : -4}px;
  opacity: ${({ offLeft }) => (offLeft ? 0 : 1)};
`;

const HeaderContent = styled.div<{ contentHidden: boolean }>`
  display: flex;
  align-items: center;
  gap: ${smallSpace}px;
  transition:
    opacity 0.3s ease-in-out,
    opacity 0.3s ease-in-out,
    transform 0.3s ease-in-out,
    opacity 0.3s ease-in-out;
  opacity: ${({ contentHidden }) => (contentHidden ? 0 : 1)};
  pointer-events: ${({ contentHidden }) => (contentHidden ? 'none' : 'auto')};
`;

export const CreateCard: React.FC<CreateCardProps> = ({
  disabled = false,
  title,
  children,
  headerContent,
  expanded = true,
  setExpanded,
  collapsible = false,
  headerContentHidden = false,
  className,
  style,
  popout = false,
  nested = false,
  transparentBackground = false,
}) => {
  const finalExpanded = expanded && !disabled;
  const hasStudioContext = useHasStudioContext();

  // Keyboard accessibility
  const handleHeaderKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (!collapsible) return;
      if (e.key === 'Enter' || (!hasStudioContext && e.key === ' ')) {
        e.preventDefault();
        setExpanded?.((prev) => !prev);
      }
    },
    [collapsible, setExpanded, hasStudioContext]
  );

  const handleHeaderClick = useCallback(() => {
    if (collapsible) {
      setExpanded?.((prev) => !prev);
    }
  }, [collapsible, setExpanded]);

  return (
    <PopoutWrapper
      popout={popout}
      nested={nested}
      className={className}
      style={style}
      transparentBackground={transparentBackground}
    >
      {title && (
        <Header>
          <HeaderLeft
            onClick={
              !collapsible || popout || disabled ? undefined : handleHeaderClick
            }
            tabIndex={collapsible ? 0 : -1}
            role={collapsible ? 'button' : undefined}
            aria-expanded={collapsible ? finalExpanded : undefined}
            onKeyDown={handleHeaderKeyDown}
          >
            {collapsible ? (
              <CaretWrapper
                expanded={finalExpanded}
                offLeft={popout || disabled}
              >
                <CaretDownIcon
                  className={`h-5 w-5 ${popout ? 'opacity-50' : ''}`}
                />
              </CaretWrapper>
            ) : (
              <div className='w-1' />
            )}
            {title}
          </HeaderLeft>
          {headerContent && (
            <HeaderContent contentHidden={headerContentHidden}>
              {headerContent}
            </HeaderContent>
          )}
        </Header>
      )}
      <ExpandableWrapper
        expanded={finalExpanded}
        collapsible={collapsible}
        disabled={disabled}
      >
        {children}
      </ExpandableWrapper>
    </PopoutWrapper>
  );
};

export default CreateCard;
