"""Shared fixtures and test data for WorkingMemory tests."""

from typing import ClassVar

import pytest

from pipelex.core.concepts.concept_factory import ConceptFactory
from pipelex.core.concepts.native.concept_native import NativeConceptCode
from pipelex.core.domains.domain import SpecialDomain
from pipelex.core.memory.working_memory import WorkingMemory
from pipelex.core.memory.working_memory_factory import WorkingMemoryFactory
from pipelex.core.stuffs.document_content import DocumentContent
from pipelex.core.stuffs.html_content import HtmlContent
from pipelex.core.stuffs.image_content import ImageContent
from pipelex.core.stuffs.list_content import ListContent
from pipelex.core.stuffs.number_content import NumberContent
from pipelex.core.stuffs.stuff_factory import StuffFactory
from pipelex.core.stuffs.text_and_images_content import TextAndImagesContent
from pipelex.core.stuffs.text_content import TextContent
from tests.cases.documents import DocumentTestCases
from tests.cases.images import ImageTestCases


# Test data constants
class TestWorkingMemoryData:
    """Test data and constants for WorkingMemory tests."""

    # Sample text content
    SAMPLE_TEXT = """
    The Dawn of Ultra-Rapid Transit: NextGen High-Speed Trains Redefine Travel
    By Eliza Montgomery, Transportation Technology Reporter

    In an era where time is increasingly precious, a revolution in rail transportation is quietly
    transforming how we connect cities and regions. The emergence of ultra-high-speed train
    networks, capable of speeds exceeding 350 mph, promises to render certain short-haul
    flights obsolete while dramatically reducing carbon emissions.
    """

    # Test cases for different content types
    SINGLE_TEXT_CASE = "single_text"
    SINGLE_IMAGE_CASE = "single_image"
    SINGLE_DOCUMENT_CASE = "single_document"
    MULTIPLE_STUFF_CASE = "multiple_stuff"
    WITH_ALIASES_CASE = "with_aliases"
    COMPLEX_LIST_CASE = "complex_list"
    TEXT_AND_IMAGES_CASE = "text_and_images"
    HTML_CONTENT_CASE = "html_content"
    NUMBER_CONTENT_CASE = "number_content"

    TEST_CASES: ClassVar[list[tuple[str, str]]] = [
        ("Single text content", SINGLE_TEXT_CASE),
        ("Single image content", SINGLE_IMAGE_CASE),
        ("Single document content", SINGLE_DOCUMENT_CASE),
        ("Multiple stuff items", MULTIPLE_STUFF_CASE),
        ("WorkingMemory with aliases", WITH_ALIASES_CASE),
        ("Complex list content", COMPLEX_LIST_CASE),
        ("Text and images content", TEXT_AND_IMAGES_CASE),
        ("HTML content", HTML_CONTENT_CASE),
        ("Number content", NUMBER_CONTENT_CASE),
    ]


# Shared fixtures for all WorkingMemory tests


@pytest.fixture
def single_text_memory() -> WorkingMemory:
    """Create WorkingMemory with single text content."""
    return WorkingMemoryFactory.make_from_single_stuff(
        stuff=StuffFactory.make_stuff(
            concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT),
            name="sample_text",
            content=TextContent(text=TestWorkingMemoryData.SAMPLE_TEXT),
        ),
    )


@pytest.fixture
def single_image_memory() -> WorkingMemory:
    """Create WorkingMemory with single image content."""
    return WorkingMemoryFactory.make_from_single_stuff(
        stuff=StuffFactory.make_stuff(
            concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.IMAGE),
            name="sample_image",
            content=ImageContent(url=ImageTestCases.IMAGE_FILE_PATH_PNG_1),
        ),
    )


@pytest.fixture
def single_document_memory() -> WorkingMemory:
    """Create WorkingMemory with single document content."""
    return WorkingMemoryFactory.make_from_single_stuff(
        stuff=StuffFactory.make_stuff(
            concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.DOCUMENT),
            name="document_file",
            content=DocumentContent(url=DocumentTestCases.PDF_FILE_URL_1),
        ),
    )


