#!/usr/bin/env python3
"""Erzeugt die Illustrationen fuer den Live-IQ-Abschnitt des Stufe-3-Artikels
aus der echten KiwiSDR-Aufnahme (keine synthetischen Daten)."""
import numpy as np
from scipy.io import wavfile
from scipy.signal import spectrogram, firwin, lfilter
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

IMG_DIR = '../../../homepage/src/assets/images'
WAV = "SND.kiwisdr.dynpc.net_2026-08-05T07_34_42Z_7033.98_iq.wav"


def load_iq():
    fs, data = wavfile.read(WAV)
    iq = data[:, 0].astype(np.float64) + 1j * data[:, 1].astype(np.float64)
    iq /= np.max(np.abs(iq))
    return fs, iq


def plot_overview():
    fs, iq = load_iq()
    f, tt, Sxx = spectrogram(iq, fs=fs, nperseg=4096, noverlap=3072, return_onesided=False)
    f = np.fft.fftshift(f)
    Sxx = np.fft.fftshift(Sxx, axes=0)
    Sxx_db = 10 * np.log10(Sxx + 1e-12)

    fig, ax = plt.subplots(figsize=(12, 6))
    im = ax.pcolormesh(tt, f, Sxx_db, shading='auto',
                        vmin=Sxx_db.max() - 50, vmax=Sxx_db.max() - 5, cmap='viridis')
    ax.set_ylim(-6000, 6000)
    ax.set_xlabel('Zeit [s]')
    ax.set_ylabel('Frequenzversatz zu 7033,98 kHz [Hz]')
    ax.set_title('KiwiSDR-IQ-Aufnahme, 40 m: Spektrogramm ueber die volle Bandbreite')
    ax.annotate('CW-Signal (getastet)\n~4511 Hz', xy=(6, 4511), xytext=(10, 5300),
                color='white', fontsize=9, arrowprops=dict(arrowstyle='->', color='white'))
    ax.annotate('Dauertraeger\n~-1666 Hz', xy=(6, -1666), xytext=(2, -3200),
                color='white', fontsize=9, arrowprops=dict(arrowstyle='->', color='white'))
    fig.colorbar(im, ax=ax, label='dB')
    fig.tight_layout()
    fig.savefig(f'{IMG_DIR}/cw-live-spectrogram.png', dpi=140)
    print("Geschrieben: cw-live-spectrogram.png")


def plot_beat():
    fs, iq = load_iq()
    f, tt, Sxx = spectrogram(iq, fs=fs, nperseg=32768, noverlap=32768 - 512, return_onesided=False)
    f = np.fft.fftshift(f)
    Sxx = np.fft.fftshift(Sxx, axes=0)
    Sxx_db = 10 * np.log10(Sxx + 1e-12)
    mask = (f > 4480) & (f < 4550)

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(13, 4.5))
    im = ax1.pcolormesh(tt, f[mask], Sxx_db[mask], shading='auto',
                         vmin=Sxx_db.max() - 40, vmax=Sxx_db.max() - 5, cmap='viridis')
    ax1.set_xlim(0, 17)
    ax1.set_xlabel('Zeit [s]')
    ax1.set_ylabel('Frequenzversatz [Hz]')
    ax1.set_title('Hochaufgeloest: zwei getrennte Linien\n~4508 Hz und ~4519 Hz')
    fig.colorbar(im, ax=ax1, label='dB')

    t = np.arange(len(iq)) / fs
    mixed = iq * np.exp(-1j * 2 * np.pi * 4510.6 * t)
    taps = firwin(1601, 15, fs=fs)
    filtered = lfilter(taps, 1.0, mixed)
    env = np.abs(filtered)
    m = (t > 0) & (t < 17)
    ax2.plot(t[m], env[m], lw=0.6, color='#bf616a')
    ax2.set_xlabel('Zeit [s]')
    ax2.set_ylabel('Huellkurve (15-Hz-Filter)')
    ax2.set_title('Resultierende Envelope: durchgehende\nSchwebung statt sauberer CW-Taktung')

    fig.suptitle('Zwei dicht benachbarte Signale bei ~4510 Hz erzeugen eine Schwebung')
    fig.tight_layout()
    fig.savefig(f'{IMG_DIR}/cw-live-beat.png', dpi=140)
    print("Geschrieben: cw-live-beat.png")


if __name__ == '__main__':
    plot_overview()
    plot_beat()
