from rights_filter.analysis.preprocessing import ImagePayload
from rights_filter.domain.records import AnalysisRun, EvidenceSource, InMemoryRightsFilterRepository
from rights_filter.integrations.naver_search import (
    FakeNaverSearchClient,
    NaverOpenApiSearchClient,
    NaverSearchAdapter,
)
from rights_filter.integrations.search_policy import SearchApiPolicy


def test_approved_text_query_returns_ranked_naver_evidence():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official album cover",
                    "link": "https://example.test/image.jpg",
                    "thumbnail": "https://example.test/thumb.jpg",
                    "sizeheight": "900",
                    "sizewidth": "900",
                    "page_url": "https://example.test/page",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU album cover", policy)

    assert client.calls == ["IU album cover"]
    assert evidence[0].source == EvidenceSource.NAVER_SEARCH
    assert evidence[0].reason == "Naver search result found"
    assert evidence[0].data["query"] == "IU album cover"
    assert evidence[0].data["rank"] == 1
    assert evidence[0].data["image_url"] == "https://example.test/image.jpg"
    assert evidence[0].data["thumbnail_url"] == "https://example.test/thumb.jpg"
    assert evidence[0].data["result_url"] == "https://example.test/page"


def test_naver_image_results_unwrap_proxy_image_urls():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official profile",
                    "link": (
                        "https://search.naver.test/proxy?"
                        "imgurl=cdn.example.test%2Fiu-profile.png"
                        "&amp;where=image"
                    ),
                    "thumbnail": (
                        "https://search.naver.test/thumb?"
                        "image_url=https%3A%2F%2Fcdn.example.test%2Fiu-thumb.jpg"
                    ),
                    "sizeheight": "900",
                    "sizewidth": "700",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU official profile", policy)

    assert evidence[0].data["image_url"] == "https://cdn.example.test/iu-profile.png"
    assert evidence[0].data["thumbnail_url"] == "https://cdn.example.test/iu-thumb.jpg"
    assert evidence[0].data["result_url"] == "https://cdn.example.test/iu-profile.png"


def test_naver_image_results_unwrap_weak_proxy_jfif_image_urls():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official profile",
                    "link": (
                        "https://search.naver.test/proxy?"
                        "url=https%3A%2F%2Fcdn.example.test%2Fiu-profile.jfif"
                        "&amp;where=image"
                    ),
                    "thumbnail": (
                        "https://search.naver.test/thumb?"
                        "u=https%3A%2F%2Fcdn.example.test%2Fiu-thumb.jfif"
                    ),
                    "sizeheight": "900",
                    "sizewidth": "700",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU official profile", policy)

    assert evidence[0].data["image_url"] == "https://cdn.example.test/iu-profile.jfif"
    assert evidence[0].data["thumbnail_url"] == "https://cdn.example.test/iu-thumb.jfif"
    assert evidence[0].data["result_url"] == "https://cdn.example.test/iu-profile.jfif"


def test_naver_image_results_unwrap_weak_proxy_query_format_image_urls():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official profile",
                    "link": (
                        "https://search.naver.test/proxy?"
                        "url=https%3A%2F%2Fcdn.example.test%2Frender%3Fformat%3Dwebp"
                        "&amp;where=image"
                    ),
                    "thumbnail": (
                        "https://search.naver.test/thumb?"
                        "u=https%3A%2F%2Fcdn.example.test%2Fthumb%3Ffm%3Djpg"
                    ),
                    "sizeheight": "900",
                    "sizewidth": "700",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU official profile", policy)

    assert evidence[0].data["image_url"] == "https://cdn.example.test/render?format=webp"
    assert evidence[0].data["thumbnail_url"] == "https://cdn.example.test/thumb?fm=jpg"
    assert evidence[0].data["result_url"] == "https://cdn.example.test/render?format=webp"


