import styled from '@emotion/styled';
import { capitalize } from 'lodash-es';
import React, { Dispatch, SetStateAction } from 'react';

import Button, { ButtonShape, ButtonVariant } from '@/components/button/Button';
import {
  ContextMenuItem,
  ContextMenuItemMainText,
  ContextMenuItemSubtext,
  ContextMenuTrigger,
} from '@/components/contextMenu/ContextMenu';
import PanelButton from '@/components/studio/PanelButton';
import Tag from '@/components/tag/Tag';
import {
  CheckIcon,
  CloseIcon,
  CreateIcon,
  ExtendLeftIcon,
  ExtendRightIcon,
  TriangleDownIcon,
} from '@/icons';
import { components } from '@/lib/gen';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { CREATE_VERSION } from '@/utils/constants';

import { CreateModes } from '../../v2/types';
import AnimatedTabs, { Option } from './AnimatedTabs';
import CreditsCounter from './CreditsCounter';
import { useModelUpsell } from './useModelUpsell';

export type ExternalModelTypeSchema =
  components['schemas']['ExternalModelTypeSchema'];

interface CreateHeaderProps<ModeType extends string> {
  creditsRemaining: number | null;
  onClickCredits?: () => void;
  creditsHref?: string;
  modeOptions: Option<ModeType>[];
  mode: ModeType;
  modelTypeOptions: ExternalModelTypeSchema[];
  modelType: string;
  setMode: Dispatch<SetStateAction<ModeType>>;
  setModelType: Dispatch<SetStateAction<string>>;
  onOutOfCreditsClick?: () => void;
  showModeSwitcher?: boolean;
}

// reused for WorkspaceHeader, WorkspaceListHeader, and StudioTimelineHeader
export const HeaderContainer = styled.div<{
  borderBottom?: boolean;
  slim?: boolean;
  center?: boolean;
}>`
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: ${({ center }) => (center ? 'center' : 'space-between')};
  width: 100%;
  max-width: 100%;
  padding: 0 ${({ slim }) => (slim ? '4px' : '16px')};
  height: ${({ slim }) => (slim ? '48px' : '68px')};
  border-bottom: ${({ borderBottom }) =>
    borderBottom ? '1px solid var(--color-border-primary)' : 'none'};
  flex-shrink: 0;

  @media (max-width: 768px) {
    height: ${({ slim }) => (slim ? '48px' : '56px')};
  }
`;

const LeftSection = styled.div<{ shrinkable?: boolean }>`
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: ${({ shrinkable }) => (shrinkable ? 'auto' : '100px')};
  flex-shrink: ${({ shrinkable }) => (shrinkable ? 1 : 0)};
`;

const CenterSection = styled.div`
  display: flex;
  align-items: center;
  flex: 1;
  justify-content: center;
`;

const RightSection = styled.div<{ shrinkable?: boolean }>`
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  min-width: ${({ shrinkable }) => (shrinkable ? 'auto' : '100px')};
  flex-shrink: ${({ shrinkable }) => (shrinkable ? 1 : 0)};
`;

export const ModelMenuContents: React.FC<{
  options: ExternalModelTypeSchema[];
  activeId: string;
  onSelect: (model: ExternalModelTypeSchema) => void;
}> = ({ options, activeId, onSelect }) => (
  <div className='flex max-h-[calc(100vh-20px)] flex-col overflow-y-auto sm:max-h-[400px]'>
    {options.map((model) => (
      <ContextMenuItem
        key={model.id || model.external_key}
        className={
          activeId === model.external_key ? 'bg-background-glass-thick' : ''
        }
        onClick={() => {
          onSelect(model);
        }}
      >
        <span className='flex flex-col gap-0 pb-1'>
          <ContextMenuItemMainText>
            {model.name}{' '}
            {model.badges?.map((b) => (
              <Tag key={b}>{capitalize(b)}</Tag>
            ))}{' '}
            {activeId === model.external_key && (
              <span className='-mb-[1px] ml-1 inline-block rounded-lg bg-foreground-primary text-background-primary'>
                <CheckIcon className='h-3 w-3' />
              </span>
            )}
          </ContextMenuItemMainText>
          <ContextMenuItemSubtext
            style={{ whiteSpace: 'normal', lineHeight: 1.4 }}
            className='max-w-[180px] text-left'
          >
            {model.description}
          </ContextMenuItemSubtext>
        </span>
      </ContextMenuItem>
    ))}
  </div>
);

