use closure_app::core::provider::{Provider, ProviderStore};
use closure_app::core::store::Store;
use std::collections::HashMap;
use tempfile::TempDir;

#[test]
fn test_store_roundtrip() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());
    store.init("password").unwrap();

    let mut env = HashMap::new();
    env.insert("ANTHROPIC_AUTH_TOKEN".to_string(), "sk-test".to_string());

    let data = ProviderStore {
        version: 1,
        providers: vec![Provider::ClaudeCode {
            name: "test-provider".to_string(),
            model: Some("kimi-for-coding".to_string()),
            env,
        }],
    };

    store.save(&data).unwrap();
    let loaded = store.load().unwrap();

    assert_eq!(loaded, data);
}

#[test]
fn test_store_load_without_auth_fails() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());

    let result = store.load();
    assert!(result.is_err());
}

#[test]
fn test_store_init() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());

    assert!(!store.has_encrypted());

    let store_data = store.init("password").unwrap();
    assert!(store.has_encrypted());
    assert!(store.is_authenticated());
    assert_eq!(store_data.providers.len(), 0);

    // Double init should fail
    let result = store.init("password2");
    assert!(result.is_err());
}

#[test]
fn test_backup_restore_roundtrip() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());
    store.init("password").unwrap();

    let mut data = store.load().unwrap();
    data.providers.push(Provider::Codex {
        name: "p1".to_string(),
        api_key: Some("sk-1".to_string()),
        base_url: Some("https://one".to_string()),
        model: Some("gpt-5.5".to_string()),
        model_provider: Some("OpenAI".to_string()),
        review_model: None,
    });
    store.save(&data).unwrap();

    let mut next = store.load().unwrap();
    next.providers.clear();
    store.save(&next).unwrap();
    assert_eq!(store.load().unwrap().providers.len(), 0);

    let backups = store.list_backups().unwrap();
    assert!(!backups.is_empty());
    let id = backups.last().unwrap().id.clone();

    store.restore_backup(&id).unwrap();
    let restored = store.load().unwrap();
    assert_eq!(restored.providers.len(), 1);
    assert_eq!(restored.providers[0].name(), "p1");
}

#[test]
fn test_verify_accepts_logged_out_vault() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());
    store.init("password").unwrap();
    store.logout().unwrap();

    let health = store.verify().unwrap();
    // Locked vault is normal — manifest validation must not fail
    // because providers.json is legitimately absent after logout.
    assert!(
        !health
            .issues
            .iter()
            .any(|issue| issue.contains("manifest invalid")),
        "manifest should not be invalid after logout: {:?}",
        health.issues
    );
}

#[test]
fn test_verify_reports_missing_state() {
    let tmp = TempDir::new().unwrap();
    let store = Store::new(tmp.path());
    store.init("password").unwrap();

    std::fs::remove_file(tmp.path().join("state.json")).unwrap();
    let health = store.verify().unwrap();
    assert!(!health.is_healthy());
    assert!(
        health
            .issues
            .iter()
            .any(|issue| issue.contains("state.json missing"))
    );
}
