//! Channel handler — 1:1 DM channel creation.

use std::sync::Arc;

use bytes::Bytes;
use prost::Message;
use quicproquo_proto::qpq::v1;
use quicproquo_rpc::method::{HandlerResult, RequestContext};

use crate::domain::channels::ChannelService;
use crate::domain::types::CreateChannelReq;
use crate::hooks::ChannelEvent;

use super::{domain_err, require_auth, ServerState};

pub async fn handle_create_channel(
    state: Arc<ServerState>,
    ctx: RequestContext,
) -> HandlerResult {
    let identity_key = match require_auth(&state, &ctx) {
        Ok(ik) => ik,
        Err(e) => return e,
    };

    let req = match v1::CreateChannelRequest::decode(ctx.payload) {
        Ok(r) => r,
        Err(e) => {
            return HandlerResult::err(
                quicproquo_rpc::error::RpcStatus::BadRequest,
                &format!("decode: {e}"),
            )
        }
    };

    let svc = ChannelService {
        store: Arc::clone(&state.store),
    };

    let domain_req = CreateChannelReq {
        peer_key: req.peer_key.clone(),
    };

    match svc.create_channel(domain_req, &identity_key) {
        Ok(resp) => {
            state.hooks.on_channel_created(&ChannelEvent {
                channel_id: resp.channel_id.clone(),
                initiator_key: identity_key,
                peer_key: req.peer_key,
                was_new: resp.was_new,
            });

            let proto = v1::CreateChannelResponse {
                channel_id: resp.channel_id,
                was_new: resp.was_new,
            };
            HandlerResult::ok(Bytes::from(proto.encode_to_vec()))
        }
        Err(e) => domain_err(e),
    }
}
