/*
 * authservice process/announcements.rs
 * - announcement-related request functions
 *
 * Copyright (C) 2025 Real Microsoft, LLC
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

use std::future::Future;
use asklyphe_common::nats::authservice::announcements::{AnnouncementFull, AnnouncementFullRequest, AnnouncementFullResponse, AnnouncementListRequest, AnnouncementListResponse, AnnouncementShortForm, LatestAnnouncementRequest, LatestAnnouncementResponse};
use log::warn;
use sea_orm::DatabaseConnection;
use crate::db::{announcements, user};
use crate::db::announcements::{AnnouncementFetchError, AnnouncementRecord};
use crate::db::user::{FetchUserError, UserInfo};

pub async fn latest_announcement(db: &DatabaseConnection, request: LatestAnnouncementRequest) -> LatestAnnouncementResponse {
    match announcements::latest_announcement(db).await {
        Ok(v) => {
            LatestAnnouncementResponse::Some(AnnouncementShortForm {
                title: v.title,
                short_text: v.short,
                date: v.created_on.timestamp(),
                slug: v.slug,
            })
        }
        Err(e) => match e {
            AnnouncementFetchError::SlugNotFound => {
                LatestAnnouncementResponse::None
            }
            AnnouncementFetchError::DatabaseError => {
                LatestAnnouncementResponse::InternalServerError("database error".to_string())
            }
        }
    }
}

// fixme: listen to limit and actually limit the amount returned
pub async fn announcement_list(db: &DatabaseConnection, request: AnnouncementListRequest) -> AnnouncementListResponse {
    match announcements::get_all_announcements(db).await {
        Ok(v) => {
            AnnouncementListResponse::Success(v.into_iter().map(|v| {
                AnnouncementShortForm {
                    title: v.title,
                    short_text: v.short,
                    date: v.created_on.timestamp(),
                    slug: v.slug,
                }
            }).collect())
        }
        Err(e) => match e {
            AnnouncementFetchError::SlugNotFound => {
                AnnouncementListResponse::Success(vec![])
            }
            AnnouncementFetchError::DatabaseError => {
                AnnouncementListResponse::InternalServerError("database error".to_string())
            }
        }
    }
}

pub async fn announcement_full(db: &DatabaseConnection, request: AnnouncementFullRequest) -> AnnouncementFullResponse {
    match announcements::get_announcement(db, request.slug).await {
        Ok(v) => {
            let username = match user::user_info(db, v.creator_uid.clone()).await {
                Ok(v) => {
                    v.username
                }
                Err(e) => {
                    match e {
                        FetchUserError::UserNotFound => {
                            warn!("creator {} not found for announcement", v.creator_uid);
                        }
                        FetchUserError::DatabaseError => {
                            warn!("database error while getting full announcement");
                        }
                    }
                    "lyphe".to_string()
                }
            };
            AnnouncementFullResponse::Some(AnnouncementFull {
                title: v.title,
                created_on: v.created_on.timestamp(),
                updated_on: v.updated_on.map(|v| v.timestamp()),
                slug: v.slug,
                creator: username,
                markdown_text: v.full,
            })
        }
        Err(e) => match e {
            AnnouncementFetchError::SlugNotFound => {
                AnnouncementFullResponse::NotFound
            }
            AnnouncementFetchError::DatabaseError => {
                AnnouncementFullResponse::InternalServerError("database error".to_string())
            }
        }
    }
}