// SPDX-FileCopyrightText: Politik im Blick developers
// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
//
// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2

use std::sync::Arc;

use axum::{
    Json,
    extract::{Path, State},
    response::Redirect,
};
use pib_service_api_types::body::meeting::{
    GetMeetingListResponseBody, Meeting, PostMeetingRequestBody,
};
use pib_service_inventory::NewMeeting;
use uuid::Uuid;

use crate::{Result, ServiceState};

pub(crate) mod by_meeting_id;

pub(crate) async fn get(
    State(service_state): State<Arc<ServiceState>>,
    Path(body_id): Path<Uuid>,
) -> Result<Json<GetMeetingListResponseBody>> {
    let mut inventory = service_state.inventory_provider.get_inventory().await?;

    let meetings = inventory.get_meetings(&body_id.to_string()).await?;

    let data = meetings
        .into_iter()
        .map(
            |pib_service_inventory::Meeting {
                 id,
                 created,
                 modified,
                 body: _,
                 organization,
                 start,
                 end,
                 name,
                 meeting_state,
                 agenda_item: _,
                 keyword: _,
                 license,
                 web,
             }| Meeting {
                id,
                organization_id: organization,
                name: name.map(Into::into),
                meeting_state: Some(meeting_state.into()),
                created,
                modified,
                body_id,
                start,
                end,
                license,
                web,
            },
        )
        .collect();

    Ok(Json(GetMeetingListResponseBody { data }))
}

pub(crate) async fn post(
    State(service_state): State<Arc<ServiceState>>,
    Path(body_id): Path<Uuid>,
    Json(PostMeetingRequestBody {
        organization_id,
        name,
        meeting_state,
        keyword,
        start,
        end,
        license,
        web,
    }): Json<PostMeetingRequestBody>,
) -> Result<Redirect> {
    let mut inventory = service_state.inventory_provider.get_inventory().await?;
    let state = meeting_state.parse()?;
    let meeting = inventory
        .create_meeting(NewMeeting {
            body_id,
            organization_id,
            start,
            end,
            name,
            state,
            keyword,
            license,
            web,
        })
        .await?;
    let meeting_id = meeting.id;
    Ok(Redirect::to(&format!(
        "/body/{body_id}/meeting/{meeting_id}"
    )))
}
