use super::super::route_prelude::*;
use crate::config::BaseRelaysConfig;
use crate::relays::popular_relays;

#[derive(Template, Clone)]
#[template(path = "settings/relays.gmi", escape = "txt")]
struct RelaysTemplate {
    relay_list_cfg: BaseRelaysConfig,
}

#[derive(Template, Clone)]
#[template(path = "settings/add_relay_from_list.gmi", escape = "txt")]
struct AddRelayFromListTemplate {
    relay_type: String,
    relays: Vec<RelayUrl>,
}

pub async fn relays_settings(
    _ctx: RouteContext,
    user: &'static mut CaracalUser,
) -> Response {
    let relay_list_cfg = user.relay_list_config();

    Response::success(WindTemplate::render(RelaysTemplate { relay_list_cfg }))
}

pub async fn relay_modify(
    ctx: RouteContext,
    user: &'static mut CaracalUser,
) -> Response {
    let Some(input_url) = decode_query(&ctx) else {
        return Response::input("Relay URL ?");
    };

    let Ok(url) = RelayUrl::parse(&input_url) else {
        return resp_invalid_params();
    };

    let Some(mode) = ctx.parameters.get("mode") else {
        return resp_invalid_params();
    };

    let Some(op) = ctx.parameters.get("op") else {
        return resp_invalid_params();
    };

    let mut relay_list_cfg = user.relay_list_config();

    match mode {
        "write" => match op {
            "add" => relay_list_cfg.write_relays.push(url),
            "rm" => relay_list_cfg.write_relays.retain(|u| url != *u),
            &_ => todo!(),
        },
        "read" => match op {
            "add" => relay_list_cfg.read_relays.push(url),
            "rm" => relay_list_cfg.read_relays.retain(|u| url != *u),
            &_ => todo!(),
        },
        &_ => return resp_invalid_params(),
    }

    match user.save_relay_list(&relay_list_cfg) {
        Ok(_) => match user.advertise_relay_list().await {
            Ok(_) => Response::temporary_redirect("/settings/relays"),
            Err(err) => Response::temporary_failure(format!(
                "Failed to send relay list: {err}"
            )),
        },
        Err(_) => Response::temporary_failure("Failed to save config"),
    }
}

pub async fn relays_add_from_popular(
    ctx: RouteContext,
    _user: &'static mut CaracalUser,
) -> Response {
    let Some(mode) = ctx.parameters.get("mode") else {
        return resp_invalid_params();
    };

    Response::success(WindTemplate::render(AddRelayFromListTemplate {
        relays: popular_relays(),
        relay_type: mode.into(),
    }))
}
