use serde_json::{Value, json};

use crate::client::Client;
use crate::error::Error;
use crate::types::{CreateTicketsResult, Ticket, TicketType};

impl Client {
    pub async fn create_tickets(&self, n: u32, show_result: bool) -> Result<Vec<Value>, Error> {
        // Returns a JSON array; we deserialize into Value so callers see the full payload.
        self.call_keyed(
            "createTickets",
            json!({ "n": n, "showResult": show_result }),
        )
        .await
    }

    pub async fn reveal_tickets(&self, ticket_id: &str) -> Result<Value, Error> {
        self.call_keyed("revealTickets", json!({ "ticketId": ticket_id }))
            .await
    }

    pub async fn list_tickets(&self, ticket_type: TicketType) -> Result<Vec<Value>, Error> {
        self.call_keyed("listTickets", json!({ "ticketType": ticket_type }))
            .await
    }

    pub async fn get_ticket(&self, ticket_id: &str) -> Result<Ticket, Error> {
        // getTicket does NOT take an apiKey.
        self.call("getTicket", json!({ "ticketId": ticket_id }))
            .await
    }

    /// Untyped getTicket — for inspection when the response shape is uncertain.
    pub async fn get_ticket_raw(&self, ticket_id: &str) -> Result<Value, Error> {
        self.call("getTicket", json!({ "ticketId": ticket_id }))
            .await
    }

    /// Typed variant of create_tickets returning the stub array.
    pub async fn create_tickets_typed(
        &self,
        n: u32,
        show_result: bool,
    ) -> Result<CreateTicketsResult, Error> {
        let v: Vec<crate::types::TicketStub> = self
            .call_keyed(
                "createTickets",
                json!({ "n": n, "showResult": show_result }),
            )
            .await?;
        Ok(CreateTicketsResult(v))
    }
}
