use tauri::{AppHandle, Emitter};

use crate::news::{
    NewsSourceConfig, QueryNewsFeedRequest, QueryNewsFeedResponse, RefreshNewsFeedRequest,
    RefreshNewsFeedResult, SaveNewsFeedConfigRequest, UpdateNewsArticleStateRequest,
};
use crate::state::AppState;

#[tauri::command]
pub async fn query_news_feed(
    state: tauri::State<'_, AppState>,
    request: QueryNewsFeedRequest,
) -> Result<QueryNewsFeedResponse, String> {
    state
        .news_service
        .query_feed(request)
        .await
        .map_err(|error| error.to_string())
}

#[tauri::command]
pub async fn refresh_news_feed(
    app: AppHandle,
    state: tauri::State<'_, AppState>,
    request: RefreshNewsFeedRequest,
) -> Result<RefreshNewsFeedResult, String> {
    let result = state
        .news_service
        .refresh_feed(request)
        .await
        .map_err(|error| error.to_string())?;

    app.emit("news_feed_updated", &result)
        .map_err(|error| error.to_string())?;

    Ok(result)
}

#[tauri::command]
pub async fn get_news_feed_config(
    state: tauri::State<'_, AppState>,
) -> Result<Vec<NewsSourceConfig>, String> {
    state
        .news_service
        .get_feed_config()
        .await
        .map_err(|error| error.to_string())
}

#[tauri::command]
pub async fn save_news_feed_config(
    state: tauri::State<'_, AppState>,
    request: SaveNewsFeedConfigRequest,
) -> Result<Vec<NewsSourceConfig>, String> {
    state
        .news_service
        .save_feed_config(request)
        .await
        .map_err(|error| error.to_string())
}

#[tauri::command]
pub async fn reset_news_feed_config(
    state: tauri::State<'_, AppState>,
) -> Result<Vec<NewsSourceConfig>, String> {
    state
        .news_service
        .reset_feed_config()
        .await
        .map_err(|error| error.to_string())
}

#[tauri::command]
pub async fn update_news_article_state(
    state: tauri::State<'_, AppState>,
    request: UpdateNewsArticleStateRequest,
) -> Result<(), String> {
    state
        .news_service
        .update_article_state(request)
        .await
        .map_err(|error| error.to_string())
}
