//! Resolve control-plane credentials for play and CLI (session file, env tokens).

use flatland_protocol::AuthCredential;

use crate::config::{default_api_base, SessionConfig};

/// Bearer token + metadata for HTTP and game connect.
#[derive(Debug, Clone)]
pub struct PlayAuth {
    pub api_base: String,
    pub bearer: String,
    pub kind: PlayAuthKind,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PlayAuthKind {
    Session,
    ApiToken,
}

impl PlayAuth {
    #[allow(dead_code)]
    pub fn game_credential(&self, character_id: uuid::Uuid) -> AuthCredential {
        match self.kind {
            PlayAuthKind::Session => AuthCredential::Session {
                token: self.bearer.clone(),
            },
            PlayAuthKind::ApiToken => AuthCredential::ApiToken {
                token: self.bearer.clone(),
                character_id,
            },
        }
    }
}

/// True when play can start without showing the in-TUI login screen.
pub fn credentials_available() -> bool {
    if std::env::var("FLATLAND_API_TOKEN")
        .map(|t| !t.is_empty())
        .unwrap_or(false)
    {
        return true;
    }
    if std::env::var("FLATLAND_SESSION_TOKEN")
        .map(|t| !t.is_empty())
        .unwrap_or(false)
    {
        return true;
    }
    SessionConfig::path()
        .ok()
        .map(|p| p.is_file())
        .unwrap_or(false)
}

pub fn load_play_auth() -> anyhow::Result<PlayAuth> {
    let api_base = default_api_base();

    if let Ok(token) = std::env::var("FLATLAND_API_TOKEN") {
        if !token.is_empty() {
            return Ok(PlayAuth {
                api_base,
                bearer: token,
                kind: PlayAuthKind::ApiToken,
            });
        }
    }

    if let Ok(token) = std::env::var("FLATLAND_SESSION_TOKEN") {
        if !token.is_empty() {
            return Ok(PlayAuth {
                api_base,
                bearer: token,
                kind: PlayAuthKind::Session,
            });
        }
    }

    let session = SessionConfig::load()?;
    Ok(PlayAuth {
        api_base: session.api_base,
        bearer: session.session_token,
        kind: PlayAuthKind::Session,
    })
}
