<?php

namespace stripe\endpoints;

use Exception;
use Stripe\Collection;
use Stripe\Exception\ApiErrorException;
use Stripe\PaymentIntent;
use traits\stripe_endpoint_t;

class stripe_endpoint_payment_intents
{
    use stripe_endpoint_t;

    /**
     * Get all readers
     * @return Collection
     * @throws ApiErrorException
     * @throws Exception
     */
    public function list(): Collection
    {
        return self::getClient()->paymentIntents->all();
    }

    /**
     * Get a payment intent by ID
     * @param string $id
     * @param array|null $params
     * @param array|null $opts
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function get(string $id, array $params = null, array $opts = null): PaymentIntent
    {
        return self::getClient()->paymentIntents->retrieve($id, $params, $opts);
    }

    /**
     * Create a payment intent
     * @param float $total_net_amount
     * @param array $data
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function create(float $total_net_amount, array $data = []): PaymentIntent
    {
        $default_data = [
            'amount' => $total_net_amount,
            'currency' => 'dkk',
            'payment_method_types' => ['card_present'],
            'capture_method' => 'manual',
        ];
        $data = array_merge($default_data, $data);
        return self::getClient()->paymentIntents->create($data);
    }

    /**
     * Update a payment intent
     * @param string $id
     * @param array $data
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function update(string $id, array $data): PaymentIntent
    {
        return self::getClient()->paymentIntents->update($id, $data);
    }

    /**
     * Cancel a payment intent
     * @param string $id
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function cancel(string $id): PaymentIntent
    {
        return self::getClient()->paymentIntents->cancel($id);
    }

    /**
     * Process a payment intent
     * @param string $id
     * @param array $data
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function process(string $id, array $data): PaymentIntent
    {
        $payment_intent = self::getClient()->paymentIntents->retrieve($id);
        if ($payment_intent->status == 'requires_confirmation') {
            return self::confirm($id, $data);
        } elseif ($payment_intent->status == 'requires_capture') {
            return self::capture($id, $data);
        } elseif ($payment_intent->status == 'requires_action') {
            return self::confirm($id, $data);
        } else {
            throw new Exception('Payment intent is not in a state to be processed');
        }
    }

    /**
     * Confirm a payment intent
     * @param string $id
     * @param array $data
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function confirm(string $id, array $data): PaymentIntent
    {
        return self::getClient()->paymentIntents->confirm($id, $data);
    }

    /**
     * Capture a payment intent
     * @param string $id
     * @param array $data
     * @return PaymentIntent
     * @throws ApiErrorException
     * @throws Exception
     */
    public function capture(string $id, array $data): PaymentIntent
    {
        return self::getClient()->paymentIntents->capture($id, $data);
    }
}