import tempfile
import unittest
from pathlib import Path

from clean_podcast_ads import (
    AdSegment,
    MarkerHit,
    PodcastCleanerError,
    build_audacity_report_lines,
    build_output_paths,
    compute_keep_segments,
    validate_and_pair_markers,
)


class ValidateAndPairMarkersTests(unittest.TestCase):
    def test_pairs_even_markers_into_ad_segments(self) -> None:
        marker_hits = [
            MarkerHit(start_seconds=10.0, end_seconds=14.24, score=0.95),
            MarkerHit(start_seconds=40.0, end_seconds=44.24, score=0.96),
            MarkerHit(start_seconds=100.0, end_seconds=104.24, score=0.97),
            MarkerHit(start_seconds=130.0, end_seconds=134.24, score=0.98),
        ]

        ad_segments = validate_and_pair_markers(marker_hits, marker_duration_seconds=4.24)

        self.assertEqual(len(ad_segments), 2)
        self.assertAlmostEqual(ad_segments[0].start_seconds, 10.0)
        self.assertAlmostEqual(ad_segments[0].end_seconds, 44.24)
        self.assertAlmostEqual(ad_segments[1].start_seconds, 100.0)
        self.assertAlmostEqual(ad_segments[1].end_seconds, 134.24)

    def test_rejects_odd_marker_count(self) -> None:
        marker_hits = [MarkerHit(start_seconds=10.0, end_seconds=14.24, score=0.95)]

        with self.assertRaises(PodcastCleanerError):
            validate_and_pair_markers(marker_hits, marker_duration_seconds=4.24)

    def test_rejects_ad_segment_longer_than_five_minutes(self) -> None:
        marker_hits = [
            MarkerHit(start_seconds=0.0, end_seconds=4.24, score=0.95),
            MarkerHit(start_seconds=400.0, end_seconds=404.24, score=0.96),
        ]

        with self.assertRaises(PodcastCleanerError):
            validate_and_pair_markers(marker_hits, marker_duration_seconds=4.24)


class ComputeKeepSegmentsTests(unittest.TestCase):
    def test_builds_complement_segments(self) -> None:
        ad_segments = [
            AdSegment(start_seconds=10.0, end_seconds=20.0),
            AdSegment(start_seconds=30.0, end_seconds=40.0),
        ]

        keep_segments = compute_keep_segments(60.0, ad_segments)

        self.assertEqual(
            keep_segments,
            [
                AdSegment(start_seconds=0.0, end_seconds=10.0),
                AdSegment(start_seconds=20.0, end_seconds=30.0),
                AdSegment(start_seconds=40.0, end_seconds=60.0),
            ],
        )


class AudacityReportTests(unittest.TestCase):
    def test_builds_labels_for_markers_ads_and_errors(self) -> None:
        marker_hits = [MarkerHit(start_seconds=10.0, end_seconds=14.24, score=0.956)]
        ad_segments = [AdSegment(start_seconds=10.0, end_seconds=44.24)]

        lines = build_audacity_report_lines(marker_hits, ad_segments, ["odd_marker_count"])

        self.assertEqual(lines[0], "10.000000\t14.240000\tmarker_01 score=0.956")
        self.assertEqual(lines[1], "10.000000\t44.240000\tpub_01")
        self.assertEqual(lines[2], "0.000000\t0.000000\tERROR odd_marker_count")


class OutputPathTests(unittest.TestCase):
    def test_uses_suffix_based_output_names(self) -> None:
        input_path = Path(r"C:\podcasts\episode.mp3")

        output_audio_path, report_path = build_output_paths(input_path)

        self.assertEqual(output_audio_path.name, "episode.sans_pub.mp3")
        self.assertEqual(report_path.name, "episode.pubs_audacity.txt")


class ReportWriteTests(unittest.TestCase):
    def test_report_lines_can_be_saved_for_audacity(self) -> None:
        lines = build_audacity_report_lines([], [], ["no_marker"])
        with tempfile.TemporaryDirectory() as temp_dir:
            report_path = Path(temp_dir) / "report.txt"
            report_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
            self.assertIn("ERROR no_marker", report_path.read_text(encoding="utf-8"))


if __name__ == "__main__":
    unittest.main()
