import * as React from 'react';
import {augmentImageFile, FallbackFile, 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 | FallbackFile;
  disabled?: boolean;
}

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

  if (!(augmentedFile)) {
    return null;
  }

  console.log(augmentedFile);

  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-[3]">
          {
            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=""
                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>
          {
            typeof augmentedFile?.size === 'number'
            && (
              <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>
            )
          }
          {
            Array.isArray(augmentedFile.metadata?.palette)
            && (
              <div className="mt-2">
                <dt className="sr-only">
                  Palette
                </dt>
                <dd
                  className="m-0 w-full text-ellipsis overflow-hidden flex flex-wrap gap-x-4 gap-y-1"
                >
                  {augmentedFile.metadata?.palette.map((rgb, i) => (
                    <>
                      {i > 0 && ' '}
                      <span
                        key={rgb.join(' ')}
                        className="whitespace-nowrap"
                        title={`rgb(${rgb.join(', ')})`}
                      >
                        <span
                          className="inline-block w-5 h-5 align-middle border border-[#ffffff] ring-1 ring-[#000000]"
                          style={{
                            backgroundColor: `rgb(${rgb.join(' ')})`,
                          }}
                        />
                        <span className="tabular-nums text-xs sr-only">
                          {
                            rgb
                              .map((c) => c.toString().padStart(4, ' ').split('').map((c, i) => (
                                <span key={i} className={clsx({
                                  'opacity-0': c === ' ',
                                })}>
                                  {i === 0 && ' '}
                                  {c === ' ' && i > 0 ? '0' : c}
                                </span>
                              )))
                              .flat()
                          }
                        </span>
                      </span>
                    </>
                  ))}
                </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-[3]': 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';
