//! In-memory new-game campaign draft.
//!
//! This is the current persistence boundary for the Rust client: the accepted
//! galaxy, character draft, and starting-base choice survive state transitions
//! during new-game setup. A later SpacetimeDB integration can replace the
//! storage backend while keeping this data shape as the handoff contract.

use bevy::prelude::*;

use crate::gameplay::character_creation::CharacterDraft;
use crate::gameplay::galaxy::{GalaxyParams, SystemContents};
use crate::gameplay::starting_base::StartingBaseSelection;

#[derive(Resource, Debug, Clone, Default)]
pub struct CampaignDraft {
    pub galaxy: Option<GeneratedGalaxy>,
    pub character: Option<CharacterDraft>,
    pub starting_base: Option<StartingBaseSelection>,
}

#[derive(Debug, Clone)]
pub struct GeneratedGalaxy {
    pub params: GalaxyParams,
    pub systems: Vec<GeneratedGalaxySystem>,
    pub contents: Vec<SystemContents>,
    pub connections: Vec<(usize, usize)>,
}

#[derive(Debug, Clone)]
pub struct GeneratedGalaxySystem {
    pub id: String,
    pub name: String,
    pub position: Vec3,
    pub faction: &'static str,
    pub faction_index: usize,
    pub color: [f32; 3],
    pub security: f32,
    pub is_core: bool,
    pub(crate) is_beam: bool,
}

impl CampaignDraft {
    pub fn save_galaxy(&mut self, galaxy: GeneratedGalaxy) {
        self.galaxy = Some(galaxy);
        self.character = None;
        self.starting_base = None;
    }

    pub fn save_character(&mut self, character: CharacterDraft) {
        self.character = Some(character);
        self.starting_base = None;
    }

    pub fn save_starting_base(&mut self, selection: StartingBaseSelection) {
        self.starting_base = Some(selection);
    }

    pub fn reset_new_game(&mut self) {
        *self = Self::default();
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::gameplay::galaxy::generate_galaxy;

    #[test]
    fn campaign_save_galaxy_clears_downstream_choices() {
        let galaxy = generate_galaxy(&GalaxyParams::default());
        let character = CharacterDraft::default();
        let starting_base = StartingBaseSelection {
            system_id: "g-0".to_string(),
            system_name: "COR-100".to_string(),
            faction: "Concord",
            security: 1.0,
        };
        let mut draft = CampaignDraft {
            galaxy: None,
            character: Some(character),
            starting_base: Some(starting_base),
        };

        draft.save_galaxy(galaxy);

        assert!(draft.galaxy.is_some());
        assert!(draft.character.is_none());
        assert!(draft.starting_base.is_none());
    }

    #[test]
    fn campaign_save_character_clears_starting_base() {
        let galaxy = generate_galaxy(&GalaxyParams::default());
        let character = CharacterDraft::default();
        let starting_base = StartingBaseSelection {
            system_id: "g-0".to_string(),
            system_name: "COR-100".to_string(),
            faction: "Concord",
            security: 1.0,
        };
        let mut draft = CampaignDraft {
            galaxy: Some(galaxy),
            character: None,
            starting_base: Some(starting_base),
        };

        draft.save_character(character);

        assert!(draft.character.is_some());
        assert!(draft.starting_base.is_none());
    }
}
