import type { ImportedMediaAsset } from '../app/application-state';
import {
  assetDurationSeconds,
  assetHasVideo,
  formatBytes,
  formatDuration,
} from '../app/application-state';
import { Icon } from './Icon';

export interface MediaBinProps {
  assets: readonly ImportedMediaAsset[];
  selectedId?: string;
  onSelect: (id: string) => void;
  onInspect: (id: string) => void;
  inspectDisabled?: boolean;
  removeDisabled?: boolean;
  onRemove: (id: string) => void;
}

export function MediaBin({
  assets,
  selectedId,
  onSelect,
  onInspect,
  inspectDisabled = false,
  removeDisabled = false,
  onRemove,
}: MediaBinProps) {
  if (assets.length === 0) {
    return (
      <div className="media-bin__empty">
        <Icon name="video" />
        <p>Your source files will appear here.</p>
      </div>
    );
  }

  return (
    <ul className="media-list" aria-label="Imported media">
      {assets.map((asset) => {
        const hasVideo = assetHasVideo(asset) === true;
        const video = asset.probe?.streams.find(
          (stream) => stream.type === 'video'
        );
        const durationSeconds = assetDurationSeconds(asset);
        const width = video?.width ?? asset.browserMetadata?.width;
        const height = video?.height ?? asset.browserMetadata?.height;
        const audioCount =
          asset.probe?.streams.filter((stream) => stream.type === 'audio')
            .length ?? 0;
        return (
          <li key={asset.id}>
            <button
              type="button"
              className={[
                'media-card',
                selectedId === asset.id ? 'media-card--selected' : '',
              ]
                .filter(Boolean)
                .join(' ')}
              aria-pressed={selectedId === asset.id}
              onClick={() => onSelect(asset.id)}
            >
              <span className="media-card__type">
                <Icon name={hasVideo ? 'video' : 'audio'} />
              </span>
              <span className="media-card__content">
                <strong title={asset.file.name}>{asset.file.name}</strong>
                <small>
                  {formatBytes(asset.file.size)}
                  {durationSeconds !== undefined
                    ? ` · ${formatDuration(durationSeconds)}`
                    : ''}
                </small>
                <small className={`phase phase--${asset.phase}`}>
                  {asset.phase === 'probing'
                    ? `${asset.browserMetadata ? 'Ready to play' : 'File ready'} · Inspecting details…`
                    : asset.phase === 'ready'
                      ? `${hasVideo ? `${width ?? '?'}×${height ?? '?'}` : 'Audio'} · ${audioCount} audio`
                      : asset.phase === 'error'
                        ? `${asset.browserMetadata ? 'Ready to play' : 'File ready'} · Details unavailable`
                        : asset.browserMetadataError
                          ? 'File ready · Basic metadata unavailable'
                          : asset.browserMetadata
                            ? 'Ready to play · Details on demand'
                            : 'File ready · Reading basic metadata…'}
                </small>
              </span>
            </button>
            {asset.phase !== 'ready' ? (
              <button
                className="icon-action"
                type="button"
                aria-label={`${asset.phase === 'error' ? 'Retry detailed inspection for' : 'Inspect details for'} ${asset.file.name}`}
                title={
                  asset.phase === 'error'
                    ? asset.error
                    : 'Read codecs, streams, chapters and tags'
                }
                disabled={inspectDisabled || asset.phase === 'probing'}
                {...(asset.error
                  ? { 'aria-describedby': `inspection-error-${asset.id}` }
                  : {})}
                onClick={() => onInspect(asset.id)}
              >
                <Icon name={asset.phase === 'probing' ? 'queue' : 'info'} />
              </button>
            ) : null}
            {asset.error ? (
              <span
                className="visually-hidden"
                id={`inspection-error-${asset.id}`}
              >
                {asset.error}
              </span>
            ) : null}
            <button
              className="icon-action"
              type="button"
              aria-label={`Remove ${asset.file.name}`}
              disabled={removeDisabled}
              onClick={() => onRemove(asset.id)}
            >
              <Icon name="trash" />
            </button>
          </li>
        );
      })}
    </ul>
  );
}