@pytest.fixture
def multiple_stuff_memory() -> WorkingMemory:
    """Create WorkingMemory with multiple stuff items."""
    text_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT),
        name="question",
        content=TextContent(text="What are the aerodynamic features?"),
    )

    document_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT),
        name="document",
        content=TextContent(text=TestWorkingMemoryData.SAMPLE_TEXT),
    )

    image_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.IMAGE),
        name="diagram",
        content=ImageContent(url=ImageTestCases.IMAGE_FILE_PATH_PNG_1),
    )

    return WorkingMemoryFactory.make_from_multiple_stuffs(stuff_list=[text_stuff, document_stuff, image_stuff], main_name="document")


@pytest.fixture
def memory_with_aliases() -> WorkingMemory:
    """Create WorkingMemory with aliases."""
    text_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT),
        name="primary_text",
        content=TextContent(text="Primary content"),
    )

    secondary_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT),
        name="secondary_text",
        content=TextContent(text="Secondary content"),
    )

    memory = WorkingMemoryFactory.make_from_multiple_stuffs(stuff_list=[text_stuff, secondary_stuff], main_name="primary_text")
    memory.set_alias(alias="main_text", target="primary_text")
    memory.set_alias(alias="backup_text", target="secondary_text")

    return memory


@pytest.fixture
def complex_list_memory() -> WorkingMemory:
    """Create WorkingMemory with complex list content containing mixed types."""
    complex_content: ListContent[TextContent | ImageContent | NumberContent] = ListContent(
        items=[
            TextContent(text="The quick brown fox jumps over the lazy dog"),
            ImageContent(url=ImageTestCases.IMAGE_FILE_PATH_PNG_1),
            NumberContent(number=42.5),
        ],
    )

    complex_stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make(
            concept_code="List", domain_code=SpecialDomain.NATIVE, description="Lorem Ipsum", structure_class_name="ListContent"
        ),
        name="mixed_list",
        content=complex_content,
    )

    return WorkingMemoryFactory.make_from_single_stuff(stuff=complex_stuff)


@pytest.fixture
def text_and_images_memory() -> WorkingMemory:
    """Create WorkingMemory with text and images content."""
    text_and_images_content = TextAndImagesContent(
        text=TextContent(text="Project overview with diagrams"),
        images=[ImageContent(url=ImageTestCases.IMAGE_FILE_PATH_PNG_1), ImageContent(url=ImageTestCases.IMAGE_FILE_PATH_PNG_2)],
    )

    stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.TEXT_AND_IMAGES),
        name="project_overview",
        content=text_and_images_content,
    )

    return WorkingMemoryFactory.make_from_single_stuff(stuff=stuff)


@pytest.fixture
def html_content_memory() -> WorkingMemory:
    """Create WorkingMemory with HTML content."""
    html_content = HtmlContent(
        inner_html="<h1>Test Report</h1><p>This is a <strong>test</strong> report.</p><ul><li>Item 1</li><li>Item 2</li></ul>",
        css_class="report-content",
    )

    stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make(
            concept_code="Html", domain_code=SpecialDomain.NATIVE, description="Lorem Ipsum", structure_class_name="HtmlContent"
        ),
        name="test_report",
        content=html_content,
    )

    return WorkingMemoryFactory.make_from_single_stuff(stuff=stuff)


@pytest.fixture
def number_content_memory() -> WorkingMemory:
    """Create WorkingMemory with number content."""
    number_content = NumberContent(number=3.14159)

    stuff = StuffFactory.make_stuff(
        concept=ConceptFactory.make_native_concept(native_concept_code=NativeConceptCode.NUMBER),
        name="pi_value",
        content=number_content,
    )

    return WorkingMemoryFactory.make_from_single_stuff(stuff=stuff)
