'use client'

import { useState, useRef } from 'react'
import { X, Upload, Search, ImageIcon, Loader2 } from 'lucide-react'
import { toast } from 'sonner'
import { cmsApi } from '../lib/api.js'
import { useApiData } from '../lib/useApiData.js'

interface MediaItem {
  id: string
  filename: string
  storageKey: string
  /** Normalized public URL from the media list endpoint (preferred for display). */
  url?: string
  mimeType: string
  fileSize: number
  width?: number
  height?: number
}

/** Minimal selected-asset shape exposed to callers that need the asset id. */
export interface SelectedMediaItem {
  id: string
  storageKey: string
  /** Normalized public URL (falls back to storageKey when absent). */
  url: string
  filename: string
  mimeType: string
  width?: number
  height?: number
}

export interface MediaPickerModalProps {
  open: boolean
  onClose: () => void
  onSelect: (url: string, alt?: string) => void
  /**
   * Optional richer callback fired alongside `onSelect` with the full media
   * item, so callers that need to store the asset id (not just the URL) can.
   */
  onSelectItem?: (item: SelectedMediaItem) => void
  accept?: string
  /**
   * Hide the "Upload New" tab and show only the existing library. Used where a
   * caller has its own upload path (e.g. brand assets, which upload with
   * format-preserving options) but still wants to reuse library assets.
   */
  libraryOnly?: boolean
}

export function MediaPickerModal({
  open,
  onClose,
  onSelect,
  onSelectItem,
  accept,
  libraryOnly = false,
}: MediaPickerModalProps) {
  const [tab, setTab] = useState<'library' | 'upload'>('library')
  const [search, setSearch] = useState('')
  const [uploading, setUploading] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const { data, loading, refetch } = useApiData<{ data: { items: MediaItem[] } }>(
    open ? `/media?pageSize=50${search ? `&search=${encodeURIComponent(search)}` : ''}` : null,
  )

  const items = (data as any)?.data?.items ?? (data as any)?.items ?? []
  const imageItems = items.filter((item: MediaItem) => item.mimeType.startsWith('image/'))

  async function handleUpload(files: FileList | null) {
    if (!files || files.length === 0) return
    setUploading(true)

    const file = files[0]!
    const formData = new FormData()
    formData.append('file', file)

    const res = await cmsApi<MediaItem>('/media/upload', {
      method: 'POST',
      body: formData,
    })

    if (res.error) {
      toast.error(res.error)
    } else if (res.data) {
      const mediaItem = res.data as MediaItem
      const url = mediaItem.url || mediaItem.storageKey || ''
      toast.success(`Uploaded ${file.name}`)
      onSelectItem?.({
        id: mediaItem.id,
        storageKey: mediaItem.storageKey,
        url,
        filename: mediaItem.filename ?? file.name,
        mimeType: mediaItem.mimeType ?? file.type,
        width: mediaItem.width,
        height: mediaItem.height,
      })
      onSelect(url, file.name)
      onClose()
    }

    setUploading(false)
    if (fileInputRef.current) fileInputRef.current.value = ''
  }

  function handleSelectItem(item: MediaItem) {
    const url = item.url || item.storageKey || ''
    onSelectItem?.({
      id: item.id,
      storageKey: item.storageKey,
      url,
      filename: item.filename,
      mimeType: item.mimeType,
      width: item.width,
      height: item.height,
    })
    onSelect(url, item.filename)
    onClose()
  }

  if (!open) return null

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="fixed inset-0 bg-black/40" onClick={onClose} />
      <div className="relative mx-4 flex max-h-[80vh] w-full max-w-2xl flex-col rounded-xl bg-white shadow-2xl">
        <div className="flex items-center justify-between border-b border-gray-200 px-4 py-3">
          <h2 className="text-lg font-semibold text-gray-900">Insert Image</h2>
          <button
            onClick={onClose}
            className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
          >
            <X className="h-5 w-5 text-gray-500" />
          </button>
        </div>

        {!libraryOnly && (
          <div className="flex border-b border-gray-200">
            <button
              onClick={() => setTab('library')}
              className={`flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${
                tab === 'library'
                  ? 'border-b-2 border-blue-600 text-blue-600'
                  : 'text-gray-500 hover:text-gray-700'
              }`}
            >
              Media Library
            </button>
            <button
              onClick={() => setTab('upload')}
              className={`flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${
                tab === 'upload'
                  ? 'border-b-2 border-blue-600 text-blue-600'
                  : 'text-gray-500 hover:text-gray-700'
              }`}
            >
              Upload New
            </button>
          </div>
        )}

        <div className="flex-1 overflow-y-auto p-4">
          {libraryOnly || tab === 'library' ? (
            <>
              <div className="relative mb-4">
                <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
                <input
                  type="text"
                  value={search}
                  onChange={(e) => setSearch(e.target.value)}
                  placeholder="Search images..."
                  className="w-full rounded-lg border border-gray-300 py-2 pr-3 pl-9 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
                />
              </div>

              {loading ? (
                <div className="flex items-center justify-center py-12">
                  <Loader2 className="h-6 w-6 animate-spin text-gray-400" />
                </div>
              ) : imageItems.length === 0 ? (
                <div className="py-12 text-center text-sm text-gray-500">
                  No images found. Try uploading one.
                </div>
              ) : (
                <div className="grid grid-cols-3 gap-3 sm:grid-cols-4">
                  {imageItems.map((item: MediaItem) => {
                    const src = item.url || item.storageKey
                    return (
                      <button
                        key={item.id}
                        onClick={() => handleSelectItem(item)}
                        title={item.filename}
                        className="group relative aspect-square overflow-hidden rounded-lg border-2 border-gray-200 bg-gray-100 transition-colors hover:border-blue-500"
                      >
                        {src ? (
                          <img
                            src={src}
                            alt={item.filename}
                            loading="lazy"
                            className="h-full w-full object-contain"
                          />
                        ) : (
                          <div className="flex h-full w-full items-center justify-center">
                            <ImageIcon className="h-8 w-8 text-gray-300" />
                          </div>
                        )}
                        <div className="absolute inset-x-0 bottom-0 bg-black/60 p-1.5 opacity-0 transition-opacity group-hover:opacity-100">
                          <p className="truncate text-xs text-white">{item.filename}</p>
                        </div>
                      </button>
                    )
                  })}
                </div>
              )}
            </>
          ) : (
            <div className="flex flex-col items-center justify-center py-12">
              <input
                ref={fileInputRef}
                type="file"
                accept={accept ?? 'image/*'}
                className="hidden"
                onChange={(e) => handleUpload(e.target.files)}
              />
              <div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-blue-50">
                {uploading ? (
                  <Loader2 className="h-8 w-8 animate-spin text-blue-600" />
                ) : (
                  <Upload className="h-8 w-8 text-blue-600" />
                )}
              </div>
              <p className="mb-4 text-sm text-gray-600">
                {uploading ? 'Uploading...' : 'Select an image file to upload'}
              </p>
              {!uploading && (
                <button
                  onClick={() => fileInputRef.current?.click()}
                  className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
                >
                  Choose File
                </button>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  )
}
