import React from 'react';
import { cn } from '@udecode/cn';
import { useElement, useRemoveNodeButton } from '@udecode/plate-common';

import { Icons } from '@/components/icons';
import { Button, buttonVariants } from '@/components/plate-ui/button';
import { inputVariants } from '@/components/plate-ui/input';
import { Separator } from '@/components/plate-ui/separator';

import {
  AttachmentToolButton,
  ELEMENT_ATTACHMENT_AUDIO,
  ELEMENT_ATTACHMENT_DOCUMENT,
  ELEMENT_ATTACHMENT_IMAGE,
  ELEMENT_ATTACHMENT_VIDEO,
  TAttachmentElement,
  useAttachmentState,
  useSizeChange,
} from '../logic';
import { AttachmentPopoverProps } from './attachment-popover';

export interface AttachmentToolbarProps
  extends Omit<AttachmentPopoverProps, 'children'> {}

export function AttachmentToolbar({
  pluginkey,
  elementRef,
}: AttachmentToolbarProps) {
  const { element } = useAttachmentState();
  const { props: buttonProps } = useRemoveNodeButton({ element });

  const { status } = element;

  return (
    <div className="box-content flex h-9 items-center gap-1">
      {status === 'link' ? (
        <StatusToolbar />
      ) : (
        <React.Fragment>
          {pluginkey === ELEMENT_ATTACHMENT_IMAGE && (
            <ImageToolbar elementRef={elementRef!} />
          )}
          {pluginkey === ELEMENT_ATTACHMENT_DOCUMENT && (
            <OfficeImageToolbar elementRef={elementRef!} />
          )}
          {pluginkey === ELEMENT_ATTACHMENT_AUDIO && <AudioToolbar />}
          {pluginkey === ELEMENT_ATTACHMENT_VIDEO && (
            <VideoToolbar elementRef={elementRef!} />
          )}
        </React.Fragment>
      )}
      <Separator orientation="vertical" className="my-1" />
      <Button variant="ghost" size="sms" {...buttonProps}>
        <Icons.delete className="h-4 w-4" />
      </Button>
    </div>
  );
}

interface ElementProps
  extends Required<Pick<AttachmentToolbarProps, 'elementRef'>> {}

function ImageToolbar({ elementRef }: ElementProps) {
  return (
    <>
      <WidthInputToolbar />
      <Separator orientation="vertical" className="my-1" />
      <SizeChangeGroupToolbar elementRef={elementRef} />
      <Separator orientation="vertical" className="my-1" />
      <BorderToolbar />
    </>
  );
}

function OfficeImageToolbar({ elementRef }: ElementProps) {
  return (
    <>
      <ImageToolbar elementRef={elementRef} />
      <Separator orientation="vertical" className="my-1" />
      <StatusToolbar />
    </>
  );
}

function AudioToolbar() {
  return (
    <>
      <WidthInputToolbar />
      <Separator orientation="vertical" className="my-1" />
      <StatusToolbar />
    </>
  );
}

function VideoToolbar({ elementRef }: ElementProps) {
  return (
    <>
      <WidthInputToolbar />
      <Separator orientation="vertical" className="my-1" />
      <SizeChangeGroupToolbar elementRef={elementRef} />
      <Separator orientation="vertical" className="my-1" />
      <StatusToolbar />
    </>
  );
}

function StatusToolbar() {
  const { status } = useElement<TAttachmentElement>();

  return (
    <AttachmentToolButton.StatusButton
      className={cn(buttonVariants({ variant: 'ghost', size: 'sm' }))}
    >
      {status === 'link' ? '作为缩略图显示' : '作为链接显示'}
    </AttachmentToolButton.StatusButton>
  );
}

function BorderToolbar() {
  const { bordered } = useElement<TAttachmentElement>();

  return (
    <AttachmentToolButton.BorderedButton
      className={cn(
        buttonVariants({ variant: 'ghost', size: 'sm' }),
        bordered && 'bg-accent text-accent-foreground'
      )}
    >
      边框
    </AttachmentToolButton.BorderedButton>
  );
}

function WidthInputToolbar() {
  return (
    <AttachmentToolButton.WidthEditInput
      className={inputVariants({ variant: 'normal', w: 'sm', h: 'sm' })}
    />
  );
}

enum EHeightSize {
  Small = 150,
  Middle = 250,
  Large = 400,
}

interface SizeChangeGroupToolbarProps
  extends Pick<AttachmentToolbarProps, 'elementRef'> {}
function SizeChangeGroupToolbar({ elementRef }: SizeChangeGroupToolbarProps) {
  const { height = 0 } = useElement<TAttachmentElement>();

  const curWidth = elementRef?.current?.clientWidth || 0;
  const curHeight = elementRef?.current?.clientHeight || 0;

  const { setHeight } = useSizeChange({ curWidth, curHeight });

  const commonButtonClass = buttonVariants({ variant: 'ghost', size: 'sm' });

  const activeClass = 'bg-accent text-accent-foreground';

  const smallActive = height === EHeightSize.Small;
  const middleActive = height === EHeightSize.Middle;
  const LargeActive = height === EHeightSize.Large;

  return (
    <>
      <AttachmentToolButton.SizeChangeButton
        className={cn(commonButtonClass, smallActive && activeClass)}
        onClick={() => setHeight(EHeightSize.Small)}
      >
        <Icons.arrowUpRightFromSquare className="h-4 w-4" />
      </AttachmentToolButton.SizeChangeButton>
      <AttachmentToolButton.SizeChangeButton
        className={cn(commonButtonClass, middleActive && activeClass)}
        onClick={() => setHeight(EHeightSize.Middle)}
      >
        <Icons.arrowUpRightFromSquare className="h-[1.125rem] w-[1.125rem]" />
      </AttachmentToolButton.SizeChangeButton>
      <AttachmentToolButton.SizeChangeButton
        className={cn(commonButtonClass, LargeActive && activeClass)}
        onClick={() => setHeight(EHeightSize.Large)}
      >
        <Icons.arrowUpRightFromSquare className="h-5 w-5" />
      </AttachmentToolButton.SizeChangeButton>
    </>
  );
}
