<?php

namespace classes;

require_once WD . '/modules/stripe/stripe_c.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_customers.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_payment_link.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_product.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_prices.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_invoice.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_readers.php';
require_once WD . '/modules/stripe/endpoints/stripe_endpoint_payment_intents.php';


// Require all helper classes
require_once WD . '/modules/stripe/helpers/stripe_line_items.php';
require_once WD . '/modules/stripe/helpers/stripe_line_item.php';
require_once WD . '/modules/stripe/helpers/stripe_product.php';
require_once WD . '/modules/stripe/helpers/stripe_price.php';


use Exception;
use interfaces\stripe_i;
use stripe\endpoints\stripe_endpoint_customers;
use stripe\endpoints\stripe_endpoint_invoice;
use stripe\endpoints\stripe_endpoint_payment_intents;
use stripe\endpoints\stripe_endpoint_payment_link;
use stripe\endpoints\stripe_endpoint_prices;
use stripe\endpoints\stripe_endpoint_product;
use stripe\endpoints\stripe_endpoint_readers;
use stripe\stripe_c;
use Stripe\StripeClient;

/**
 * Stripe module
 * @see https://docs.stripe.com/api/customers/create?lang=php
 */
class stripe implements stripe_i
{
    /**
     * Configuration of the stripe module
     * @var stripe_c
     */
    public stripe_c $config;
    /**
     * Customers endpoint
     * @var stripe_endpoint_customers
     */
    public stripe_endpoint_customers $customers;
    /**
     * Payment link endpoint
     * @var stripe_endpoint_payment_link
     */
    public stripe_endpoint_payment_link $payment_link;
    /**
     * Product endpoint
     * @var stripe_endpoint_product
     */
    public stripe_endpoint_product $product;
    /**
     * Prices endpoint
     * @var stripe_endpoint_prices
     */
    public stripe_endpoint_prices $prices;
    /**
     * Invoice endpoint
     * @var stripe_endpoint_invoice
     */
    public stripe_endpoint_invoice $invoice;
    /**
     * Readers endpoint
     * @var stripe_endpoint_readers
     */
    public stripe_endpoint_readers $readers;
    /**
     * Payment intents endpoint
     * @var stripe_endpoint_payment_intents
     */
    public stripe_endpoint_payment_intents $payment_intents;
    /**
     * Stripe client
     * @var StripeClient
     */
    protected StripeClient $client;


    public function __construct()
    {
        $this->config = new stripe_c();
        $this->customers = new stripe_endpoint_customers();
        $this->payment_link = new stripe_endpoint_payment_link();
        $this->product = new stripe_endpoint_product();
        $this->prices = new stripe_endpoint_prices();
        $this->invoice = new stripe_endpoint_invoice();
        $this->readers = new stripe_endpoint_readers();
        $this->payment_intents = new stripe_endpoint_payment_intents();
    }

    /**
     * @inheritDoc
     * @throws Exception
     */
    public function getClient(): StripeClient
    {
        // Get the stripe client
        if (!isset($this->client)) {
            // Require the module to be enabled
            self::requireModuleEnabled();
            // Require the secret key to be set
            self::requireValidSecretKey();
            // Require the publishable key to be set
            self::requireValidPublishableKey();
            // Create the client
            $this->client = new StripeClient([
                'api_key' => $this->config->secret_key->getVariableValue()
            ]);
        }
        return $this->client;
    }

    /**
     * @inheritDoc
     * @throws Exception
     */
    function requireModuleEnabled(): void
    {
        // Check if the module is enabled
        if (!$this->config->enabled->isTrue()) {
            throw new Exception('The Stripe module is not enabled');
        }
    }

    /**
     * @inheritDoc
     * @throws Exception
     */
    function requireValidSecretKey(): void
    {
        // Check if the secret key is valid
        if ($this->config->secret_key->getVariableValue() === null) {
            throw new Exception('Invalid secret key');
        }
    }

    /**
     * @inheritDoc
     * @throws Exception
     */
    public function requireValidPublishableKey(): void
    {
        // Check if the publishable key is valid
        if ($this->config->publishable_key->getVariableValue() === null) {
            throw new Exception('Invalid publishable key');
        }
    }
}