// Copyright (C) 2026 Ordinary Labs, LLC.
//
// SPDX-License-Identifier: AGPL-3.0-only

use crate::cmds::accounts::get_current_account;
use clap::Subcommand;
use ordinary_api::client::OrdinaryApiClient;

#[derive(Subcommand, Debug)]
pub enum Content {
    /// manage content definitions for Ordinary project
    Definition {
        #[command(subcommand)]
        definition: Definition,
    },
    /// manage content objects for Ordinary project
    Object {
        #[command(subcommand)]
        object: Object,
    },
    /// update content for application running on `ordinaryd` instance
    Update,
}

#[derive(Subcommand, Debug)]
pub enum Definition {
    /// add a content definition to your Ordinary project
    Add {
        /// content definition / instance name
        name: String,

        /// JSON formatted list of fields
        ///
        /// EXAMPLE: `'[{ "idx": 0, "name": "some", "kind": "String" }, { "idx": 1, "name": "thing", "kind": "I32" }]'`
        fields: String,
    },
    /// edit a content definition to your Ordinary project
    Edit {
        /// numerical identifier / index for the content definition
        idx: u8,

        /// content definition / instance name
        name: String,

        /// JSON formatted list of fields
        ///
        /// EXAMPLE: `'[{ "idx": 0, "name": "some", "kind": "String" }, { "idx": 1, "name": "thing", "kind": "I32" }]'`
        fields: String,
    },
}

#[derive(Subcommand, Debug)]
pub enum Object {
    /// add a content object to your Ordinary project
    Add {
        /// json value of content object
        json: String,
    },
    /// edit a content object to your Ordinary project
    Edit {
        /// json value of content object
        json: String,
    },
    /// delete a content object to your Ordinary project
    Delete {
        /// instance name that matches the content definition
        instance_of: String,
        /// unique identifier for the object to be deleted
        uuid: String,
    },
}

impl Content {
    pub async fn handle(
        &self,
        api_domain: Option<&str>,
        accept_invalid_certs: bool,
        project: &str,
        insecure: bool,
    ) -> anyhow::Result<()> {
        let account = get_current_account(insecure)?;
        let client = OrdinaryApiClient::new(
            &account.host,
            &account.name,
            api_domain,
            accept_invalid_certs,
            crate::USER_AGENT,
            false,
        )?;

        match self {
            Self::Definition { definition } => match definition {
                Definition::Add { name, fields } => {
                    ordinary_modify::content::add_def(project, name, fields)?;
                }
                Definition::Edit { idx, name, fields } => {
                    ordinary_modify::content::edit_def(project, *idx, Some(name.clone()), fields)?;
                }
            },
            Self::Object { object } => match object {
                Object::Add { json } => {
                    ordinary_modify::content::add_obj(project, json)?;
                }
                Object::Edit { json } => {
                    ordinary_modify::content::edit_obj(project, json)?;
                }
                Object::Delete { instance_of, uuid } => {
                    ordinary_modify::content::delete_obj(project, instance_of, uuid)?;
                }
            },
            Self::Update => {
                client.update(project).await?;
            }
        }

        Ok(())
    }
}
