"""Integration tests: images resource (including history).

Expensive tests (text_to_img, img_to_img, etc.) are marked with
``@pytest.mark.expensive`` and skipped by default.
"""

from __future__ import annotations

import pytest

from seaart import AsyncClient


# A publicly accessible test image
TEST_IMAGE_URL = "https://image.cdn2.seaart.me/2026-03-01/d6iaplte878c7394hke0/6df71b7525cde42de0ac8f45671524df_high.webp"


# ── Read-only ───────────────────────────────────────────────────────────────

class TestImagesReadOnly:
    async def test_get_download_url(self, client: AsyncClient) -> None:
        result = await client.images.get_download_url(TEST_IMAGE_URL)
        assert result.status.code == 10000
        assert result.value is not None

    async def test_upload_by_url(self, client: AsyncClient) -> None:
        result = await client.images.upload_by_url(TEST_IMAGE_URL)
        assert result.status.code == 10000
        assert result.value is not None

    async def test_estimate(self, client: AsyncClient, model_no: str) -> None:
        result = await client.images.estimate("a cute cat", model_no)
        assert result.status.code == 10000

    async def test_detail(self, client: AsyncClient) -> None:
        """detail() delegates to tasks.detail — needs a known task_id.
        We use history to find one, or skip."""
        history = await client.images.history.list_v2(limit=1)
        items = history.value.items if history.value else None
        if not items:
            pytest.skip("no history items to test detail()")
        result = await client.images.detail(items[0].id)  # type: ignore[arg-type]
        assert result.status.code == 10000


# ── History ─────────────────────────────────────────────────────────────────

class TestHistory:
    async def test_list(self, client: AsyncClient) -> None:
        result = await client.images.history.list()
        assert result.status.code == 10000

    async def test_list_v2(self, client: AsyncClient) -> None:
        result = await client.images.history.list_v2()
        assert result.status.code == 10000

    async def test_add_and_delete(self, client: AsyncClient) -> None:
        """Add an entry, then remove it."""
        add_result = await client.images.history.add(TEST_IMAGE_URL)
        assert add_result.status.code == 10000

        del_result = await client.images.history.delete(TEST_IMAGE_URL)
        assert del_result.status.code == 10000


# ── Upload ──────────────────────────────────────────────────────────────────

class TestUpload:
    async def test_upload_bytes(self, client: AsyncClient) -> None:
        from urllib.request import urlopen

        with urlopen(TEST_IMAGE_URL) as resp:  # noqa: S310
            image_bytes = resp.read()

        result = await client.images.upload(bytes_data=image_bytes, filename="test.webp")
        assert result.status.code == 10000
        assert result.value is not None


# ── Expensive (image generation) ────────────────────────────────────────────

@pytest.mark.expensive
class TestImagesExpensive:
    async def test_text_to_img(self, client: AsyncClient, model_no: str) -> None:
        result = await client.images.text_to_img(
            prompt="a cute cat, simple sketch",
            model_no=model_no,
            num_images=1,
        )
        assert result.status.code == 10000
        assert result.value is not None
        await result.wait()

    async def test_img_to_text(self, client: AsyncClient) -> None:
        result = await client.images.img_to_text(TEST_IMAGE_URL)
        assert result.status.code == 10000
        await result.wait()

    async def test_img_to_img(self, client: AsyncClient, model_no: str) -> None:
        result = await client.images.img_to_img(
            prompt="a cute cat, oil painting",
            model_no=model_no,
            image_url=TEST_IMAGE_URL,
            num_images=1,
        )
        assert result.status.code == 10000
        await result.wait()

    async def test_controlnet(self, client: AsyncClient, model_no: str) -> None:
        result = await client.images.controlnet(
            prompt="a cute cat",
            model_no=model_no,
            control_input_image=TEST_IMAGE_URL,
            num_images=1,
        )
        assert result.status.code == 10000
        await result.wait()

    async def test_smart_edit(self, client: AsyncClient) -> None:
        result = await client.images.smart_edit(
            prompt="add sunglasses",
            image_url=TEST_IMAGE_URL,
        )
        assert result.status.code == 10000
        await result.wait()

    async def test_upscale(self, client: AsyncClient, model_no: str) -> None:
        result = await client.images.upscale(
            image_url=TEST_IMAGE_URL,
            model_no=model_no,
        )
        assert result.status.code == 10000
        await result.wait()

    async def test_upscale_hd_fix(self, client: AsyncClient) -> None:
        result = await client.images.upscale_hd_fix(TEST_IMAGE_URL)
        assert result.status.code == 10000
        await result.wait()

    async def test_remove_bg(self, client: AsyncClient) -> None:
        result = await client.images.remove_bg(TEST_IMAGE_URL)
        assert result.status.code == 10000
        await result.wait()
