//! Publish configuration — parsed from the `[publish]` section of `el.toml`.

/// App Store Connect / TestFlight configuration.
#[derive(Debug, Clone)]
pub struct AppleConfig {
    pub account: String,
    pub team_id: String,
    pub bundle_id: String,
    pub category: String,
}

impl AppleConfig {
    pub fn new(
        account: impl Into<String>,
        team_id: impl Into<String>,
        bundle_id: impl Into<String>,
    ) -> Self {
        Self {
            account: account.into(),
            team_id: team_id.into(),
            bundle_id: bundle_id.into(),
            category: "productivity".into(),
        }
    }

    pub fn with_category(mut self, category: impl Into<String>) -> Self {
        self.category = category.into();
        self
    }
}

/// Google Play Developer API configuration.
#[derive(Debug, Clone)]
pub struct GoogleConfig {
    pub service_account_path: String,
    pub package_name: String,
    /// Which track to publish to: "internal" | "alpha" | "beta" | "production"
    pub track: String,
}

impl GoogleConfig {
    pub fn new(
        service_account_path: impl Into<String>,
        package_name: impl Into<String>,
    ) -> Self {
        Self {
            service_account_path: service_account_path.into(),
            package_name: package_name.into(),
            track: "internal".into(),
        }
    }

    pub fn with_track(mut self, track: impl Into<String>) -> Self {
        self.track = track.into();
        self
    }
}

/// Staged rollout configuration.
#[derive(Debug, Clone)]
pub struct RolloutConfig {
    /// Initial rollout percentage (0-100).
    pub initial_percent: u8,
    /// Automatically advance rollout after `advance_after_hours` hours.
    pub auto_advance: bool,
    pub advance_after_hours: u64,
    /// Halt rollout if crash rate exceeds this fraction (0.0 - 1.0).
    pub max_crash_rate: f64,
}

impl Default for RolloutConfig {
    fn default() -> Self {
        Self {
            initial_percent: 100,
            auto_advance: false,
            advance_after_hours: 24,
            max_crash_rate: 0.01,
        }
    }
}

impl RolloutConfig {
    pub fn new(initial_percent: u8) -> Self {
        Self { initial_percent, ..Default::default() }
    }

    pub fn with_auto_advance(mut self, hours: u64) -> Self {
        self.auto_advance = true;
        self.advance_after_hours = hours;
        self
    }

    pub fn with_max_crash_rate(mut self, rate: f64) -> Self {
        self.max_crash_rate = rate;
        self
    }
}

/// The complete publish configuration.
#[derive(Debug, Clone)]
pub struct PublishConfig {
    pub version: String,
    pub build_number: u32,
    pub apple: Option<AppleConfig>,
    pub google: Option<GoogleConfig>,
    pub rollout: Option<RolloutConfig>,
    /// Directory with store metadata (title.txt, description.txt, etc.)
    pub metadata_dir: String,
    pub screenshot_targets: Vec<String>,
}

impl PublishConfig {
    pub fn new(version: impl Into<String>, build_number: u32) -> Self {
        Self {
            version: version.into(),
            build_number,
            apple: None,
            google: None,
            rollout: None,
            metadata_dir: "./store".into(),
            screenshot_targets: Vec::new(),
        }
    }

    pub fn with_apple(mut self, apple: AppleConfig) -> Self {
        self.apple = Some(apple);
        self
    }

    pub fn with_google(mut self, google: GoogleConfig) -> Self {
        self.google = Some(google);
        self
    }

    pub fn with_rollout(mut self, rollout: RolloutConfig) -> Self {
        self.rollout = Some(rollout);
        self
    }

    pub fn with_screenshot_targets(mut self, targets: Vec<impl Into<String>>) -> Self {
        self.screenshot_targets = targets.into_iter().map(|t| t.into()).collect();
        self
    }
}
