import axios from 'axios'
import { useState } from 'react'
import { useBooks } from '../context/BooksContext.jsx'

const OPEN_LIBRARY_SEARCH = 'https://openlibrary.org/search.json'

function docToBookPayload(doc) {
  return {
    title: doc.title || 'Sans titre',
    author: Array.isArray(doc.author_name)
      ? doc.author_name[0]
      : 'Auteur inconnu',
    year:
      typeof doc.first_publish_year === 'number'
        ? doc.first_publish_year
        : new Date().getFullYear(),
    genre: Array.isArray(doc.subject) ? doc.subject[0] : '',
    price: 10,
    read: false,
  }
}

function resultKey(doc, index) {
  return doc.key || doc.cover_edition_key || `${doc.title || 'work'}-${index}`
}

export default function SearchPage() {
  const { postBook } = useBooks()
  const [q, setQ] = useState('')
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  const [docs, setDocs] = useState([])
  const [addedKeys, setAddedKeys] = useState(() => new Set())
  const [lastQuery, setLastQuery] = useState('')

  async function handleSearch(e) {
    e.preventDefault()
    const term = q.trim()
    if (!term) return
    setLoading(true)
    setError(null)
    setDocs([])
    setAddedKeys(() => new Set())
    setLastQuery(term)
    try {
      const { data } = await axios.get(OPEN_LIBRARY_SEARCH, {
        params: { q: term, limit: 15 },
        timeout: 15000,
      })
      setDocs(Array.isArray(data.docs) ? data.docs : [])
    } catch (err) {
      setError(
        err.response?.data?.error ||
          err.message ||
          'Impossible de contacter Open Library.',
      )
    } finally {
      setLoading(false)
    }
  }

  function handleAdd(doc, index) {
    postBook(docToBookPayload(doc))
    const k = resultKey(doc, index)
    setAddedKeys((prev) => new Set(prev).add(k))
  }

  return (
    <div className="search-page">
      <h2 className="search-page-title">Recherche Open Library</h2>
      <p className="search-page-lead">
        Interroge l’API publique Open Library avec Axios, puis ajoute un
        ouvrage à ton catalogue local.
      </p>
      <form className="search-form" onSubmit={handleSearch}>
        <input
          type="search"
          className="search search-wide"
          placeholder="Titre, auteur, sujet…"
          value={q}
          onChange={(e) => setQ(e.target.value)}
          aria-label="Requête Open Library"
        />
        <button type="submit" className="btn primary" disabled={loading}>
          {loading ? 'Recherche…' : 'Rechercher'}
        </button>
      </form>

      {error ? (
        <p className="search-error" role="alert">
          {error}
        </p>
      ) : null}

      {!loading && docs.length === 0 && !error && !lastQuery ? (
        <p className="search-hint">Saisis un mot-clé et lance la recherche.</p>
      ) : null}

      {!loading && docs.length === 0 && !error && lastQuery ? (
        <p className="search-hint">Aucun résultat pour « {lastQuery} ».</p>
      ) : null}

      {docs.length > 0 ? (
        <ul className="ol-results">
          {docs.map((doc, i) => {
            const key = resultKey(doc, i)
            const year =
              typeof doc.first_publish_year === 'number'
                ? doc.first_publish_year
                : '—'
            const authors = Array.isArray(doc.author_name)
              ? doc.author_name.slice(0, 2).join(', ')
              : '—'
            const justAdded = addedKeys.has(key)
            return (
              <li key={key} className="ol-result-card">
                <h3 className="ol-result-title">
                  {doc.title || 'Sans titre'}
                </h3>
                <p className="ol-result-meta">
                  {authors} · {year}
                </p>
                <button
                  type="button"
                  className="btn small primary"
                  onClick={() => handleAdd(doc, i)}
                  disabled={justAdded}
                >
                  {justAdded ? 'Enregistré' : 'Enregistrer (POST /api/books)'}
                </button>
              </li>
            )
          })}
        </ul>
      ) : null}
    </div>
  )
}
