use clap::Parser;
use jacquard::api::com_atproto::repo::create_record::CreateRecord;
use jacquard::client::{Agent, AgentSessionExt, FileAuthStore};
use jacquard::oauth::client::OAuthClient;
use jacquard::oauth::loopback::LoopbackConfig;
use jacquard::types::string::Datetime;
use jacquard::CowStr;
use jacquard_common::types::ident::AtIdentifier;
use jacquard_common::types::string::Nsid;
use jacquard_common::types::value::Data;
use serde_json::json;

#[derive(Parser, Debug)]
#[command(author, version, about = "Create a bookmark record")]
struct Args {
    // Handle (e.g., hyperreal.at.moonshadow.dev), DID, or PDS URL
    input: CowStr<'static>,

    // Bookmark title
    #[arg(short, long)]
    title: String,

    // Bookmark URL
    #[arg(short, long)]
    url: String,

    // Bookmarks tags
    #[arg(short, long)]
    tags: Vec<String>,

    // Path to auth store file (will be created if missing)
    #[arg(long, default_value = "/tmp/jacquard-oauth-session.json")]
    store: String,
}

#[tokio::main]
async fn main() -> miette::Result<()> {
    let args = Args::parse();

    let oauth = OAuthClient::with_default_config(FileAuthStore::new(&args.store));
    let session = oauth
        .login_with_local_server(args.input, Default::default(), LoopbackConfig::default())
        .await?;

    let agent: Agent<_> = Agent::from(session);

    //let linkding_host =
    //std::env::var("LINKDING_HOST").unwrap_or("http://localhost:10407".to_string());
    //let linkding_token =
    //std::env::var("LINKDING_TOKEN").expect("LINKDING_TOKEN env variable is not set");
    //let linkding_client = LinkDingClient::new(&linkding_host, &linkding_token);

    // Create JSON record for monomark item
    let json_record = json!({
        "url": Some(args.url),
        "tags": Some(args.tags),
        "$type": "at.monomarks.bookmark",
        "title": Some(args.title),
        "createdAt": Some(Datetime::now())
    });

    let bookmark_record = CreateRecord {
        collection: Nsid::new("at.monomarks.bookmark")?,
        record: Data::from_json(&json_record)?,
        repo: AtIdentifier::new("did:plc:nuc33thnsiqzhytkleyr5jek")?,
        extra_data: None,
        rkey: None,
        swap_commit: None,
        validate: None,
    };

    let output = agent.create_record(
        bookmark_record,
        None
    ).await?;
    println!("Created monomark item: {}", output.uri);

    Ok(())
}

In the code above, the agent.create_record() method requires a type that implements the trait jacquard::types::collection::Collection. The problem is that bookmark_record's type, CreateRecord, does not implement that trait. The types listed here are the only ones that implement that trait.

The various examples I've seen using jacquard use types like Post<,_> that implement that trait. Each type seems to be pre-defined for the given NSID. at.monomarks.bookmark does not have a type defined for it. So my intention with CreateRecord was to try to create a generic record.

Is there a way to create such a generic record with Rust? Do I have to create a type myself for at.monomarks.bookmark that implements the required trait? Would it be easier, for me as an absolute beginner, to do the Rust equivalent of sending a POST request with curl to the XRPC API?

Is there so much to unpack here that I should just give up and use curl or Python? Lol.