use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct State {
    pub connections: ConnectionState,
    pub metronome: MetronomeState,
    pub track_volumes: TrackVolumes,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConnectionState {
    pub midi_in: Vec<String>,
    pub midi_out: Vec<String>,
    pub audio_in: Vec<String>,
    pub audio_out: Vec<String>,
    pub click_track_out: Vec<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetronomeState {
    pub frames_per_beat: usize,
    pub click_volume: f32, // 0.0 to 1.0
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TrackVolumes {
    volumes: HashMap<String, f32>, // "col_1_row_1" → volume (1-based naming)
}

impl TrackVolumes {
    pub fn new() -> Self {
        Self {
            volumes: HashMap::new(),
        }
    }

    pub fn set_volume(&mut self, column: usize, row: usize, volume: f32) {
        let key = Self::make_key(column, row);
        let clamped_volume = volume.clamp(0.0, 1.0);
        self.volumes.insert(key, clamped_volume);
    }

    fn make_key(column: usize, row: usize) -> String {
        format!("col_{}_row_{}", column + 1, row + 1)
    }
}

impl Default for TrackVolumes {
    fn default() -> Self {
        Self::new()
    }
}

impl Default for State {
    fn default() -> Self {
        Self {
            connections: ConnectionState {
                midi_in: Vec::new(),
                midi_out: Vec::new(),
                audio_in: Vec::new(),
                audio_out: Vec::new(),
                click_track_out: Vec::new(),
            },
            metronome: MetronomeState {
                frames_per_beat: 96000, // 120 BPM at 192kHz sample rate
                click_volume: 0.5,      // Default 50% volume
            },
            track_volumes: TrackVolumes::new(),
        }
    }
}
