"""Shared fixtures for unit tests."""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any, Dict, List

import pytest


@pytest.fixture
def multi_choice_pkg_index() -> Dict[str, Any]:
    """Return package-index.json data for a small library set."""
    return {
        "H5P.MultiChoice": {
            "dir_name": "multi_choice",
            "flat_name":
                "byteb4rb1e_sphinxcontrib_h5p_multi_choice",
            "pip_name":
                "byteb4rb1e.sphinxcontrib.h5p.multi_choice",
            "vendor_name": "h5p-multi-choice",
        },
        "H5P.JoubelUI": {
            "dir_name": "joubel_ui",
            "flat_name":
                "byteb4rb1e_sphinxcontrib_h5p_joubel_ui",
            "pip_name":
                "byteb4rb1e.sphinxcontrib.h5p.joubel_ui",
            "vendor_name": "h5p-joubel-ui",
        },
        "FontAwesome": {
            "dir_name": "font_awesome",
            "flat_name":
                "byteb4rb1e_sphinxcontrib_h5p_font_awesome",
            "pip_name":
                "byteb4rb1e.sphinxcontrib.h5p.font_awesome",
            "vendor_name": "font-awesome",
        },
    }


@pytest.fixture
def pkg_index_file(
    tmp_path: Path,
    multi_choice_pkg_index: Dict[str, Any],
) -> Path:
    """Write package-index.json and return the file path."""
    data_dir = tmp_path / "data"
    data_dir.mkdir()
    path = data_dir / "package-index.json"
    path.write_text(
        json.dumps(
            multi_choice_pkg_index, indent=2, ensure_ascii=False,
        ),
        encoding="utf-8",
    )
    return path


@pytest.fixture
def lib_index_data() -> Dict[str, Any]:
    """Return library-index.json data with version entries and deps."""
    return {
        "H5P.MultiChoice": {
            "versions": {
                "1.16.0": {
                    "ref": "aaa0000000000000000000000000000000000000",
                    "dependencies": {
                        "FontAwesome": "4.5",
                        "H5P.JoubelUI": "1.3",
                    },
                },
                "1.16.22": {
                    "ref": "aaa1111111111111111111111111111111111111",
                    "dependencies": {
                        "FontAwesome": "4.5",
                        "H5P.JoubelUI": "1.3",
                    },
                },
                "1.15.3": {
                    "ref": "bbb0000000000000000000000000000000000000",
                    "dependencies": {
                        "FontAwesome": "4.5",
                    },
                },
            },
        },
        "H5P.JoubelUI": {
            "versions": {
                "1.3.11": {
                    "ref": "ccc0000000000000000000000000000000000000",
                    "dependencies": {
                        "FontAwesome": "4.5",
                    },
                },
            },
        },
        "FontAwesome": {
            "versions": {
                "4.5.6": {
                    "ref": "ddd0000000000000000000000000000000000000",
                    "dependencies": {},
                },
            },
        },
    }


@pytest.fixture
def lib_index_file(
    tmp_path: Path,
    lib_index_data: Dict[str, Any],
) -> Path:
    """Write library-index.json and return the file path."""
    data_dir = tmp_path / "data"
    data_dir.mkdir(exist_ok=True)
    path = data_dir / "library-index.json"
    path.write_text(
        json.dumps(
            lib_index_data, indent=2, ensure_ascii=False,
        ),
        encoding="utf-8",
    )
    return path


# -------------------------------------------------------------------
# Build pipeline fixtures
# -------------------------------------------------------------------

@pytest.fixture
def true_false_library_json() -> Dict[str, Any]:
    """Return H5P.TrueFalse library.json data."""
    return {
        "title": "True/False Question",
        "machineName": "H5P.TrueFalse",
        "majorVersion": 1,
        "minorVersion": 8,
        "patchVersion": 0,
        "runnable": 1,
        "preloadedJs": [
            {"path": "js/h5p-true-false.js"},
        ],
        "preloadedCss": [
            {"path": "css/h5p-true-false.css"},
        ],
    }


@pytest.fixture
def font_awesome_library_json() -> Dict[str, Any]:
    """Return FontAwesome library.json data (non-runnable)."""
    return {
        "title": "FontAwesome",
        "machineName": "FontAwesome",
        "majorVersion": 4,
        "minorVersion": 5,
        "patchVersion": 4,
        "runnable": 0,
        "preloadedCss": [
            {"path": "css/font-awesome.min.css"},
            {"path": "css/override.css"},
        ],
    }


@pytest.fixture
def true_false_pyproject(tmp_path: Path) -> Path:
    """Write a minimal pyproject.toml with [tool.h5p] and return path."""
    content = """\
[project]
name = "byteb4rb1e.sphinxcontrib.h5p.true_false"

[tool.h5p]
machine_name = "H5P.TrueFalse"

[tool.h5p.vendor]
"H5P.TrueFalse" = "vendor/h5p-true-false"
"FontAwesome" = "vendor/font-awesome"
"""
    path = tmp_path / "pyproject.toml"
    path.write_text(content, encoding="utf-8")
    return path


@pytest.fixture
def true_false_vendor_dir(
    tmp_path: Path,
    true_false_library_json: Dict[str, Any],
) -> Path:
    """Create a vendor dir with library.json + semantics.json."""
    vendor = tmp_path / "vendor" / "h5p-true-false"
    vendor.mkdir(parents=True)
    (vendor / "library.json").write_text(
        json.dumps(true_false_library_json, indent=2),
        encoding="utf-8",
    )
    (vendor / "semantics.json").write_text(
        json.dumps(_TRUE_FALSE_SEMANTICS, indent=2),
        encoding="utf-8",
    )
    return vendor


_TRUE_FALSE_SEMANTICS: List[Dict[str, Any]] = [
    {
        "name": "media",
        "type": "group",
        "label": "Media",
        "importance": "medium",
        "fields": [
            {
                "name": "type",
                "type": "library",
                "label": "Type",
                "importance": "medium",
                "options": [
                    "H5P.Image 1.1",
                    "H5P.Video 1.6",
                ],
                "optional": True,
            },
        ],
    },
    {
        "name": "question",
        "type": "text",
        "widget": "html",
        "label": "Question",
        "importance": "high",
    },
    {
        "name": "correct",
        "type": "select",
        "label": "Correct answer",
        "importance": "high",
        "options": [
            {"value": "true", "label": "True"},
            {"value": "false", "label": "False"},
        ],
        "default": "true",
    },
    {
        "name": "l10n",
        "type": "group",
        "common": True,
        "label": "User interface translations",
        "importance": "low",
        "fields": [
            {
                "name": "trueText",
                "type": "text",
                "label": "True label",
                "default": "True",
            },
        ],
    },
    {
        "name": "behaviour",
        "type": "group",
        "label": "Behavioural settings",
        "importance": "low",
        "fields": [
            {
                "name": "enableRetry",
                "type": "boolean",
                "label": "Enable Retry",
                "default": True,
            },
            {
                "name": "enableSolutionsButton",
                "type": "boolean",
                "label": "Enable Show Solution",
                "default": True,
            },
            {
                "name": "confirmCheckDialog",
                "type": "boolean",
                "label": "Show confirmation on Check",
                "default": False,
            },
            {
                "name": "autoCheck",
                "type": "boolean",
                "label": "Automatically check answer",
                "default": False,
            },
            {
                "name": "feedbackOnCorrect",
                "type": "text",
                "label": "Feedback on correct",
                "optional": True,
            },
            {
                "name": "feedbackOnWrong",
                "type": "text",
                "label": "Feedback on wrong",
                "optional": True,
            },
        ],
    },
]
