from __future__ import annotations

import csv
import sys
import tempfile
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))

from csv_dedupe import deduplicate_csv, deduplicate_rows


class CsvDedupeTests(unittest.TestCase):
    def test_first_row_wins_for_one_key(self) -> None:
        rows = [
            {"id": "1", "name": "Ada"},
            {"id": "1", "name": "Ada revised"},
            {"id": "2", "name": "Grace"},
        ]
        retained, removed = deduplicate_rows(rows, ["id"])
        self.assertEqual(retained, [rows[0], rows[2]])
        self.assertEqual(removed, 1)

    def test_last_row_wins_and_retains_source_order(self) -> None:
        rows = [
            {"id": "1", "name": "old"},
            {"id": "2", "name": "middle"},
            {"id": "1", "name": "new"},
        ]
        retained, removed = deduplicate_rows(rows, ["id"], keep="last")
        self.assertEqual(retained, [rows[1], rows[2]])
        self.assertEqual(removed, 1)

    def test_composite_normalized_key(self) -> None:
        rows = [
            {"email": " ADA@EXAMPLE.COM ", "team": "A"},
            {"email": "ada@example.com", "team": "A"},
            {"email": "ada@example.com", "team": "B"},
        ]
        retained, removed = deduplicate_rows(
            rows,
            ["email", "team"],
            ignore_case=True,
            strip_key_whitespace=True,
        )
        self.assertEqual(retained, [rows[0], rows[2]])
        self.assertEqual(removed, 1)

    def test_file_round_trip_and_summary(self) -> None:
        with tempfile.TemporaryDirectory() as temporary:
            source = Path(temporary, "input.csv")
            output = Path(temporary, "output.csv")
            source.write_text("id,name\n1,Ada\n1,Ada duplicate\n2,Grace\n", encoding="utf-8")
            summary = deduplicate_csv(source, output, ["id"])
            with output.open(newline="", encoding="utf-8") as handle:
                rows = list(csv.DictReader(handle))
            self.assertEqual(rows, [{"id": "1", "name": "Ada"}, {"id": "2", "name": "Grace"}])
            self.assertEqual(summary["duplicates_removed"], 1)

    def test_missing_key_is_rejected(self) -> None:
        with tempfile.TemporaryDirectory() as temporary:
            source = Path(temporary, "input.csv")
            source.write_text("id,name\n1,Ada\n", encoding="utf-8")
            with self.assertRaisesRegex(ValueError, "missing key column"):
                deduplicate_csv(source, Path(temporary, "output.csv"), ["email"])


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