from qiskit import QuantumCircuit
from qiskit.quantum_info import Statevector
import numpy as np

def create_circuit():
    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.s(0)
    qc.cx(1, 2)
    qc.h(0)
    return qc

def simulate_and_analyze():
    qc = create_circuit()
    sv = Statevector.from_instruction(qc)
    probs = sv.probabilities([0, 2])
    
    prob_photon_0_idler_0 = probs[0] + probs[1]
    prob_photon_0_idler_1 = probs[2] + probs[3]
    
    return prob_photon_0_idler_0, prob_photon_0_idler_1

def send_message(message):
    results = []
    for bit in message:
        prob_0_0, prob_0_1 = simulate_and_analyze()
        if bit == '1':
            results.append(abs(prob_0_0 - prob_0_1) <= 0.1)
        else:
            results.append(abs(prob_0_0 - 0.5) >= 0.1)
    return results

def receive_message(results):
    return ''.join('1' if result else '0' for result in results)

def string_to_binary(s):
    return ''.join(format(ord(c), '08b') for c in s)

def binary_to_string(binary):
    return ''.join(chr(int(binary[i:i+8], 2)) for i in range(0, len(binary), 8))

# Cuvântul de transmis
word = "evrika"

print(f"Cuvântul de transmis: {word}")

# Convertim cuvântul în reprezentare binară
binary_message = string_to_binary(word)
print(f"Reprezentarea binară: {binary_message}")

# Transmitem mesajul
sent_results = send_message(binary_message)
received_binary = receive_message(sent_results)

print(f"\nMesaj binar trimis:    {binary_message}")
print(f"Mesaj binar primit:    {received_binary}")
print(f"Transmisie corectă: {binary_message == received_binary}")

# Convertim mesajul primit înapoi în text
received_word = binary_to_string(received_binary)
print(f"\nCuvântul primit: {received_word}")

print("\nDetalii pentru fiecare caracter:")
for i in range(0, len(binary_message), 8):
    char_binary = binary_message[i:i+8]
    char = chr(int(char_binary, 2))
    print(f"\nCaracter: '{char}' (ASCII: {ord(char)})")
    print(f"Octet trimis:   {char_binary}")
    print(f"Octet primit:   {received_binary[i:i+8]}")
    print("Detalii pentru fiecare bit:")
    for j, bit in enumerate(char_binary):
        prob_0_0, prob_0_1 = simulate_and_analyze()
        print(f"  Bit {j}: Trimis {bit}, Primit {received_binary[i+j]}, "
              f"Prob(0,0): {prob_0_0:.4f}, Prob(0,1): {prob_0_1:.4f}, "
              f"Diferență: {abs(prob_0_0 - prob_0_1):.4f}")
