import logging

import requests

logger = logging.getLogger(__name__)

OPENLIBRARY_BASE_URL = "https://openlibrary.org"


def lookup_book_from_openlibrary(title: str, author: str | None = None) -> dict:
    try:
        response = requests.get(
            f"{OPENLIBRARY_BASE_URL}/search.json",
            params={"title": title, "limit": 5},
            timeout=10,
        )
        response.raise_for_status()
        search_results = response.json()
    except Exception as e:
        logger.warning(f"Could not search for {title}: {e}")
        return {}

    docs = search_results.get("docs", [])

    title_lower = title.lower()
    for work_doc in docs:
        found_title = work_doc.get("title", "")
        if found_title.lower() == title_lower:
            olid = work_doc.get("key", "").replace("/works/", "")
            if not olid:
                continue
            break
    else:
        logger.info(f"OpenLibrary: no close match for '{title}', skipping")
        return {}

    try:
        work_response = requests.get(
            f"{OPENLIBRARY_BASE_URL}/works/{olid}.json", timeout=10
        )
        work_response.raise_for_status()
        work_json = work_response.json()
    except Exception as e:
        logger.warning(f"Could not get work JSON for {olid}: {e}")
        return {}

    book_dict: dict = {"title": work_json.get("title"), "openlibrary_id": olid}

    description = work_json.get("description")
    if description:
        if isinstance(description, dict):
            book_dict["summary"] = description.get("value", "")
        else:
            book_dict["summary"] = str(description)

    subjects = work_json.get("subjects", [])
    if subjects:
        book_dict["genres"] = subjects[:10]

    covers = work_json.get("covers", [])
    if covers:
        book_dict["cover_url"] = (
            f"https://covers.openlibrary.org/b/id/{covers[0]}-L.jpg"
        )

    try:
        editions_response = requests.get(
            f"{OPENLIBRARY_BASE_URL}/works/{olid}/editions.json", timeout=10
        )
        if editions_response.status_code == 200:
            editions_data = editions_response.json()
            entries = editions_data.get("entries", [])
            if entries:
                edition = entries[0]
                isbn_list = edition.get("isbn_10", [])
                if isbn_list:
                    book_dict["isbn_10"] = isbn_list[0]
                isbn_list = edition.get("isbn_13", [])
                if isbn_list:
                    book_dict["isbn_13"] = isbn_list[0]
                publishers = edition.get("publishers", [])
                if publishers:
                    book_dict["publisher"] = publishers[0]
                pub_date = edition.get("publish_date")
                if pub_date:
                    if len(pub_date) >= 4:
                        try:
                            book_dict["first_publish_year"] = int(pub_date[:4])
                        except ValueError:
                            pass
                pages = edition.get("number_of_pages_median")
                if pages:
                    book_dict["pages"] = pages
                edition_covers = edition.get("covers", [])
                if edition_covers and not book_dict.get("cover_url"):
                    book_dict["cover_url"] = (
                        f"https://covers.openlibrary.org/b/id/{edition_covers[0]}-L.jpg"
                    )
    except Exception as e:
        logger.warning(f"Could not get editions for {olid}: {e}")

    if author:
        book_dict["authors"] = [author]
    elif work_doc.get("author_name"):
        book_dict["authors"] = work_doc.get("author_name", [])

    return book_dict


def lookup_author_from_openlibrary(name: str) -> dict:
    try:
        response = requests.get(
            f"{OPENLIBRARY_BASE_URL}/search.json",
            params={"author": name, "limit": 1},
            timeout=10,
        )
        response.raise_for_status()
        search_results = response.json()
    except Exception as e:
        logger.warning(f"Could not search for author {name}: {e}")
        return {}

    docs = search_results.get("docs", [])
    if not docs:
        return {}

    author_doc = docs[0]
    author_olid = author_doc.get("key", "").replace("/authors/", "")
    if not author_olid:
        return {}

    author_dict: dict = {
        "name": author_doc.get("name", name),
        "openlibrary_id": author_olid,
    }

    try:
        author_response = requests.get(
            f"{OPENLIBRARY_BASE_URL}/authors/{author_olid}.json", timeout=10
        )
        if author_response.status_code == 200:
            author_json = author_response.json()
            bio = author_json.get("bio")
            if bio:
                if isinstance(bio, dict):
                    author_dict["bio"] = bio.get("value", "")
                else:
                    author_dict["bio"] = str(bio)

            wikipedia = author_json.get("wikipedia")
            if wikipedia:
                author_dict["wikipedia_url"] = wikipedia
    except Exception as e:
        logger.warning(f"Could not get author JSON for {author_olid}: {e}")

    author_dict["author_headshot_url"] = (
        f"https://covers.openlibrary.org/a/olid/{author_olid}-L.jpg"
    )

    return author_dict
