import tempfile
import unittest
from pathlib import Path
import core


class TasksTest(unittest.TestCase):
    def test_identity_after_filter(self):
        rows = []
        core.add(rows, "Matematika")
        core.add(rows, "Sains")
        core.complete(rows, core.search(rows, "sains")[0]["id"])
        self.assertEqual([r["done"] for r in rows], [False, True])
        self.assertEqual(core.summary(rows), (1, 2))

    def test_invalid_title_id_and_schema(self):
        rows = []
        with self.assertRaises(ValueError):
            core.add(rows, " ")
        with self.assertRaises(ValueError):
            core.complete(rows, 99)
        with self.assertRaises(ValueError):
            core.validate([{"id": 1, "title": "A", "done": "false"}])
        self.assertEqual(rows, [])

    def test_roundtrip_and_corrupt_file(self):
        with tempfile.TemporaryDirectory() as folder:
            path = Path(folder) / "tasks.json"
            rows = []
            core.add(rows, "Baca")
            core.complete(rows, 1)
            core.save(path, rows)
            self.assertEqual(core.load(path), rows)
            path.write_text("{rusak", encoding="utf-8")
            with self.assertRaises(ValueError):
                core.load(path)
            self.assertEqual(path.read_text(encoding="utf-8"), "{rusak")

    def test_gui_filtered_identity_and_reload(self):
        import tkinter as tk
        import app
        with tempfile.TemporaryDirectory() as folder:
            path = Path(folder) / "tasks.json"
            root = tk.Tk()
            root.withdraw()
            try:
                view = app.build_window(root, path)
                for title in ("Matematika", "Sains"):
                    view["title"].set(title)
                    view["buttons"]["Tambah"].invoke()
                view["query"].set("Sains")
                view["render"]()
                view["list"].selection_set(0)
                view["buttons"]["Selesai"].invoke()
                self.assertEqual([r["done"] for r in view["rows"]], [False, True])
                view["buttons"]["Simpan"].invoke()
                view["rows"].clear()
                view["buttons"]["Muat"].invoke()
                self.assertEqual(core.summary(view["rows"]), (1, 2))
                root.update_idletasks()
            finally:
                root.destroy()


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