import * as React from 'react';
import {augmentImageFile, getMimeTypeDescription} from '@/utils/blob';
import {formatFileSize, formatNumeral} from '@/utils/numeral';
import clsx from 'clsx';
import {useAugmentedFile, useImageControls} from '@/categories/blob/react';

type ImageFilePreviewDerivedComponent = HTMLImageElement;

export interface ImageFilePreviewProps extends Omit<React.HTMLProps<ImageFilePreviewDerivedComponent>, 'src' | 'alt'> {
  file?: File;
  disabled?: boolean;
}

export const ImageFilePreview = React.forwardRef<ImageFilePreviewDerivedComponent, ImageFilePreviewProps>(({
  file,
  className,
  style,
  disabled = false,
  ...etcProps
}, forwardedRef) => {
  const { augmentedFile, error } = useAugmentedFile({
    file,
    augmentFunction: augmentImageFile,
  });
  const { fullScreen, handleAction, imageRef, filenameRef } = useImageControls({
    forwardedRef,
  });

  if (!augmentedFile) {
    return null;
  }

  return (
    <div
      className={clsx(
        'flex flex-col sm:grid sm:grid-cols-3 gap-8 w-full',
        className,
      )}
      style={style}
    >
      <div className="h-full relative">
        <div className="sm:absolute top-0 left-0 w-full sm:h-full z-[1]">
          {
            typeof augmentedFile.metadata?.previewUrl === 'string'
            && (
              <img
                {...etcProps}
                ref={imageRef}
                className={clsx(
                  'block h-full max-w-full object-center bg-[#000000]',
                  {
                    'object-contain fixed w-full top-0 left-0': fullScreen,
                    'object-cover w-full': !fullScreen,
                  },
                )}
                src={augmentedFile.metadata.previewUrl}
                alt={augmentedFile.name}
                data-testid="preview"
              />
            )
          }
          {
            error
            && (
              <div className="w-full h-full flex items-center justify-center text-center px-4 bg-[#000000] select-none">
                {error.message}
              </div>
            )
          }
        </div>
      </div>
      <div
        className="col-span-2 flex-shrink-0 m-0 flex flex-col gap-4 justify-between"
      >
        <dl data-testid="infoBox">
          <div className="w-full font-bold">
            <dt className="sr-only">
              Name
            </dt>
            <dd
              className="m-0 w-full text-ellipsis overflow-hidden"
              title={augmentedFile.name}
              ref={filenameRef}
            >
              {augmentedFile.name}
            </dd>
          </div>
          <div className="w-full">
            <dt className="sr-only">
              Type
            </dt>
            <dd
              title={augmentedFile.type}
              className="m-0 w-full text-ellipsis overflow-hidden"
            >
              {getMimeTypeDescription(augmentedFile.type, augmentedFile.name)}
            </dd>
          </div>
          <div className="w-full">
            <dt className="sr-only">
              Size
            </dt>
            <dd
              className="m-0 w-full text-ellipsis overflow-hidden"
              title={`${formatNumeral(augmentedFile.size ?? 0)} bytes`}
            >
              {formatFileSize(augmentedFile.size)}
            </dd>
          </div>
          {
            typeof augmentedFile.metadata?.width === 'number'
            && typeof augmentedFile.metadata?.height === 'number'
            && (
              <div>
                <dt className="sr-only">
                  Pixel Dimensions
                </dt>
                <dd
                  className="m-0 w-full text-ellipsis overflow-hidden"
                >
                  {formatNumeral(augmentedFile.metadata.width)} &times; {formatNumeral(augmentedFile.metadata.height)} pixels
                </dd>
              </div>
            )
          }
        </dl>
        <form
          onSubmit={handleAction}
          className="flex gap-4"
        >
          <fieldset
            disabled={disabled || typeof error !== 'undefined'}
            className="contents"
          >
            <legend className="sr-only">
              Controls
            </legend>
            <button
              type="submit"
              name="action"
              value="toggleFullScreen"
              className={clsx(
                'h-12 flex bg-negative text-primary disabled:text-primary focus:text-secondary active:text-tertiary items-center justify-center leading-none gap-4 select-none',
                'focus:outline-0',
                'disabled:opacity-50 disabled:cursor-not-allowed',
                {
                  'fixed top-0 left-0 w-full h-full opacity-0 z-[1]': fullScreen,
                }
              )}
            >
              <span
                className="block uppercase font-bold h-[1.1em] w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded"
              >
                Preview
              </span>
            </button>
            {' '}
            <button
              type="submit"
              name="action"
              value="download"
              className={clsx(
                'h-12 flex bg-negative text-primary disabled:text-primary focus:text-secondary active:text-tertiary items-center justify-center leading-none gap-4 select-none',
                'focus:outline-0',
                'disabled:opacity-50 disabled:cursor-not-allowed',
              )}
            >
              <span
                className="block uppercase font-bold h-[1.1em] w-full whitespace-nowrap overflow-hidden text-ellipsis font-semi-expanded"
              >
                Download
              </span>
            </button>
          </fieldset>
        </form>
      </div>
    </div>
  );
});

ImageFilePreview.displayName = 'ImageFilePreview';
