"""
Generate synthetic UV-Vis absorption spectra for testing analyze_batch.

Scenario: A researcher measures UV-Vis spectra of a dye solution at different
temperatures and pH values. Each spectrum file contains only wavelength and
absorbance columns. The experimental conditions (temperature, pH) are provided
via sidecar JSONs, a global conditions file, or inline.

The spectra have a main absorption peak whose position and intensity shift
with temperature and pH — mimicking a real thermochromic / solvatochromic dye.
"""

import json
import numpy as np
import pandas as pd
from pathlib import Path

HERE = Path(__file__).parent
np.random.seed(42)

# Experimental conditions grid
conditions = [
    {"temperature_C": 25, "pH": 4.0},
    {"temperature_C": 25, "pH": 7.0},
    {"temperature_C": 25, "pH": 10.0},
    {"temperature_C": 50, "pH": 4.0},
    {"temperature_C": 50, "pH": 7.0},
    {"temperature_C": 50, "pH": 10.0},
    {"temperature_C": 75, "pH": 4.0},
    {"temperature_C": 75, "pH": 7.0},
]


def generate_spectrum(temp, ph, wavelengths):
    """Generate a synthetic UV-Vis spectrum with physically-motivated shifts."""
    # Peak center shifts with temperature (red-shift) and pH (blue-shift at high pH)
    peak_center = 450 + 0.3 * (temp - 25) - 5.0 * (ph - 7.0)
    # Peak width broadens with temperature
    peak_width = 30 + 0.15 * (temp - 25)
    # Peak height decreases with temperature (thermal quenching), increases with pH
    peak_height = 1.2 - 0.005 * (temp - 25) + 0.04 * (ph - 7.0)
    peak_height = max(peak_height, 0.2)

    # Main peak (Gaussian)
    absorbance = peak_height * np.exp(-0.5 * ((wavelengths - peak_center) / peak_width) ** 2)

    # Small shoulder peak (always at ~400 nm, weak)
    shoulder = 0.15 * np.exp(-0.5 * ((wavelengths - 400) / 15) ** 2)
    absorbance += shoulder

    # Baseline slope + noise
    baseline = 0.02 + 0.0001 * (wavelengths - 350)
    noise = np.random.normal(0, 0.005, len(wavelengths))

    return np.clip(absorbance + baseline + noise, 0, None)


wavelengths = np.linspace(350, 600, 251)

# --- Generate individual spectrum CSVs ---
global_conditions = {}

for i, cond in enumerate(conditions):
    temp, ph = cond["temperature_C"], cond["pH"]
    fname = f"spectrum_T{temp}_pH{ph:.0f}.csv"

    absorbance = generate_spectrum(temp, ph, wavelengths)
    df = pd.DataFrame({"wavelength_nm": wavelengths, "absorbance": absorbance})
    df.to_csv(HERE / fname, index=False)

    # Sidecar JSON (per-file metadata)
    sidecar = {
        "temperature_C": temp,
        "pH": ph,
    }
    sidecar_path = HERE / fname.replace(".csv", ".json")
    with open(sidecar_path, "w") as f:
        json.dump(sidecar, f, indent=2)

    global_conditions[fname] = cond

# --- Global conditions file ---
with open(HERE / "conditions.json", "w") as f:
    json.dump(global_conditions, f, indent=2)

print(f"Generated {len(conditions)} spectrum files with sidecar JSONs and conditions.json")
print(f"Output directory: {HERE}")
