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

from __future__ import annotations

import json
from pathlib import Path

import pygit2
import pytest

from pygittools.tui.git_colors import init_tui_color_theme
from pygittools.tui.log_list import CommitLogList, _draw_entry, _format_entry, _LogEntry
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) -> None:
	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) -> None:
	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(0, 5, 80, 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)
	from unicurses import KEY_DOWN, KEY_RESIZE, KEY_UP

	log.handle_nav_key(KEY_DOWN, repo)
	log.handle_nav_key(KEY_UP, repo)
	log.handle_nav_key(KEY_RESIZE, repo)
	log.handle_nav_key(ord("x"), repo)


def test_draw_entry_uses_git_colors() -> None:
	init_tui_color_theme(None)
	entry = _LogEntry(short_id="abc1234", date="2026-01-01", subject="feat: hello")
	_draw_entry(0, 80, entry, focused=True, highlight=True)


def test_format_entry_truncates_long_subject() -> None:
	from pygittools.tui.log_list import _LogEntry

	entry = _LogEntry(short_id="abc1234", date="2026-01-01", subject="x" * 100)
	formatted = _format_entry(entry, 30)
	assert len(formatted) <= 30


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:
	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)