"""Tests for Workbook class."""

import os
import tempfile

import pytest

from py_xmind16.workbook import Workbook, load_workbook
from py_xmind16.sheet import Sheet
from py_xmind16.topic import Topic
from py_xmind16.exceptions import ParseError


class TestWorkbookCreation:
    """Tests for workbook creation."""
    
    def test_create_empty_workbook(self):
        """Test creating an empty workbook."""
        workbook = Workbook()
        assert workbook.id is not None
        assert len(workbook.id) == 32
        assert workbook.sheet_count == 0
        assert workbook.sheets == []
    
    def test_create_workbook_with_id(self):
        """Test creating a workbook with a specific ID."""
        custom_id = "custom123"
        workbook = Workbook(id=custom_id)
        assert workbook.id == custom_id


class TestWorkbookSheetManagement:
    """Tests for workbook sheet management."""
    
    def test_create_sheet(self):
        """Test creating a sheet in the workbook."""
        workbook = Workbook()
        sheet = workbook.create_sheet("My Sheet")
        
        assert sheet.title == "My Sheet"
        assert sheet in workbook.sheets
        assert workbook.sheet_count == 1
    
    def test_create_multiple_sheets(self):
        """Test creating multiple sheets."""
        workbook = Workbook()
        sheet1 = workbook.create_sheet("Sheet 1")
        sheet2 = workbook.create_sheet("Sheet 2")
        
        assert workbook.sheet_count == 2
        assert sheet1 in workbook.sheets
        assert sheet2 in workbook.sheets
    
    def test_add_sheet(self):
        """Test adding an existing sheet."""
        workbook = Workbook()
        sheet = Sheet(title="External Sheet")
        workbook.add_sheet(sheet)
        
        assert sheet in workbook.sheets
        assert workbook.sheet_count == 1
    
    def test_remove_sheet(self):
        """Test removing a sheet."""
        workbook = Workbook()
        sheet = workbook.create_sheet()
        
        result = workbook.remove_sheet(sheet)
        
        assert result is True
        assert sheet not in workbook.sheets
        assert workbook.sheet_count == 0
    
    def test_remove_nonexistent_sheet(self):
        """Test removing a sheet that doesn't exist."""
        workbook = Workbook()
        external_sheet = Sheet()
        
        result = workbook.remove_sheet(external_sheet)
        
        assert result is False
    
    def test_get_sheet_by_index(self):
        """Test getting a sheet by index."""
        workbook = Workbook()
        sheet = workbook.create_sheet("Target")
        
        found = workbook.get_sheet(0)
        
        assert found == sheet
    
    def test_get_sheet_invalid_index(self):
        """Test getting a sheet with invalid index."""
        workbook = Workbook()
        
        assert workbook.get_sheet(0) is None
        assert workbook.get_sheet(-1) is None
        assert workbook.get_sheet(100) is None
    
    def test_get_sheet_by_title(self):
        """Test finding a sheet by title."""
        workbook = Workbook()
        sheet = workbook.create_sheet("Target Sheet")
        workbook.create_sheet("Other Sheet")
        
        found = workbook.get_sheet_by_title("Target Sheet")
        
        assert found == sheet
    
    def test_get_sheet_by_title_not_found(self):
        """Test finding a nonexistent sheet by title."""
        workbook = Workbook()
        workbook.create_sheet()
        
        found = workbook.get_sheet_by_title("Nonexistent")
        
        assert found is None


class TestWorkbookSaveLoad:
    """Tests for workbook save and load operations."""
    
    def test_save_and_load(self):
        """Test saving and loading a workbook."""
        workbook = Workbook()
        sheet = workbook.create_sheet("Test Sheet")
        root = sheet.get_root_topic()
        root.title = "Root Topic"
        root.add_subtopic("Child 1")
        root.add_subtopic("Child 2")
        
        with tempfile.NamedTemporaryFile(suffix='.xmind', delete=False) as f:
            temp_path = f.name
        
        try:
            workbook.save(temp_path)
            assert os.path.exists(temp_path)
            
            loaded = Workbook.load(temp_path)
            assert loaded.sheet_count == 1
            assert loaded.get_sheet(0).title == "Test Sheet"
            assert loaded.get_sheet(0).root_topic.title == "Root Topic"
            assert len(loaded.get_sheet(0).root_topic.subtopics) == 2
        finally:
            if os.path.exists(temp_path):
                os.remove(temp_path)
    
    def test_save_creates_default_sheet(self):
        """Test that save creates a default sheet if none exists."""
        workbook = Workbook()
        
        with tempfile.NamedTemporaryFile(suffix='.xmind', delete=False) as f:
            temp_path = f.name
        
        try:
            workbook.save(temp_path)
            
            loaded = Workbook.load(temp_path)
            assert loaded.sheet_count == 1
        finally:
            if os.path.exists(temp_path):
                os.remove(temp_path)
    
    def test_load_nonexistent_file(self):
        """Test loading a nonexistent file."""
        with pytest.raises(ParseError):
            Workbook.load("/nonexistent/path/file.xmind")
    
    def test_to_bytes_and_from_bytes(self):
        """Test converting workbook to bytes and back."""
        workbook = Workbook()
        sheet = workbook.create_sheet("Test")
        sheet.get_root_topic().title = "Root"
        
        data = workbook.to_bytes()
        assert isinstance(data, bytes)
        assert len(data) > 0
        
        loaded = Workbook.from_bytes(data)
        assert loaded.sheet_count == 1
        assert loaded.get_sheet(0).title == "Test"


class TestLoadWorkbookFunction:
    """Tests for load_workbook convenience function."""
    
    def test_load_workbook_function(self):
        """Test the load_workbook convenience function."""
        original = Workbook()
        sheet = original.create_sheet("Test Sheet")
        sheet.get_root_topic().title = "Root"
        
        with tempfile.NamedTemporaryFile(suffix='.xmind', delete=False) as f:
            temp_path = f.name
        
        try:
            original.save(temp_path)
            
            loaded = load_workbook(temp_path)
            assert loaded.sheet_count == 1
            assert loaded.get_sheet(0).title == "Test Sheet"
        finally:
            if os.path.exists(temp_path):
                os.remove(temp_path)


class TestWorkbookRepresentation:
    """Tests for workbook string representation."""
    
    def test_repr(self):
        """Test workbook representation."""
        workbook = Workbook(id="1234567890abcdef")
        workbook.create_sheet()
        workbook.create_sheet()
        
        repr_str = repr(workbook)
        assert "Workbook" in repr_str
        assert "sheets=2" in repr_str
