"""Unit test for NFOService.update_tvshow_nfo() - tests XML parsing logic."""

import asyncio
import logging
import shutil
import tempfile
from pathlib import Path

import pytest
from lxml import etree

logger = logging.getLogger(__name__)

from src.core.services.nfo_service import NFOService
from src.core.services.tmdb_client import TMDBAPIError


def create_sample_nfo(tmdb_id: int = 1429) -> str:
    """Create a sample NFO XML with TMDB ID."""
    return f'''<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
    <title>Attack on Titan</title>
    <originaltitle>Shingeki no Kyojin</originaltitle>
    <year>2013</year>
    <plot>Several hundred years ago, humans were nearly exterminated by Titans.</plot>
    <uniqueid type="tmdb" default="false">{tmdb_id}</uniqueid>
    <uniqueid type="tvdb" default="true">267440</uniqueid>
    <tmdbid>{tmdb_id}</tmdbid>
    <tvdbid>267440</tvdbid>
</tvshow>'''


def test_parse_nfo_with_uniqueid():
    """Test parsing NFO with uniqueid elements."""
    # Create temporary directory structure
    temp_dir = Path(tempfile.mkdtemp())
    serie_folder = temp_dir / "test_series"
    serie_folder.mkdir()
    nfo_path = serie_folder / "tvshow.nfo"
    
    try:
        # Write sample NFO
        nfo_path.write_text(create_sample_nfo(1429), encoding="utf-8")
        
        # Parse it (same logic as in update_tvshow_nfo)
        tree = etree.parse(str(nfo_path))
        root = tree.getroot()
        
        # Extract TMDB ID
        tmdb_id = None
        for uniqueid in root.findall(".//uniqueid"):
            if uniqueid.get("type") == "tmdb":
                tmdb_id = int(uniqueid.text)
                break
        
        assert tmdb_id == 1429, f"Expected TMDB ID 1429, got {tmdb_id}"
        logger.info("Successfully parsed TMDB ID from uniqueid: %s", tmdb_id)
        
    finally:
        shutil.rmtree(temp_dir)


def test_parse_nfo_with_tmdbid_element():
    """Test parsing NFO with tmdbid element (fallback)."""
    # Create NFO without uniqueid but with tmdbid element
    nfo_content = '''<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
    <title>Test Show</title>
    <tmdbid>12345</tmdbid>
</tvshow>'''
    
    temp_dir = Path(tempfile.mkdtemp())
    serie_folder = temp_dir / "test_series"
    serie_folder.mkdir()
    nfo_path = serie_folder / "tvshow.nfo"
    
    try:
        nfo_path.write_text(nfo_content, encoding="utf-8")
        
        # Parse it
        tree = etree.parse(str(nfo_path))
        root = tree.getroot()
        
        # Try uniqueid first (should fail)
        tmdb_id = None
        for uniqueid in root.findall(".//uniqueid"):
            if uniqueid.get("type") == "tmdb":
                tmdb_id = int(uniqueid.text)
                break
        
        # Fallback to tmdbid element
        if tmdb_id is None:
            tmdbid_elem = root.find(".//tmdbid")
            if tmdbid_elem is not None and tmdbid_elem.text:
                tmdb_id = int(tmdbid_elem.text)
        
        assert tmdb_id == 12345, f"Expected TMDB ID 12345, got {tmdb_id}"
        logger.info("Successfully parsed TMDB ID from tmdbid element: %s", tmdb_id)
        
    finally:
        shutil.rmtree(temp_dir)


def test_parse_nfo_without_tmdb_id():
    """Test parsing NFO without TMDB ID raises appropriate error."""
    # Create NFO without any TMDB ID
    nfo_content = '''<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
    <title>Test Show</title>
</tvshow>'''
    
    temp_dir = Path(tempfile.mkdtemp())
    serie_folder = temp_dir / "test_series"
    serie_folder.mkdir()
    nfo_path = serie_folder / "tvshow.nfo"
    
    try:
        nfo_path.write_text(nfo_content, encoding="utf-8")
        
        # Parse it
        tree = etree.parse(str(nfo_path))
        root = tree.getroot()
        
        # Try to extract TMDB ID
        tmdb_id = None
        for uniqueid in root.findall(".//uniqueid"):
            if uniqueid.get("type") == "tmdb":
                tmdb_id = int(uniqueid.text)
                break
        
        if tmdb_id is None:
            tmdbid_elem = root.find(".//tmdbid")
            if tmdbid_elem is not None and tmdbid_elem.text:
                tmdb_id = int(tmdbid_elem.text)
        
        assert tmdb_id is None, "Should not have found TMDB ID"
        logger.info("Correctly identified NFO without TMDB ID")
        
    finally:
        shutil.rmtree(temp_dir)


def test_parse_invalid_xml():
    """Test parsing invalid XML raises appropriate error."""
    nfo_content = '''<?xml version="1.0" encoding="UTF-8"?>
<tvshow>
    <title>Unclosed tag
</tvshow>'''
    
    temp_dir = Path(tempfile.mkdtemp())
    serie_folder = temp_dir / "test_series"
    serie_folder.mkdir()
    nfo_path = serie_folder / "tvshow.nfo"
    
    try:
        nfo_path.write_text(nfo_content, encoding="utf-8")
        
        # Try to parse - should raise XMLSyntaxError
        try:
            tree = etree.parse(str(nfo_path))
            assert False, "Should have raised XMLSyntaxError"
        except etree.XMLSyntaxError:
            logger.info("Correctly raised XMLSyntaxError for invalid XML")
        
    finally:
        shutil.rmtree(temp_dir)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, format="%(message)s")
    logger.info("Testing NFO XML parsing logic...")
    logger.info("")

    test_parse_nfo_with_uniqueid()
    test_parse_nfo_with_tmdbid_element()
    test_parse_nfo_without_tmdb_id()
    test_parse_invalid_xml()

    logger.info("")
    logger.info("%s", "=" * 60)
    logger.info("ALL TESTS PASSED")
    logger.info("%s", "=" * 60)