def test_naver_image_results_unwrap_scheme_less_proxy_query_format_image_urls():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official profile",
                    "link": (
                        "https://search.naver.test/proxy?"
                        "url=cdn.example.test%2Frender%3Fformat%3Dwebp"
                        "&amp;where=image"
                    ),
                    "thumbnail": (
                        "https://search.naver.test/thumb?"
                        "u=cdn.example.test%2Fthumb%3Ffm%3Djpg"
                    ),
                    "sizeheight": "900",
                    "sizewidth": "700",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU official profile", policy)

    assert evidence[0].data["image_url"] == "https://cdn.example.test/render?format=webp"
    assert evidence[0].data["thumbnail_url"] == "https://cdn.example.test/thumb?fm=jpg"
    assert evidence[0].data["result_url"] == "https://cdn.example.test/render?format=webp"


def test_naver_image_results_unwrap_redirect_page_urls():
    client = FakeNaverSearchClient(
        response={
            "items": [
                {
                    "title": "IU official profile",
                    "link": "https://cdn.example.test/iu-profile.png",
                    "thumbnail": "https://cdn.example.test/iu-thumb.jpg",
                    "page_url": (
                        "https://search.naver.test/rd?"
                        "url=https%3A%2F%2Fexample.test%2Fprofile-page"
                        "&amp;where=image"
                    ),
                    "sizeheight": "900",
                    "sizewidth": "700",
                }
            ]
        }
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "IU official profile", policy)

    assert evidence[0].data["result_url"] == "https://example.test/profile-page"


def test_empty_naver_results_are_visible_evidence():
    adapter = NaverSearchAdapter(FakeNaverSearchClient(response={"items": []}))
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search("submission-1", "unknown query", policy)

    assert evidence[0].source == EvidenceSource.NAVER_SEARCH
    assert evidence[0].reason == "Naver search returned no results"
    assert evidence[0].confidence == 0.0