function CreateHeader<ModeType extends string>({
  creditsRemaining,
  onClickCredits,
  creditsHref,
  modeOptions,
  mode,
  modelTypeOptions,
  modelType,
  setMode,
  setModelType,
  onOutOfCreditsClick,
  showModeSwitcher = true,
}: CreateHeaderProps<ModeType>) {
  const model =
    modelTypeOptions.find((m) => m.external_key === modelType) ||
    modelTypeOptions[0];
  const modelUpsell = useModelUpsell();

  return (
    <HeaderContainer borderBottom>
      <LeftSection>
        {creditsRemaining !== null && (
          <CreditsCounter
            creditsRemaining={creditsRemaining}
            onClick={onClickCredits}
            href={creditsHref}
            onOutOfCreditsClick={onOutOfCreditsClick}
          />
        )}
      </LeftSection>
      <CenterSection>
        {mode === CreateModes.ADJUST_SPEED ? (
          <div className='text-xl font-semibold text-foreground-primary'>
            Adjust Speed
          </div>
        ) : showModeSwitcher ? (
          <AnimatedTabs
            options={modeOptions}
            value={mode}
            onChange={(option) => {
              logWebUserEvent({
                actionName: 'CustomToggleClicked',
                context: {
                  stateBefore: modeOptions[0]?.value === mode ? 'on' : 'off',
                  stateAfter:
                    modeOptions[0]?.value === option.value ? 'on' : 'off',
                  createVersion: CREATE_VERSION,
                },
              });
              setMode(option.value);
            }}
          />
        ) : null}
      </CenterSection>
      <RightSection>
        {mode === CreateModes.ADJUST_SPEED ? (
          <Button
            variant={ButtonVariant.Secondary}
            shape={ButtonShape.Pill}
            className='h-[40px] text-[12px]'
            onClick={() => setMode(modeOptions[modeOptions.length - 1].value)}
            icon={<CloseIcon className='h-4 w-4' />}
          />
        ) : (
          <ContextMenuTrigger
            placement='bottom-left'
            ButtonComponent={(props) => (
              <Button
                variant={ButtonVariant.Secondary}
                shape={ButtonShape.Pill}
                className='h-[40px] text-[12px]'
                {...props}
              >
                {model?.name}
                <TriangleDownIcon className='-ml-1 h-4 w-4' />
              </Button>
            )}
            ContentsComponent={() => (
              <ModelMenuContents
                options={modelTypeOptions}
                activeId={modelType}
                onSelect={(model) => {
                  const isUpsellTriggered = modelUpsell.checkForUpsell(
                    model.external_key
                  );
                  if (!isUpsellTriggered) {
                    setModelType(model.external_key);
                  }
                }}
              />
            )}
          />
        )}
      </RightSection>
    </HeaderContainer>
  );
}

interface StudioCreateHeaderProps<ModeType extends string> {
  modeOptions?: Option<ModeType>[];
  mode: ModeType;
  setMode: Dispatch<SetStateAction<ModeType>>;
  setModelType: Dispatch<SetStateAction<string>>;
  expanded: boolean;
  setExpanded?: Dispatch<SetStateAction<boolean>>;
  modelTypeOptions: ExternalModelTypeSchema[];
  modelType: string;
}

export function StudioCreateHeader<ModeType extends string>({
  modeOptions,
  mode,
  modelTypeOptions,
  modelType,
  setMode,
  setModelType,
  expanded,
  setExpanded,
}: StudioCreateHeaderProps<ModeType>) {
  const model =
    modelTypeOptions.find((m) => m.external_key === modelType) ||
    modelTypeOptions[0];

  return !expanded ? (
    <HeaderContainer borderBottom slim center>
      <PanelButton
        Icon={CreateIcon}
        HoverIcon={ExtendRightIcon}
        enabled={!!setExpanded}
        onClick={() => setExpanded?.(true)}
      />
    </HeaderContainer>
  ) : (
    <HeaderContainer borderBottom slim>
      <LeftSection shrinkable>
        <PanelButton
          Icon={CreateIcon}
          HoverIcon={ExtendLeftIcon}
          enabled={!!setExpanded}
          onClick={() => setExpanded?.(false)}
        />
      </LeftSection>
      {modeOptions && (
        <CenterSection>
          <AnimatedTabs
            options={modeOptions}
            value={mode}
            onChange={(option) => {
              logWebUserEvent({
                actionName: 'CustomToggleClicked',
                context: {
                  stateBefore: modeOptions[0]?.value === mode ? 'on' : 'off',
                  stateAfter:
                    modeOptions[0]?.value === option.value ? 'on' : 'off',
                  createVersion: CREATE_VERSION,
                },
              });
              setMode(option.value);
            }}
          />
        </CenterSection>
      )}
      <RightSection shrinkable>
        <ContextMenuTrigger
          placement='bottom-left'
          ButtonComponent={(props) => (
            <Button
              variant={ButtonVariant.Secondary}
              shape={ButtonShape.Pill}
              className='h-[40px] text-[12px]'
              {...props}
            >
              {model?.name}
              <TriangleDownIcon className='-ml-1 h-4 w-4' />
            </Button>
          )}
          ContentsComponent={() => (
            <ModelMenuContents
              options={modelTypeOptions}
              activeId={modelType}
              onSelect={(model) => setModelType(model.external_key)}
            />
          )}
        />
      </RightSection>
    </HeaderContainer>
  );
}

export default CreateHeader;
