"""Human proteome self-peptide reference set for self/non-self discrimination."""

from __future__ import annotations

import numpy as np

from peptidegym.peptide.properties import AMINO_ACIDS

# Human proteome amino acid frequencies (approximate, well-established values)
_AA_FREQS = {
    "L": 9.9, "A": 7.0, "G": 7.0, "V": 6.6, "E": 6.3,
    "S": 6.8, "I": 5.3, "K": 5.8, "R": 5.5, "D": 5.2,
    "T": 5.4, "P": 5.0, "N": 4.1, "Q": 4.0, "F": 3.9,
    "Y": 2.9, "M": 2.4, "H": 2.3, "C": 1.4, "W": 1.1,
}

# Build ordered probability array matching AMINO_ACIDS order
_aa_list = list(AMINO_ACIDS)
_probs = np.array([_AA_FREQS[aa] for aa in _aa_list], dtype=np.float64)
_probs /= _probs.sum()


def _generate_human_4mers(n: int = 2000, seed: int = 42) -> frozenset[str]:
    rng = np.random.RandomState(seed)
    kmers = set()
    indices = rng.choice(len(_aa_list), size=(n, 4), p=_probs)
    for row in indices:
        kmers.add("".join(_aa_list[i] for i in row))
    return frozenset(kmers)


HUMAN_4MERS: frozenset[str] = _generate_human_4mers()


def max_kmer_overlap(sequence: str, k: int = 4) -> float:
    if len(sequence) < k:
        return 0.0
    kmers = [sequence[i:i + k] for i in range(len(sequence) - k + 1)]
    if not kmers:
        return 0.0
    hits = sum(1 for kmer in kmers if kmer in HUMAN_4MERS)
    return hits / len(kmers)
