import pytest
import json
from pathlib import Path
from ..extractors.filename_extractor import FilenameExtractor
from ..constants import FRAME_CLASSES


def load_test_filenames():
    """Load test filenames from dataset"""
    dataset_file = Path(__file__).parent / "datasets" / "filenames" / "filename_patterns.json"
    if dataset_file.exists():
        with open(dataset_file, 'r', encoding='utf-8') as f:
            data = json.load(f)
            return [case['filename'] for case in data['test_cases']]
    return []


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_title(filename):
    """Test title extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    title = extractor.extract_title()
    # Print filename and extracted title clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted title: \033[1;32m{title}\033[0m")
    # For now, just check it's not None and is string
    assert isinstance(title, str) or title is None


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_year(filename):
    """Test year extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    year = extractor.extract_year()
    # Print filename and extracted year clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted year: \033[1;32m{year}\033[0m")
    # Year should be None or 4-digit string
    if year:
        assert len(year) == 4 and year.isdigit()


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_source(filename):
    """Test source extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    source = extractor.extract_source()
    # Print filename and extracted source clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted source: \033[1;32m{source}\033[0m")
    # Source should be None or string
    assert isinstance(source, str) or source is None


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_frame_class(filename):
    """Test frame class extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    frame_class = extractor.extract_frame_class()
    # Print filename and extracted frame class clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted frame_class: \033[1;32m{frame_class}\033[0m")
    # Frame class should be a string or None
    assert frame_class is None or isinstance(frame_class, str)
    # Should be one of the valid frame classes or None
    if frame_class is not None:
        valid_classes = set(FRAME_CLASSES.keys())
        assert frame_class in valid_classes


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_hdr(filename):
    """Test HDR extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    hdr = extractor.extract_hdr()
    # Print filename and extracted HDR clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted HDR: \033[1;32m{hdr}\033[0m")
    # HDR should be 'HDR' or None
    assert hdr is None or hdr == 'HDR'


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_movie_db(filename):
    """Test movie database identifier extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    movie_db = extractor.extract_movie_db()
    # Print filename and extracted movie DB clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted movie DB: \033[1;32m{movie_db}\033[0m")
    # Movie DB should be list [str, str] or None
    if movie_db:
        assert isinstance(movie_db, list) and len(movie_db) == 2
        assert isinstance(movie_db[0], str) and isinstance(movie_db[1], str)
    else:
        assert movie_db is None


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_audio_langs(filename):
    """Test audio languages extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    audio_langs = extractor.extract_audio_langs()
    # Print filename and extracted audio languages clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted audio langs: \033[1;32m{audio_langs}\033[0m")
    # Audio langs should be a string (possibly empty)
    assert isinstance(audio_langs, str)


@pytest.mark.parametrize("filename", load_test_filenames())
def test_extract_audio_tracks(filename):
    """Test audio tracks extraction from filename"""
    file_path = Path(filename)
    extractor = FilenameExtractor(file_path)
    audio_tracks = extractor.extract_audio_tracks()
    # Print filename and extracted audio tracks clearly
    print(f"\nFilename: \033[1;36m{filename}\033[0m")
    print(f"Extracted audio tracks: \033[1;32m{audio_tracks}\033[0m")
    # Audio tracks should be a list of dicts
    assert isinstance(audio_tracks, list)
    for track in audio_tracks:
        assert isinstance(track, dict)
        assert 'language' in track