#[derive(Clone, Debug)]
pub struct Checkout<'a> {
    api: &'a crate::Api,
    access_token: &'a crate::AccessToken,
}

impl<'a> Checkout<'a> {
    pub fn new(api: &'a crate::Api, access_token: &'a crate::AccessToken) -> Self {
        Self { api, access_token }
    }

    pub fn create(
        &self,
        amount: f32,
        currency: &str,
        checkout_ref: &str,
        pay_to_email: &str,
        description: Option<&str>,
        pay_from_email: Option<&str>,
        return_url: Option<&str>,
    ) -> crate::Result<crate::Checkout> {
        let mut payload = ureq::json!({
            "amount": amount,
            "currency": currency,
            "checkout_reference": checkout_ref,
            "pay_to_email": pay_to_email,
            "description": description,
        });

        if let Some(pay_from_email) = pay_from_email {
            payload["pay_from_email"] = serde_json::Value::String(pay_from_email.to_string());
        }

        if let Some(return_url) = return_url {
            payload["return_url"] = serde_json::Value::String(return_url.to_string());
        }

        self.api.checkout_create(&payload, self.access_token)
    }

    pub fn find_by_id(&self, id: &str) -> crate::Result<crate::Checkout> {
        self.api.checkout_get(id, self.access_token)
    }

    pub fn find_by_reference_id(&self, reference_id: &str) -> crate::Result<crate::Checkout> {
        self.api
            .checkout_reference_id(reference_id, self.access_token)
    }

    pub fn delete(&self, id: &str) -> crate::Result {
        self.api.checkout_delete(id, self.access_token)
    }

    pub fn pay(
        &self,
        id: &str,
        customer_id: &str,
        card_token: &str,
        installments: Option<u8>,
    ) -> crate::Result {
        let payload = ureq::json!({
            "payment_typ": "card",
            "customer_id": customer_id,
            "token": card_token,
            "installments": installments.unwrap_or(1),
        });

        self.api.checkout_update(id, &payload, self.access_token)
    }
}
