import json
import pickle
import re
from collections import defaultdict, Counter

# Load the requirement map
with open('/tmp/req_map.pkl', 'rb') as f:
    req_map = pickle.load(f)

# Read pairs
pairs_path = "C:/Users/decid/AppData/Local/Temp/claude/C--Users-decid-Documents-projects-liaison/29287739-71ae-4df9-a62d-b2c76b202b34/scratchpad/stage-phaseB/pairs-01.tsv"

pairs = []
with open(pairs_path, 'r', encoding='utf-8') as f:
    for line in f:
        parts = line.strip().split('\t')
        if len(parts) >= 2:
            pairs.append((parts[0], parts[1]))

def score_confusability(req_a, req_b, req_map):
    """
    Score confusability between two requirements.
    """

    if req_a not in req_map or req_b not in req_map:
        return 0

    info_a = req_map[req_a]
    info_b = req_map[req_b]

    id_a = info_a['id']
    id_b = info_b['id']
    title_a = info_a['title']
    title_b = info_b['title']
    doc_a = info_a['doc']
    doc_b = info_b['doc']

    # If docs are identical, check titles
    if doc_a == doc_b:
        # Same documentation paragraph
        if title_a == title_b:
            # Identical title and doc - nearly indistinguishable
            return 85
        elif title_a.lower() == title_b.lower():
            # Same title different case
            return 90
        else:
            # Same doc, different titles - engineer might confuse them
            return 65

    # Extract requirement family (REQ-FAMILY)
    family_a = re.match(r'REQ-([A-Z]+)', id_a)
    family_b = re.match(r'REQ-([A-Z]+)', id_b)

    base_score = 0

    # Factor 1: Family match
    if family_a and family_b:
        family_a_name = family_a.group(1)
        family_b_name = family_b.group(1)

        if family_a_name == family_b_name:
            # Same family - starting point
            base_score = 15
        else:
            # Different families - starting point
            base_score = 0

    # Factor 2: Title similarity (word overlap)
    title_a_lower = title_a.lower()
    title_b_lower = title_b.lower()

    if title_a_lower == title_b_lower:
        base_score = max(base_score, 75)
    else:
        # Split into words and check overlap
        words_a = set(re.findall(r'\b\w+\b', title_a_lower))
        words_b = set(re.findall(r'\b\w+\b', title_b_lower))

        if len(words_a) > 0 and len(words_b) > 0:
            # Remove common small words
            common_words = {'a', 'an', 'the', 'and', 'or', 'is', 'on', 'in', 'of', 'to', 'that', 'this', 'are', 'be'}
            words_a_clean = words_a - common_words
            words_b_clean = words_b - common_words

            if words_a_clean and words_b_clean:
                overlap = len(words_a_clean & words_b_clean)
                union = len(words_a_clean | words_b_clean)
                similarity = overlap / union if union > 0 else 0

                if similarity > 0.6:
                    base_score = max(base_score, 50)
                elif similarity > 0.4:
                    base_score = max(base_score, 30)
                elif similarity > 0.2:
                    base_score = max(base_score, 15)

    # Factor 3: Doc text similarity
    doc_a_lower = doc_a.lower()
    doc_b_lower = doc_b.lower()

    # Check for key phrase overlap
    sentences_a = [s.strip() for s in re.split(r'[.!?;]', doc_a_lower) if len(s.strip()) > 20]
    sentences_b = [s.strip() for s in re.split(r'[.!?;]', doc_b_lower) if len(s.strip()) > 20]

    if sentences_a and sentences_b:
        matching_sentences = 0
        for sent_a in sentences_a:
            for sent_b in sentences_b:
                if len(sent_a) > 30 and (sent_a in sent_b or sent_b in sent_a):
                    matching_sentences += 1
                    break

        if matching_sentences >= len(sentences_a) * 0.5:
            # Significant doc overlap
            base_score = max(base_score, 50)
        elif matching_sentences > 0:
            base_score = max(base_score, 25)

    # Factor 4: Check if they're in the same domain/subsystem
    domain_markers = {
        'HAZARD': 'hazard',
        'UPDATE': 'update',
        'INSTALL': 'install',
        'INST': 'install',
        'PICKER': 'picker',
        'SUBNET': 'subnet',
        'MESH': 'mesh',
        'EP': 'endpoint',
        'ENDPOINT': 'endpoint',
        'DAEMON': 'daemon',
        'SHELL': 'shell',
        'CLI': 'cli',
        'ACL': 'acl',
        'API': 'api',
        'MSG': 'msg',
        'RELAY': 'relay',
        'PSYCHE': 'psyche',
        'SESSION': 'session',
        'RESUME': 'resume',
        'WAKE': 'wake',
        'START': 'start',
        'UPD': 'update',
    }

    domains_a = set()
    domains_b = set()

    for prefix, domain in domain_markers.items():
        if prefix in id_a:
            domains_a.add(domain)
        if prefix in id_b:
            domains_b.add(domain)

    if domains_a and domains_b and (domains_a & domains_b):  # Shared domains
        base_score = max(base_score, int(base_score * 1.2))  # Boost if in same domain

    # Final adjustments
    # If base score is low but they're consecutive numbers in same family, boost slightly
    if base_score < 20 and family_a and family_b:
        family_a_num = re.search(r'(\d+)', id_a)
        family_b_num = re.search(r'(\d+)', id_b)
        if family_a_num and family_b_num:
            num_a = int(family_a_num.group(1))
            num_b = int(family_b_num.group(1))
            if abs(num_a - num_b) == 1 and family_a.group(1) == family_b.group(1):
                base_score = max(base_score, 25)  # Sequential numbers in same family

    return int(min(100, max(0, base_score)))

# Score all pairs
scored_pairs = []
for idx, (req_a, req_b) in enumerate(pairs, 1):
    score = score_confusability(req_a, req_b, req_map)
    scored_pairs.append({
        'index': idx,
        'a': req_a,
        'b': req_b,
        'score': score
    })

# Print summary statistics
scores = [p['score'] for p in scored_pairs]
print(f"Scoring complete!")
print(f"Average score: {sum(scores) / len(scores):.1f}")
print(f"Min score: {min(scores)}")
print(f"Max score: {max(scores)}")
print(f"Median score: {sorted(scores)[len(scores)//2]}")

# Show distribution
score_dist = Counter(s // 10 * 10 for s in scores)
print("\nScore distribution:")
for bucket in sorted(score_dist.keys()):
    print(f"  {bucket:3d}-{bucket+9:3d}: {score_dist[bucket]:3d} pairs")

# Show some high-scoring pairs
print("\nHighest confusability pairs (score >= 50):")
high_score = [p for p in scored_pairs if p['score'] >= 50]
for p in high_score[:10]:
    print(f"  {p['a']:40s} vs {p['b']:40s} = {p['score']}")

# Save results
with open('/tmp/scored_pairs.json', 'w') as f:
    json.dump(scored_pairs, f, indent=2)

print(f"\nSaved {len(scored_pairs)} scored pairs")
