from __future__ import annotations

import copy
from pathlib import Path

from scripts import build_telegram_visible_unseen_chain_packet as packet_builder
from scripts import verify_telegram_visible_unseen_chain as verifier

SUBJECT_ID = "c0000000-0000-4000-8000-000000000001"


def packet_and_path(tmp_path: Path) -> tuple[dict, Path]:
    packet = packet_builder.build_packet(
        handler_receipt_path=packet_builder.DEFAULT_HANDLER_RECEIPT.resolve(),
        git_sha="a" * 40,
    )
    path = tmp_path / "packet.json"
    packet_builder.write_json(path, packet)
    return packet, path


def preflight(packet: dict, packet_path: Path) -> dict:
    return {
        "phase": "preflight",
        "status": "pass",
        "protocol_sha256": packet["protocol_sha256"],
        "packet_file_sha256": verifier._sha256_file(packet_path),
        "state_token_sha256": "1" * 64,
        "remote": {
            "fingerprint_after": {"fingerprint_sha256": "f" * 64},
            "service_after": {
                "MainPID": "123",
                "NRestarts": "0",
                "ExecMainStartTimestamp": "Wed 2026-07-15 00:00:00 UTC",
            },
        },
    }


def postflight(packet: dict) -> dict:
    return {
        "phase": "postflight",
        "status": "pass",
        "protocol_sha256": packet["protocol_sha256"],
        "state_token_sha256": "2" * 64,
        "subject_ref": "c0000000",
        "remote": {
            "fingerprint_after": {"fingerprint_sha256": "f" * 64},
            "service_after": {
                "MainPID": "123",
                "NRestarts": "0",
                "ExecMainStartTimestamp": "Wed 2026-07-15 00:00:00 UTC",
            },
            "subject_readback": {
                "subject_ref": "c0000000",
                "matches": [
                    {
                        "table": "public.beliefs",
                        "row": {"id": SUBJECT_ID, "statement": "Coordination is the bottleneck."},
                    }
                ],
            },
        },
    }


def good_capture(packet: dict, tmp_path: Path) -> dict:
    screenshot = tmp_path / "final.png"
    accessibility = tmp_path / "final.txt"
    screenshot.write_bytes(b"png proof")
    accessibility.write_text("telegram accessibility proof", encoding="utf-8")
    replies = [
        (
            "The database public.beliefs object c0000000 is an axiom with confidence 0.85. What supports it in "
            "the DB: nothing supports it; there are zero evidence rows and no external primary source."
        ),
        (
            "Claim c0000000 is still the coordination bottleneck belief. Assumption versus observed support: the "
            "priority leap is assumed and the evidence is absent. Falsifier: a contrary case. Proposal A and "
            "Proposal B are staged only for review; nothing applied and neither is live knowledge."
        ),
        (
            "Revised proposal: separate the mechanism from the business outcome. What would resolve the "
            "disagreement: a randomized study and its primary source dataset. Keep it pending_review for human "
            "review; approved is not apply and applied_at remains null. This is not an apply."
        ),
    ]
    messages = []
    for item, reply in zip(packet["exact_messages"], replies, strict=True):
        sequence = item["sequence"]
        turn_screenshot = tmp_path / f"turn-{sequence}.png"
        turn_accessibility = tmp_path / f"turn-{sequence}.txt"
        turn_screenshot.write_bytes(f"turn {sequence} screenshot".encode())
        turn_accessibility.write_text(
            f"Telegram message: {item['message']}\nLeo reply: {reply}\n",
            encoding="utf-8",
        )
        messages.append(
            {
                "sequence": sequence,
                "prompt_id": item["prompt_id"],
                "sent_text": item["message"],
                "reply": reply,
                "sent_at_utc": f"2026-07-15T00:0{sequence}:00Z",
                "reply_at_utc": f"2026-07-15T00:0{sequence}:20Z",
                "telegram_message_id": f"sent-{sequence}",
                "reply_message_id": f"reply-{sequence}",
                "turn_screenshot": str(turn_screenshot),
                "turn_accessibility": str(turn_accessibility),
            }
        )
    return {
        "protocol_sha256": packet["protocol_sha256"],
        "preflight_state_token_sha256": "1" * 64,
        "operator_authorization_text": packet["explicit_operator_authorization_text"],
        "operator_authorization_captured_at_utc": "2026-07-15T00:00:00Z",
        "extra_messages_sent": 0,
        "capture_source": {
            "platform": "telegram",
            "transport": "authenticated_chrome_telegram_ui",
            "chat_label": "Leo",
            "chat_id": "-5146042086",
            "captured_at_utc": "2026-07-15T00:05:00Z",
            "captured_by": "codex",
            "final_screenshot": str(screenshot),
            "final_accessibility": str(accessibility),
        },
        "messages": messages,
    }


def test_no_capture_returns_awaiting_authorization_template(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)

    receipt = verifier.verify_capture(
        packet,
        preflight(packet, packet_path),
        None,
        None,
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "awaiting_action_time_authorization"
    assert receipt["telegram_visible_messages_sent"] is False
    assert receipt["capture_template"]["messages"][0]["prompt_id"] == "OOS-CHAIN-01"


def test_good_chrome_capture_and_unchanged_fingerprint_pass_t3(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)
    before = preflight(packet, packet_path)

    receipt = verifier.verify_capture(
        packet,
        before,
        good_capture(packet, tmp_path),
        postflight(packet),
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "pass"
    assert receipt["receipt_ready"] is True
    assert receipt["current_tier"] == "T3_live_readonly"
    assert all(receipt["checks"].values())
    assert all(receipt["outcomes"].values())
    assert receipt["selected_subject"]["row_id"] == SUBJECT_ID


def test_bot_api_capture_is_rejected(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)
    capture = good_capture(packet, tmp_path)
    capture["capture_source"]["transport"] = "telegram_bot_api"

    receipt = verifier.verify_capture(
        packet,
        preflight(packet, packet_path),
        capture,
        postflight(packet),
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "fail"
    assert receipt["checks"]["authenticated_chrome_transport_proven"] is False
    assert receipt["checks"]["bot_api_not_substituted"] is False


def test_postflight_fingerprint_drift_is_rejected(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)
    after = copy.deepcopy(postflight(packet))
    after["remote"]["fingerprint_after"]["fingerprint_sha256"] = "0" * 64

    receipt = verifier.verify_capture(
        packet,
        preflight(packet, packet_path),
        good_capture(packet, tmp_path),
        after,
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "fail"
    assert receipt["checks"]["canonical_fingerprint_unchanged_from_preflight"] is False


def test_message_text_drift_is_rejected(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)
    capture = good_capture(packet, tmp_path)
    capture["messages"][1]["sent_text"] += " extra"

    receipt = verifier.verify_capture(
        packet,
        preflight(packet, packet_path),
        capture,
        postflight(packet),
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "fail"
    assert receipt["checks"]["sent_text_exact"] is False


def test_copied_reply_not_present_in_accessibility_is_rejected(tmp_path: Path) -> None:
    packet, packet_path = packet_and_path(tmp_path)
    capture = good_capture(packet, tmp_path)
    capture["messages"][0]["reply"] += " copied-only suffix"

    receipt = verifier.verify_capture(
        packet,
        preflight(packet, packet_path),
        capture,
        postflight(packet),
        packet_path=packet_path,
        evidence_root=tmp_path,
    )

    assert receipt["status"] == "fail"
    assert receipt["checks"]["turn_accessibility_binds_exact_messages_and_replies"] is False
