import { type ChangeEvent, useRef } from 'react'
import type { MediaClient, MediaItem } from './client.js'
import { useMediaLibrary } from './useMediaLibrary.js'
import { useUpload } from './useUpload.js'

export interface MediaLibraryProps {
  client: MediaClient
  onSelect(item: MediaItem): void
  className?: string
  allowDelete?: boolean
}

export function MediaLibrary({ client, onSelect, className, allowDelete = true }: MediaLibraryProps) {
  const lib = useMediaLibrary(client)
  const up = useUpload(client)
  const inputRef = useRef<HTMLInputElement>(null)

  const onFile = async (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return
    try {
      await up.upload(file)
      await lib.refresh()
    } catch {
      // up.error surfaces a host rejection (UploadRejectedError) — the region renders it below.
      // (A re-entrant UploadInFlightError can't occur here: input is disabled while up.uploading.)
    } finally {
      if (inputRef.current) inputRef.current.value = ''
    }
  }

  // WCAG 2.4.3: deleting the focused item removes its button from the DOM. Restore focus
  // to a stable in-component target (the upload input) after remove settles, so focus never
  // falls to <body>. lib.remove never rejects (it surfaces failures via lib.error), so this
  // runs on both success and failure — focus lands on the always-rendered input either way.
  const onDelete = async (key: string) => {
    await lib.remove(key)
    inputRef.current?.focus()
  }

  return (
    <section
      aria-label="Media library"
      className={className}
      style={{ containerType: 'inline-size' }}
    >
      <div>
        <label>
          <span>Upload image</span>
          <input ref={inputRef} type="file" accept="image/*" onChange={onFile} disabled={up.uploading} />
        </label>
        {up.error ? <p role="alert">{up.error.message}</p> : null}
      </div>

      {lib.error ? <p role="alert">{lib.error.message}</p> : null}

      {!lib.loading && !lib.error && lib.items.length === 0 ? (
        <p>No media yet. Upload an image to begin.</p>
      ) : (
        <ul
          style={{
            display: 'grid',
            // container-query responsive: columns track the COMPONENT's width, not the viewport.
            gridTemplateColumns: 'repeat(auto-fill, minmax(min(12cqi, 100%), 1fr))',
            gap: '0.75rem',
            listStyle: 'none',
            margin: 0,
            padding: 0,
          }}
        >
          {lib.items.map((item) => (
            <li key={item.key}>
              <button type="button" aria-label={`Select ${item.key}`} onClick={() => onSelect(item)} style={{ display: 'block', width: '100%', border: 'none', padding: 0, background: 'none', cursor: 'pointer' }}>
                <img src={item.url} alt="" width={item.width} height={item.height} style={{ width: '100%', height: 'auto', display: 'block' }} />
              </button>
              {allowDelete ? (
                <button type="button" aria-label={`Delete ${item.key}`} onClick={() => void onDelete(item.key)}>
                  Delete
                </button>
              ) : null}
            </li>
          ))}
        </ul>
      )}

      {lib.hasMore ? (
        <button type="button" onClick={() => void lib.loadMore()} disabled={lib.loading}>
          Load more
        </button>
      ) : null}
    </section>
  )
}
