from __future__ import annotations

import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path


SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "resume_bank.py"


class ResumeBankCliTest(unittest.TestCase):
    def setUp(self) -> None:
        self.temp_dir = tempfile.TemporaryDirectory()
        self.root = Path(self.temp_dir.name)
        self.resume = self.root / "resumes" / "acme" / "resume.md"
        self.resume.parent.mkdir(parents=True)
        self.bullet_one = "Built a capacity model that improved planning accuracy by 20%"
        self.bullet_two = "Redesigned quotas and reduced attainment dispersion by 50%"
        self.project_bullet = "Built a side project that automates research workflows"
        self.write_resume([self.bullet_one, self.bullet_two])

    def tearDown(self) -> None:
        self.temp_dir.cleanup()

    def write_resume(self, bullets: list[str]) -> None:
        lines = [
            "# TEST CANDIDATE",
            "",
            "## Professional Experience",
            "### 2024 - Present | ACME | Remote",
            "**Finance Lead**",
            *(f"- {bullet}" for bullet in bullets),
            "",
            "## Additional",
            f"- {self.project_bullet}",
        ]
        self.resume.write_text("\n".join(lines) + "\n", encoding="utf-8")

    def run_cli(self, *args: str, expect: int = 0) -> subprocess.CompletedProcess[str]:
        result = subprocess.run(
            [
                sys.executable,
                str(SCRIPT),
                "--repo-root",
                str(self.root),
                *args,
            ],
            text=True,
            capture_output=True,
        )
        self.assertEqual(expect, result.returncode, result.stderr or result.stdout)
        return result

    def approve(self, achievement_id: str, text: str) -> None:
        self.run_cli(
            "approve",
            "--id",
            achievement_id,
            "--text",
            text,
            "--company",
            "Acme",
            "--role",
            "Finance Lead",
            "--source",
            "resumes/acme/resume.md",
            "--evidence",
            "User explicitly confirmed the result",
            "--metric",
            "Verified outcome",
            "--target-signal",
            "Planning effectiveness",
            "--skip-index",
        )

    def test_approval_state_and_drift_loop(self) -> None:
        self.run_cli("init")
        self.approve("acme-capacity-model", self.bullet_one)

        failed = self.run_cli(
            "content-approved",
            "--resume",
            "resumes/acme/resume.md",
            expect=2,
        )
        self.assertIn(self.bullet_two, failed.stderr)

        self.approve("acme-quota-redesign", self.bullet_two)
        self.run_cli("content-approved", "--resume", "resumes/acme/resume.md")

        status = self.run_cli("status", "--resume", "resumes/acme/resume.md")
        self.assertEqual("content-approved", json.loads(status.stdout)["effective_state"])

        self.write_resume([self.bullet_one, f"{self.bullet_two} across three regions"])
        drift = self.run_cli(
            "status",
            "--resume",
            "resumes/acme/resume.md",
            expect=1,
        )
        payload = json.loads(drift.stdout)
        self.assertTrue(payload["drift"])
        self.assertEqual("draft", payload["effective_state"])

    def test_replacing_wording_requires_change_note_and_keeps_history(self) -> None:
        self.run_cli("init")
        self.approve("acme-capacity-model", self.bullet_one)
        revised = "Built a capacity model that improved planning accuracy by 25%"
        self.write_resume([revised, self.bullet_two])

        missing_note = self.run_cli(
            "approve",
            "--id",
            "acme-capacity-model",
            "--text",
            revised,
            "--company",
            "Acme",
            "--role",
            "Finance Lead",
            "--source",
            "resumes/acme/resume.md",
            "--evidence",
            "User corrected the verified result",
            "--skip-index",
            expect=2,
        )
        self.assertIn("--change-note", missing_note.stderr)

        self.run_cli(
            "approve",
            "--id",
            "acme-capacity-model",
            "--text",
            revised,
            "--company",
            "Acme",
            "--role",
            "Finance Lead",
            "--source",
            "resumes/acme/resume.md",
            "--evidence",
            "User corrected the verified result",
            "--change-note",
            "Updated after source verification",
            "--skip-index",
        )
        vault = json.loads((self.root / "resume_vault.json").read_text(encoding="utf-8"))
        achievement = vault["achievements"][0]
        self.assertEqual(revised, achievement["canonical_text"])
        self.assertEqual(self.bullet_one, achievement["history"][0]["text"])

    def test_approval_requires_exact_source_bullet(self) -> None:
        self.run_cli("init")
        result = self.run_cli(
            "approve",
            "--id",
            "acme-invented-result",
            "--text",
            "Invented a result that is not present in the source",
            "--company",
            "Acme",
            "--role",
            "Finance Lead",
            "--source",
            "resumes/acme/resume.md",
            "--evidence",
            "Should fail",
            "--skip-index",
            expect=2,
        )
        self.assertIn("not an exact bullet", result.stderr)

    def test_approval_accepts_exact_additional_section_bullet(self) -> None:
        self.run_cli("init")
        self.run_cli(
            "approve",
            "--id",
            "acme-side-project",
            "--text",
            self.project_bullet,
            "--company",
            "Personal Project",
            "--role",
            "Builder",
            "--section",
            "Additional",
            "--source",
            "resumes/acme/resume.md",
            "--evidence",
            "User explicitly approved the project wording",
            "--skip-index",
        )
        vault = json.loads((self.root / "resume_vault.json").read_text(encoding="utf-8"))
        self.assertEqual(self.project_bullet, vault["achievements"][0]["canonical_text"])

    def test_finalize_records_artifact_hashes_and_detects_export_drift(self) -> None:
        self.run_cli("init")
        self.approve("acme-capacity-model", self.bullet_one)
        self.approve("acme-quota-redesign", self.bullet_two)
        self.run_cli("content-approved", "--resume", "resumes/acme/resume.md")

        docx = self.root / "final resumes" / "resume.docx"
        pdf = self.root / "final resumes" / "resume.pdf"
        docx.parent.mkdir(parents=True)
        docx.write_bytes(b"docx fixture")
        pdf.write_bytes(b"pdf fixture")
        log = self.root / "resumes" / "resume_completion_log.md"
        log.write_text(
            "## Acme\n\n"
            "- **Path:** `resumes/acme/resume.md`\n"
            "- **Status:** final-rendered\n",
            encoding="utf-8",
        )

        self.run_cli(
            "finalize",
            "--resume",
            "resumes/acme/resume.md",
            "--docx",
            "final resumes/resume.docx",
            "--pdf",
            "final resumes/resume.pdf",
            "--completion-log",
            "resumes/resume_completion_log.md",
            "--qa-note",
            "Fixture QA passed",
            "--skip-index",
        )
        status = self.run_cli("status", "--resume", "resumes/acme/resume.md")
        self.assertEqual("rendered-final", json.loads(status.stdout)["effective_state"])

        pdf.write_bytes(b"changed PDF")
        drift = self.run_cli(
            "status",
            "--resume",
            "resumes/acme/resume.md",
            expect=1,
        )
        payload = json.loads(drift.stdout)
        self.assertTrue(payload["export_drift"])
        self.assertEqual("draft", payload["effective_state"])


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