from __future__ import annotations

from pathlib import Path
from typing import Literal

import pytest
from PySide6 import QtWidgets
from PySide6.QtCore import Qt
from pytestqt.qtbot import QtBot

from ..conftest import assert_labelfile_sanity
from ..conftest import close_or_pause
from .conftest import MainWinFactory
from .conftest import show_window_and_wait_for_imagedata


@pytest.mark.gui
def test_MainWindow_open_img(
    main_win: MainWinFactory,
    qtbot: QtBot,
    data_path: Path,
    pause: bool,
) -> None:
    image_file: str = str(data_path / "raw/2011_000003.jpg")
    win = main_win(file_or_dir=image_file)
    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)

    close_or_pause(qtbot=qtbot, widget=win, pause=pause)


@pytest.mark.gui
def test_MainWindow_open_json(
    main_win: MainWinFactory,
    qtbot: QtBot,
    data_path: Path,
    pause: bool,
) -> None:
    json_files: list[str] = [
        str(data_path / "annotated_with_data/apc2016_obj3.json"),
        str(data_path / "annotated/2011_000003.json"),
    ]
    json_file: str
    for json_file in json_files:
        assert_labelfile_sanity(json_file)

        win = main_win(file_or_dir=json_file)
        show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)

        close_or_pause(qtbot=qtbot, widget=win, pause=pause)


@pytest.mark.gui
@pytest.mark.parametrize("scenario", ["raw", "annotated", "annotated_nested"])
def test_MainWindow_open_dir(
    main_win: MainWinFactory,
    qtbot: QtBot,
    scenario: Literal["raw", "annotated", "annotated_nested"],
    data_path: Path,
    pause: bool,
) -> None:
    directory: str
    output_dir: str | None
    if scenario == "annotated_nested":
        directory = str(data_path / "annotated_nested" / "images")
        output_dir = str(data_path / "annotated_nested" / "annotations")
    else:
        directory = str(data_path / scenario)
        output_dir = None

    win = main_win(file_or_dir=directory, output_dir=output_dir)
    show_window_and_wait_for_imagedata(qtbot=qtbot, win=win)

    first_image_name: str = "2011_000003.jpg"
    second_image_name: str = "2011_000006.jpg"

    assert win._image_path
    assert Path(win._image_path).name == first_image_name
    win._open_prev_image()
    qtbot.wait(100)
    assert Path(win._image_path).name == first_image_name

    win._open_next_image()
    qtbot.wait(100)
    assert Path(win._image_path).name == second_image_name
    win._open_prev_image()
    qtbot.wait(100)
    assert Path(win._image_path).name == first_image_name

    assert win._docks.file_list.count() == 3
    expected_check_state = (
        Qt.CheckState.Checked
        if scenario.startswith("annotated")
        else Qt.CheckState.Unchecked
    )
    for index in range(win._docks.file_list.count()):
        item: QtWidgets.QListWidgetItem | None = win._docks.file_list.item(index)
        assert item
        assert item.checkState() == expected_check_state

    close_or_pause(qtbot=qtbot, widget=win, pause=pause)
