use super::{apply_preview_profiles, disconnect_cooldown_remaining, disconnect_cooldown_status};
use crate::launcher::preview::{LauncherPreview, PreviewSurface};
use crate::launcher::state::{CaptureSizePreset, FeedSourcePreset, LauncherState};
use std::time::{Duration, Instant};

#[test]
/// Keeps `disconnect_cooldown_remaining_expires_cleanly` explicit because the connect-time audio epoch refresh should not be interrupted by an eager disconnect click.
/// Inputs are a synthetic monotonic clock and cooldown deadline; output is either the remaining guard duration or no guard after expiry.
fn disconnect_cooldown_remaining_expires_cleanly() {
    let now = Instant::now();
    assert_eq!(disconnect_cooldown_remaining(now, None), None);
    assert_eq!(disconnect_cooldown_remaining(now, Some(now)), None);
    assert_eq!(
        disconnect_cooldown_remaining(now, Some(now + Duration::from_secs(2))),
        Some(Duration::from_secs(2))
    );
}

#[test]
/// Keeps `disconnect_cooldown_status_names_audio_refresh` explicit because users need the disabled Disconnect button to explain the protective auto-heal window.
/// Inputs are the remaining cooldown duration; output is the user-visible status text.
fn disconnect_cooldown_status_names_audio_refresh() {
    let status = disconnect_cooldown_status(Duration::from_millis(1900));
    assert!(status.contains("audio is refreshing"));
    assert!(status.contains("disconnect unlocks in 2s"));
}

#[test]
fn fresh_preview_bootstrap_is_overridden_by_launcher_state_profiles() {
    let preview = LauncherPreview::new("http://127.0.0.1:1".to_string()).unwrap();
    let state = LauncherState::default();

    let bootstrap = preview.profile_for_test(1, PreviewSurface::Inline).unwrap();
    assert_eq!(bootstrap.0, 0);
    assert_eq!(bootstrap.3, 1280);
    assert_eq!(bootstrap.4, 720);
    assert_eq!(bootstrap.5, 30);
    assert_eq!(bootstrap.6, 6_000);

    apply_preview_profiles(&preview, &state);

    let inline = preview.profile_for_test(1, PreviewSurface::Inline).unwrap();
    assert_eq!(inline.0, 1);
    assert_eq!(inline.3, 1280);
    assert_eq!(inline.4, 720);
    assert_eq!(inline.5, 30);
    assert_eq!(inline.6, 6_000);

    let window = preview.profile_for_test(1, PreviewSurface::Window).unwrap();
    assert_eq!(window.0, 1);
    assert_eq!(window.3, 1920);
    assert_eq!(window.4, 1080);
    assert_eq!(window.5, 60);
    assert_eq!(window.6, 18_000);

    preview.shutdown_all();
}

#[test]
fn source_preview_profile_caps_inline_after_apply() {
    let preview = LauncherPreview::new("http://127.0.0.1:1".to_string()).unwrap();
    let mut state = LauncherState::default();
    state.set_capture_size_preset(1, CaptureSizePreset::P1080);

    apply_preview_profiles(&preview, &state);

    let inline = preview.profile_for_test(1, PreviewSurface::Inline).unwrap();
    assert_eq!(inline.0, 1);
    assert_eq!(inline.3, 1280);
    assert_eq!(inline.4, 720);
    assert_eq!(inline.5, 30);
    assert_eq!(inline.6, 6_000);

    preview.shutdown_all();
}

#[test]
fn mirrored_preview_profile_keeps_its_own_feed_id_but_uses_the_other_source() {
    let preview = LauncherPreview::new("http://127.0.0.1:1".to_string()).unwrap();
    let mut state = LauncherState::default();
    state.set_feed_source_preset(0, FeedSourcePreset::OtherEye);

    apply_preview_profiles(&preview, &state);

    let inline = preview.profile_for_test(0, PreviewSurface::Inline).unwrap();
    let window = preview.profile_for_test(0, PreviewSurface::Window).unwrap();
    assert_eq!(inline.0, 1);
    assert_eq!(window.0, 1);

    preview.shutdown_all();
}

#[test]
fn mirrored_preview_profile_inherits_the_source_eye_mode() {
    let preview = LauncherPreview::new("http://127.0.0.1:1".to_string()).unwrap();
    let mut state = LauncherState::default();
    state.set_feed_source_preset(0, FeedSourcePreset::OtherEye);
    state.set_capture_size_preset(1, CaptureSizePreset::P720);

    apply_preview_profiles(&preview, &state);

    let inline = preview.profile_for_test(0, PreviewSurface::Inline).unwrap();
    let window = preview.profile_for_test(0, PreviewSurface::Window).unwrap();
    assert_eq!(inline.0, 1);
    assert_eq!(window.0, 1);
    assert_eq!(inline.3, 1280);
    assert_eq!(inline.4, 720);
    assert_eq!(inline.5, 30);
    assert_eq!(inline.6, 6_000);
    assert_eq!(window.3, 1280);
    assert_eq!(window.4, 720);
    assert_eq!(window.5, 60);
    assert_eq!(window.6, 12_000);

    preview.shutdown_all();
}

#[test]
fn off_preview_profile_disables_both_surfaces_instead_of_leaving_idle_feeds_running() {
    let preview = LauncherPreview::new("http://127.0.0.1:1".to_string()).unwrap();
    let mut state = LauncherState::default();
    state.set_feed_source_preset(0, FeedSourcePreset::Off);

    apply_preview_profiles(&preview, &state);

    assert_eq!(
        preview.feed_disabled_for_test(0, PreviewSurface::Inline),
        Some(true)
    );
    assert_eq!(
        preview.feed_disabled_for_test(0, PreviewSurface::Window),
        Some(true)
    );
    assert_eq!(
        preview.feed_disabled_for_test(1, PreviewSurface::Inline),
        Some(false)
    );

    preview.shutdown_all();
}