def test_blog_search_results_are_mapped_as_page_evidence():
    client = FakeNaverSearchClient(
        response={"items": []},
        blog_response={
            "items": [
                {
                    "title": "IU official profile blog",
                    "description": "profile image",
                    "link": "https://example.test/blog-post",
                    "bloggername": "official blog",
                    "bloggerlink": "https://blog.example.test",
                    "postdate": "20260527",
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_pages("submission-1", "IU official profile", policy)

    assert client.blog_calls == ["IU official profile"]
    assert evidence[0].source == EvidenceSource.NAVER_SEARCH
    assert evidence[0].reason == "Naver blog search result found"
    assert evidence[0].data["query_signature"] == "naver-blog:iu official profile"
    assert evidence[0].data["provider"] == "naver"
    assert evidence[0].data["search_type"] == "blog"
    assert evidence[0].data["result_url"] == "https://example.test/blog-post"
    assert evidence[0].data["match"] == "page"


def test_blog_search_results_preserve_provider_image_hints_as_page_candidates():
    client = FakeNaverSearchClient(
        response={"items": []},
        blog_response={
            "items": [
                {
                    "title": "IU official profile blog",
                    "description": "profile image",
                    "link": "https://example.test/blog-post",
                    "thumbnail": "https://postfiles.pstatic.net/profile-thumb.jpg?type=w966",
                    "bloggername": "official blog",
                    "bloggerlink": "https://blog.example.test",
                    "postdate": "20260527",
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_pages("submission-1", "IU official profile", policy)

    assert evidence[0].data["page_image_urls"] == [
        "https://postfiles.pstatic.net/profile-thumb.jpg?type=w966"
    ]


def test_blog_search_results_unwrap_redirect_result_urls():
    client = FakeNaverSearchClient(
        response={"items": []},
        blog_response={
            "items": [
                {
                    "title": "IU official profile blog",
                    "description": "profile image",
                    "link": (
                        "https://search.naver.test/rd?"
                        "url=https%3A%2F%2Fexample.test%2Fblog-post"
                        "&amp;where=blog"
                    ),
                    "bloggername": "official blog",
                    "bloggerlink": "https://blog.example.test",
                    "postdate": "20260527",
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_pages("submission-1", "IU official profile", policy)

    assert evidence[0].data["result_url"] == "https://example.test/blog-post"


def test_web_search_results_are_mapped_as_page_evidence():
    client = FakeNaverSearchClient(
        response={"items": []},
        web_response={
            "items": [
                {
                    "title": "IU official profile page",
                    "description": "profile image",
                    "link": "https://example.test/web-profile",
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_web_pages("submission-1", "IU official profile", policy)

    assert client.web_calls == ["IU official profile"]
    assert evidence[0].source == EvidenceSource.NAVER_SEARCH
    assert evidence[0].reason == "Naver web search result found"
    assert evidence[0].data["query_signature"] == "naver-web:iu official profile"
    assert evidence[0].data["provider"] == "naver"
    assert evidence[0].data["search_type"] == "web"
    assert evidence[0].data["result_url"] == "https://example.test/web-profile"
    assert evidence[0].data["match"] == "page"


def test_web_search_results_preserve_provider_image_hints_as_page_candidates():
    client = FakeNaverSearchClient(
        response={"items": []},
        web_response={
            "items": [
                {
                    "title": "IU official profile page",
                    "description": "profile image",
                    "link": "https://example.test/web-profile",
                    "imageUrl": "//cdn.example.test/profile.webp",
                    "thumbnailUrl": "https://cdn.example.test/profile-thumb?format=webp",
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_web_pages("submission-1", "IU official profile", policy)

    assert evidence[0].data["page_image_urls"] == [
        "https://cdn.example.test/profile.webp",
        "https://cdn.example.test/profile-thumb?format=webp",
    ]


def test_web_search_results_unwrap_redirect_result_urls():
    client = FakeNaverSearchClient(
        response={"items": []},
        web_response={
            "items": [
                {
                    "title": "IU official profile page",
                    "description": "profile image",
                    "link": (
                        "https://search.naver.test/rd?"
                        "u=https%3A%2F%2Fexample.test%2Fweb-profile"
                        "&amp;where=web"
                    ),
                }
            ]
        },
    )
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    evidence = adapter.search_web_pages("submission-1", "IU official profile", policy)

    assert evidence[0].data["result_url"] == "https://example.test/web-profile"


def test_blocked_policy_makes_no_naver_client_call():
    client = FakeNaverSearchClient(response={"items": []})
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(disabled=True, compliance_approved=True)

    evidence = adapter.search("submission-1", "IU album cover", policy)

    assert client.calls == []
    assert evidence[0].source == EvidenceSource.SEARCH_SKIPPED
    assert evidence[0].reason == "search API disabled"


def test_naver_adapter_reserves_configured_page_calls_before_search():
    client = FakeNaverSearchClient(response={"items": []})
    client.image_pages = 2
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(
        compliance_approved=True,
        allowed_providers={"naver"},
        daily_limit=1,
    )

    evidence = adapter.search("submission-1", "IU album cover", policy)

    assert client.calls == []
    assert evidence[0].source == EvidenceSource.SEARCH_SKIPPED
    assert evidence[0].reason == "search API usage limit reached"


def test_blocked_policy_makes_no_naver_blog_client_call():
    client = FakeNaverSearchClient(blog_response={"items": []})
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(disabled=True, compliance_approved=True)

    evidence = adapter.search_pages("submission-1", "IU official profile", policy)

    assert client.blog_calls == []
    assert evidence[0].source == EvidenceSource.SEARCH_SKIPPED
    assert evidence[0].data["query_signature"] == "naver-blog:iu official profile"


def test_blocked_policy_makes_no_naver_web_client_call():
    client = FakeNaverSearchClient(web_response={"items": []})
    adapter = NaverSearchAdapter(client)
    policy = SearchApiPolicy(disabled=True, compliance_approved=True)

    evidence = adapter.search_web_pages("submission-1", "IU official profile", policy)

    assert client.web_calls == []
    assert evidence[0].source == EvidenceSource.SEARCH_SKIPPED
    assert evidence[0].data["query_signature"] == "naver-web:iu official profile"


def test_naver_open_api_client_calls_blog_endpoint_with_same_credentials():
    class FakeTransport:
        def __init__(self):
            self.calls = []

        def request_json(self, method, url, headers=None, payload=None, timeout=10):
            self.calls.append({"method": method, "url": url, "headers": headers or {}})
            return {"items": []}

    transport = FakeTransport()
    client = NaverOpenApiSearchClient(
        client_id="naver-id",
        client_secret="naver-secret",
        transport=transport,
        blog_display=3,
    )

    client.search_blog("IU official profile")

    call = transport.calls[0]
    assert call["method"] == "GET"
    assert call["url"].startswith("https://openapi.naver.com/v1/search/blog?")
    assert "query=IU+official+profile" in call["url"]
    assert "display=3" in call["url"]
    assert call["headers"]["X-Naver-Client-Id"] == "naver-id"
    assert call["headers"]["X-Naver-Client-Secret"] == "naver-secret"


def test_naver_open_api_client_merges_configured_image_pages_with_incremented_start():
    class PagingTransport:
        def __init__(self):
            self.calls = []

        def request_json(self, method, url, headers=None, payload=None, timeout=10):
            self.calls.append({"method": method, "url": url, "headers": headers or {}})
            if "start=3" in url:
                return {
                    "items": [
                        {
                            "title": "page 2",
                            "link": "https://example.test/page-2.jpg",
                        }
                    ]
                }
            return {
                "items": [
                    {
                        "title": "page 1",
                        "link": "https://example.test/page-1.jpg",
                    }
                ]
            }

    transport = PagingTransport()
    client = NaverOpenApiSearchClient(
        client_id="naver-id",
        client_secret="naver-secret",
        transport=transport,
        display=2,
        image_pages=2,
    )

    response = client.search_image("IU official profile")

    assert [item["link"] for item in response["items"]] == [
        "https://example.test/page-1.jpg",
        "https://example.test/page-2.jpg",
    ]
    assert "start=1" in transport.calls[0]["url"]
    assert "start=3" in transport.calls[1]["url"]


def test_naver_open_api_client_calls_web_endpoint_with_same_credentials():
    class FakeTransport:
        def __init__(self):
            self.calls = []

        def request_json(self, method, url, headers=None, payload=None, timeout=10):
            self.calls.append({"method": method, "url": url, "headers": headers or {}})
            return {"items": []}

    transport = FakeTransport()
    client = NaverOpenApiSearchClient(
        client_id="naver-id",
        client_secret="naver-secret",
        transport=transport,
        web_display=3,
    )

    client.search_web("IU official profile")

    call = transport.calls[0]
    assert call["method"] == "GET"
    assert call["url"].startswith("https://openapi.naver.com/v1/search/webkr?")
    assert "query=IU+official+profile" in call["url"]
    assert "display=3" in call["url"]
    assert call["headers"]["X-Naver-Client-Id"] == "naver-id"
    assert call["headers"]["X-Naver-Client-Secret"] == "naver-secret"


def test_naver_adapter_rejects_image_payload_input():
    adapter = NaverSearchAdapter(FakeNaverSearchClient())
    policy = SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"})

    try:
        adapter.search(
            "submission-1",
            ImagePayload(content=b"image", width=10, height=10),
            policy,
        )
    except ValueError as error:
        assert "text query" in str(error)
    else:
        raise AssertionError("expected text-only query rejection")


def test_naver_evidence_can_be_stored_with_existing_analysis_run():
    repo = InMemoryRightsFilterRepository()
    run = AnalysisRun.for_submission("submission-1", "v1")
    evidence = NaverSearchAdapter(
        FakeNaverSearchClient(response={"items": [{"title": "IU", "link": "url"}]})
    ).search(
        "submission-1",
        "IU",
        SearchApiPolicy(compliance_approved=True, allowed_providers={"naver"}),
    )

    for item in evidence:
        run.add_evidence(item)
    repo.save_analysis_run(run)

    assert repo.analysis_runs_for_submission("submission-1")[0].evidence[0].source == (
        EvidenceSource.NAVER_SEARCH
    )
