use indieweb::http::Client;
use indieweb::standards::indieauth::AccessToken;
use indieweb::standards::micropub::action::{Action, ActionResponse, CreationProperties};
use indieweb::algorithms::Properties;
use serde::Serialize;
use url::Url;
use std::collections::HashMap;

#[derive(Serialize)]
pub struct CreateResult {
    pub location: String,
    pub sync: bool,
}

pub async fn run(
    client: &impl Client,
    endpoint: &Url,
    access_token: &AccessToken,
    content: &str,
    post_type: &str,
    category: Option<Vec<String>>,
    name: Option<String>,
) -> miette::Result<CreateResult> {
    let mf2_class = match post_type.to_lowercase().as_str() {
        "entry" | "note" | "article" => indieweb::mf2::types::Class::Known(indieweb::mf2::types::KnownClass::Entry),
        "event" => indieweb::mf2::types::Class::Known(indieweb::mf2::types::KnownClass::Event),
        "card" => indieweb::mf2::types::Class::Known(indieweb::mf2::types::KnownClass::Card),
        "cite" => indieweb::mf2::types::Class::Known(indieweb::mf2::types::KnownClass::Cite),
        _ => indieweb::mf2::types::Class::Known(indieweb::mf2::types::KnownClass::Entry),
    };

    let mut extra_fields = Properties::default();
    extra_fields.insert("content".to_string(), serde_json::json!([content]));
    
    if let Some(name) = name {
        extra_fields.insert("name".to_string(), serde_json::json!([name]));
    }

    let mut parameters = indieweb::standards::micropub::Parameters::default();
    if let Some(categories) = category {
        parameters.category = categories;
    }

    let action = Action::Create {
        properties: Box::new(CreationProperties {
            r#type: mf2_class,
            parameters,
            extra_fields,
        }),
        files: HashMap::new(),
    };

    let response = action.send(client, endpoint, access_token).await?;

    match response {
        ActionResponse::Created { sync, location, .. } => {
            Ok(CreateResult {
                location: location.to_string(),
                sync,
            })
        }
        _ => Err(miette::miette!("Unexpected response from Micropub server")),
    }
}
