#!/usr/bin/env python3
import hashlib
import json
import re
import sys
from collections import defaultdict
from datetime import datetime, timezone
from pathlib import Path

PROJECT = Path(__file__).resolve().parents[1]
CANDIDATE = PROJECT / "story/spoken-narration.txt"
REFERENCES = [
    Path("/data/video-pipeline/Chanel-HuyenAnAudio/project/002-Co-Ke-Toan-Bi-Ep-Nhan-Toi-Bien-Thu-Quy-Cuu-Tro-Den-Khi-Muoi-Hai-Chu-Ky-Cung-Phan-Chu/story/v3/spoken-narration.txt"),
    Path("/data/video-pipeline/Chanel-HuyenAnAudio/project/003-Co-Chu-Tro-Bi-Ep-Ban-Nha-Bay-Chia-Khoa-Bong-Tro-Ve/story/spoken-narration.txt"),
    Path("/data/video-pipeline/Chanel-HuyenAnAudio/project/004-Co-Ky-Su-Bi-Vu-Toi-Sap-Cau-Muoi-Ba-Vet-Nut-Doi-Huong/story/spoken-narration.txt"),
]
REPORT = PROJECT / "story/originality-report.json"
TOKEN_RE = re.compile(r"[\wÀ-ỹĐđ]+", re.UNICODE)


def tokens(text):
    return [token.casefold() for token in TOKEN_RE.findall(text)]


def digest(text):
    return hashlib.sha256(text.encode()).hexdigest()


def longest(first, second):
    positions = defaultdict(list)
    for index, token in enumerate(second):
        positions[token].append(index)
    best = 0
    sample = None
    previous = {}
    for index, token in enumerate(first):
        current = {}
        for other_index in positions.get(token, []):
            length = previous.get(other_index - 1, 0) + 1
            current[other_index] = length
            if length > best:
                best = length
                sample = (index - length + 1, index + 1)
        previous = current
    return best, " ".join(first[sample[0]:sample[1]]) if sample else ""


def main():
    issues = []
    candidate = CANDIDATE.read_text() if CANDIDATE.exists() else ""
    if not candidate:
        issues.append("candidate_missing")
    candidate_tokens = tokens(candidate)
    rows = []
    for reference in REFERENCES:
        if not reference.exists():
            issues.append("reference_missing:" + str(reference))
            continue
        text = reference.read_text()
        reference_tokens = tokens(text)
        size = 14
        shingles = {tuple(reference_tokens[index:index + size]) for index in range(max(0, len(reference_tokens) - size + 1))}
        matches = []
        for index in range(max(0, len(candidate_tokens) - size + 1)):
            shingle = tuple(candidate_tokens[index:index + size])
            if shingle in shingles:
                matches.append({"index": index, "text": " ".join(shingle)})
            if len(matches) >= 20:
                break
        run, sample = longest(candidate_tokens, reference_tokens) if candidate_tokens and reference_tokens else (0, "")
        rows.append({"path": str(reference), "sha256": digest(text), "shingle_matches": matches, "longest_exact_token_run": run, "sample": sample[:500]})
        if matches:
            issues.append(f"reference_shingle_matches:{reference.parent.parent.name}:{len(matches)}")
        if run >= 14:
            issues.append(f"long_exact_token_run:{reference.parent.parent.name}:{run}")
    paragraphs = [re.sub(r"\s+", " ", item.strip().casefold()) for item in re.split(r"\n\s*\n", candidate) if len(tokens(item)) >= 35]
    seen = {}
    duplicates = []
    for index, paragraph in enumerate(paragraphs):
        item_hash = hashlib.sha256(paragraph.encode()).hexdigest()
        if item_hash in seen:
            duplicates.append({"first": seen[item_hash], "duplicate": index})
        else:
            seen[item_hash] = index
    if duplicates:
        issues.append(f"internal_duplicate_paragraphs:{len(duplicates)}")
    report = {
        "version": 1,
        "verified": not issues,
        "status": "passed" if not issues else "failed",
        "source_canon_sha256": digest(candidate) if candidate else None,
        "references": rows,
        "shingle_size": 14,
        "internal_duplicate_paragraphs": duplicates,
        "issues": issues,
        "checked_at": datetime.now(timezone.utc).isoformat(),
    }
    REPORT.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n")
    print(json.dumps({"verified": report["verified"], "references": len(rows), "issues": issues}, ensure_ascii=False))
    return 0 if report["verified"] else 1


if __name__ == "__main__":
    sys.exit(main())
