import numpy as np
from decimal import Decimal
import hashlib

# -------------------------------
# Example learned T mapping (replace with your model)
# -------------------------------
def predict_params(f, model=None):
    # For demonstration, synthetic linear mapping
    alpha = 3.0 + 0.01*f
    beta  = 6.0 + 0.02*f
    eta   = 2.0 + 0.005*f
    zeta  = 3.0 + 0.007*f
    return dict(alpha=alpha, beta=beta, eta=eta, zeta=zeta)

# -------------------------------
# Nodal hash function
# -------------------------------
def nodal_hash(alpha, beta, eta, zeta, Nx=32, Ny=32):
    x = np.linspace(0, 1, Nx)
    y = np.linspace(0, 1, Ny)
    Xg, Yg = np.meshgrid(x, y)
    Z = np.sin(alpha*np.pi*Xg) * np.sin(beta*np.pi*Yg) + eta*np.cos(zeta*np.pi*(Xg+Yg))
    # Flatten and hash
    flat = Z.flatten()
    # Convert to bytes (scaled integers)
    flat_bytes = (np.round(flat*1e5)).astype(np.int64).tobytes()
    h = hashlib.sha256(flat_bytes).hexdigest()
    # Convert hash to numeric value
    h_num = int(h[:16], 16)  # take first 16 hex digits → 64-bit int
    return Decimal(h_num)

# -------------------------------
# PhiCompression augmentation
# -------------------------------
def phi_encode_with_tuner(sequence, phi=1.6180339887498948):
    from decimal import Decimal
    PHI = Decimal(str(phi))
    # Step 1: basic φ-encoding (sum phi^x_i)
    seq_phi = sum(PHI**Decimal(x) for x in sequence)
    # Step 2: compute a synthetic frequency from sequence sum
    f_synth = float(seq_phi % 1000) + 100  # map to [100,1100] Hz range
    # Step 3: predict nodal params
    params = predict_params(f_synth)
    # Step 4: compute nodal hash
    h = nodal_hash(**params)
    # Step 5: combine φ-encoding + hash modulo large slot
    SATURATE_SLOT = Decimal('9223372036854775')
    encoded = (seq_phi + h) % SATURATE_SLOT
    return encoded

# -------------------------------
# Example usage
# -------------------------------
if __name__ == "__main__":
    sequence = [35, 33, 10, 97, 98]  # e.g., ASCII codes
    encoded = phi_encode_with_tuner(sequence)
    print("Sequence:", sequence)
    print("Phi+Tuner encoded value:", encoded)