import type { Meta, StoryObj } from '@storybook/react';
import React, { useCallback, useState } from 'react';
import { twMerge } from 'tailwind-merge';

import AspectRatioContainer from './AspectRatioContainer';
import {
  HorizontalSplitGroup,
  SplitPanel,
  VerticalSplitGroup,
} from './SplitPanel';

type PagePropsAndCustomArgs = React.ComponentProps<
  typeof AspectRatioContainer
> & {
  contentClassName?: string;
  inactivePanelClassName?: string;
  initialWidth?: number;
  initialHeight?: number;
};

function rotatePosition(className: string) {
  const [, prefix, position] = className.match(
    /(.*?)(?:-(start|center|end))?$/
  ) || [className];
  switch (position) {
    case 'start':
      return `${prefix}-center`;
    case 'center':
      return `${prefix}-end`;
    case 'end':
      return `${prefix}-start`;
    default:
      return className;
  }
}

function AspectRatioContainerDemo(props: PagePropsAndCustomArgs) {
  const {
    className,
    contentClassName,
    inactivePanelClassName = 'bg-opacity-black-20',
    initialWidth,
    initialHeight,
    ...restProps
  } = props;
  const [alignItemsClassName, setAlignItemsClassName] =
    useState('items-center');
  const [justifyContentClassName, setJustifyContentClassName] =
    useState('justify-center');

  const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
    const container =
      e.currentTarget instanceof HTMLElement &&
      e.currentTarget.closest('[data-container-fill-type]');
    const fillType =
      container instanceof HTMLElement && container.dataset.containerFillType;
    if (fillType === 'width') {
      setAlignItemsClassName((prevClassName) => rotatePosition(prevClassName));
    } else {
      setJustifyContentClassName((prevClassName) =>
        rotatePosition(prevClassName)
      );
    }
  }, []);

  return (
    <VerticalSplitGroup className='fixed inset-0'>
      <SplitPanel className={inactivePanelClassName} style={{ width: 10 }} />
      <HorizontalSplitGroup style={{ width: initialWidth }}>
        <SplitPanel className={inactivePanelClassName} style={{ height: 10 }} />
        <SplitPanel
          className='overflow-visible bg-background-secondary text-center'
          style={{ height: initialHeight }}
        >
          <AspectRatioContainer
            className={twMerge(
              'absolute inset-0 select-none',
              'data-[container-fill-type=width]:cursor-ns-resize',
              'data-[container-fill-type=height]:cursor-ew-resize',
              className,
              alignItemsClassName,
              justifyContentClassName
            )}
            onClick={handleClick}
            {...restProps}
          >
            <div
              className={twMerge(
                'aspect-(--aspect-ratio)',
                'h-(--aspect-ratio-child-height,auto) w-(--aspect-ratio-child-width,auto)',
                'max-h-full max-w-full',
                contentClassName
              )}
            />
          </AspectRatioContainer>
        </SplitPanel>
        <SplitPanel
          className={twMerge('-mr-2 flex-1', inactivePanelClassName)}
        />
      </HorizontalSplitGroup>
      <SplitPanel className={twMerge('flex-1', inactivePanelClassName)} />
    </VerticalSplitGroup>
  );
}

const meta: Meta<PagePropsAndCustomArgs> = {
  title: 'components/AspectRatioContainer',
  component: AspectRatioContainerDemo,
};

export default meta;
type Story = StoryObj<PagePropsAndCustomArgs>;

export const Contain: Story = {
  args: {
    className:
      'bg-background-tertiary text-foreground-primary flex items-center justify-center',
    contentClassName: 'bg-accent-green text-accent-green-contrast rounded-lg',
    width: 90,
    height: 160,
    initialWidth: 400,
    initialHeight: 400,
  },
};

export const Fill: Story = {
  args: {
    className:
      'bg-background-tertiary text-foreground-primary flex items-center justify-center',
    contentClassName: [
      'absolute top-0 left-0',
      'bg-accent-green text-accent-green-contrast rounded-lg',
      'w-(--aspect-ratio-child-height,auto) h-(--aspect-ratio-child-width,auto)',
      'max-h-none max-w-none min-w-full min-h-full',
    ].join(' '),
    width: 90,
    height: 160,
    initialWidth: 400,
    initialHeight: 400,
  },
};

export const AspecRatio: Story = {
  args: {
    className:
      'bg-background-tertiary text-foreground-primary flex items-center justify-center',
    contentClassName: [
      'absolute top-0 left-0',
      'bg-accent-green text-accent-green-contrast rounded-lg',
      'w-(--aspect-ratio-child-height,auto) h-(--aspect-ratio-child-width,auto)',
      'max-h-none max-w-none min-w-full min-h-full',
    ].join(' '),
    aspectRatio: 9 / 16,
    initialWidth: 400,
    initialHeight: 400,
  },
};
