"""Tests for project label and commit log helpers."""

from __future__ import annotations

import json
from pathlib import Path
from unittest.mock import MagicMock

import pygit2
import pytest
from pyratatui import Rect

from pygittools.tui.keys import key
from pygittools.tui.log_list import CommitLogList
from pygittools.tui.project_label import repo_project_label

SIG = pygit2.Signature("t", "t@example.com", 0)


def test_repo_project_label_falls_back_to_worktree(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	settings = tmp_path / "settings.json"
	settings.write_text(json.dumps({"PROJECTROOT": str(tmp_path / "projects")}), encoding="utf-8")
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(settings))
	repo_dir = tmp_path / "standalone"
	repo_dir.mkdir()
	pygit2.init_repository(str(repo_dir), bare=False)
	assert repo_project_label(repo_dir) == str(repo_dir.resolve())


def test_repo_project_label_uses_worktree_for_git_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	settings = tmp_path / "settings.json"
	settings.write_text(json.dumps({"PROJECTROOT": str(tmp_path / "projects")}), encoding="utf-8")
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(settings))
	repo_dir = tmp_path / "pygitweb"
	repo_dir.mkdir()
	repo = pygit2.init_repository(str(repo_dir), bare=False)
	assert repo_project_label(Path(repo.path)) == str(repo_dir.resolve())


def test_commit_log_list_loads_head_commit(tmp_path: Path) -> None:
	repo = pygit2.init_repository(str(tmp_path / "repo"), bare=False)
	tree = repo.index.write_tree()
	repo.create_commit("HEAD", SIG, SIG, "feat: first", tree, [])
	log = CommitLogList()
	log.refresh(repo)
	assert str(repo.head.target)[:7] in log.status_hint()


def test_commit_log_list_empty_repo(repo: pygit2.Repository) -> None:
	log = CommitLogList()
	log.refresh(repo)
	assert log.status_hint() == "No commits — j/k move"
	log.draw(MagicMock(), Rect(0, 0, 80, 5), highlight=True)


def test_commit_log_list_navigation(tmp_path: Path) -> None:
	repo = pygit2.init_repository(str(tmp_path / "repo"), bare=False)
	tree = repo.index.write_tree()
	repo.create_commit("HEAD", SIG, SIG, "one", tree, [])
	log = CommitLogList()
	log.refresh(repo)
	log.handle_nav_key(key("Down"), repo)
	log.handle_nav_key(key("Up"), repo)
	log.handle_nav_key(key("x"), repo)


def test_load_entries_without_head(repo: pygit2.Repository) -> None:
	from pygit2 import init_repository

	from pygittools.tui.log_list import _load_entries

	empty = init_repository(str(Path(repo.workdir).parent / "bare"), bare=True)
	assert _load_entries(empty) == []


def test_repo_project_label_under_projectroot(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	monkeypatch.delenv("PYGITWEB_PROJECTROOT", raising=False)
	root = tmp_path / "root"
	project = root / "demo"
	project.mkdir(parents=True)
	pygit2.init_repository(str(project), bare=False)
	settings = tmp_path / "settings.json"
	settings.write_text(json.dumps({"PROJECTROOT": str(root)}), encoding="utf-8")
	monkeypatch.setenv("PYGITWEB_SETTINGS_CONFIG", str(settings))
	assert repo_project_label(project) == "demo"


def test_repo_project_label_oserror_falls_back(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
	repo_dir = tmp_path / "standalone"
	repo_dir.mkdir()
	pygit2.init_repository(str(repo_dir), bare=False)
	monkeypatch.setattr(
		"pygittools.tui.project_label.load_pygitweb_layout",
		lambda: (_ for _ in ()).throw(OSError("missing")),
	)
	assert repo_project_label(repo_dir) == str(repo_dir.resolve())


@pytest.fixture
def repo(tmp_path: Path) -> pygit2.Repository:
	repo_path = tmp_path / "repo"
	repo_path.mkdir()
	return pygit2.init_repository(str(repo_path), bare=False)