use client::{Authentication, ClientConfig};
use lightyear::prelude::*;
use lightyear::server::config::ServerConfig;
use std::time::Duration;

pub const PRIVIATE_KEY: Key = [12; 32];
pub const FIXED_TIMESTEP_HZ: f64 = 64.0;
pub const REPLICATION_INTERVAL: Duration = Duration::from_millis(100);
pub const LOCAL_IP: &str = "127.0.0.1:7000";
pub const ANY_IP: &str = "0.0.0.0:0";

pub fn client_config() -> ClientConfig {
    let auth = Authentication::Manual {
        server_addr: "127.0.0.1:7001".parse().unwrap(),
        client_id: 2,
        private_key: PRIVIATE_KEY,
        protocol_id: 0,
    };
    let netcode_config = client::NetcodeConfig::default();
    let io_config = client::IoConfig {
        transport: client::ClientTransport::UdpSocket(ANY_IP.parse().unwrap()),
        conditioner: None,
        compression: CompressionConfig::default(),
    };
    let net = client::NetConfig::Netcode {
        auth,
        config: netcode_config,
        io: io_config,
    };
    ClientConfig {
        shared: shared_config(Mode::Separate),
        net,
        ..Default::default()
    }
}

pub fn server_config() -> ServerConfig {
    let netcode_config = server::NetcodeConfig {
        protocol_id: 0,
        private_key: PRIVIATE_KEY,
        ..Default::default()
    };
    let io_config = server::IoConfig {
        transport: server::ServerTransport::UdpSocket(LOCAL_IP.parse().unwrap()),
        conditioner: None,
        compression: CompressionConfig::default(),
    };
    let net = server::NetConfig::Netcode {
        config: netcode_config,
        io: io_config,
    };
    ServerConfig {
        shared: shared_config(Mode::Separate),
        net: vec![net],
        replication: ReplicationConfig {
            send_interval: REPLICATION_INTERVAL,
            ..Default::default()
        },
        ..Default::default()
    }
}

/// The [`SharedConfig`] must be shared between the `ClientConfig` and `ServerConfig`
pub fn shared_config(mode: Mode) -> SharedConfig {
    SharedConfig {
        server_replication_send_interval: REPLICATION_INTERVAL,
        tick: TickConfig {
            tick_duration: Duration::from_secs_f64(1.0 / FIXED_TIMESTEP_HZ),
        },
        mode,
    }
}
