<?php

namespace stripe\helpers;

use classes\stripe;
use Exception;
use Stripe\Exception\ApiErrorException;

class stripe_line_item
{
    /**
     * @var int $product_id
     */
    protected int $product_id;
    /**
     * Price (Unit amount)
     * @var int $price
     */
    protected int $price;
    /**
     * @var int $quantity
     */
    protected int $quantity;
    protected string $price_id;

    /**
     * @throws Exception
     */
    public function __construct(int $product_id, int $price, int $quantity = 1)
    {
        // Multiply the price by 100 to convert it to the smallest currency unit
        $price = $price * 100;
        // Check if the product exists
        if (!self::doesProductExist($product_id)) {
            // If the product does not exist, import it from the database
            self::createProduct($product_id);
        }
        // Create the price object (This seems redundant, but it is necessary for the Stripe API)
        self::createPrice($product_id, $price);
        $this->product_id = $product_id;
        $this->price = $price;
        $this->quantity = $quantity;
    }

    /**
     * Check if a product exists
     * @param int $product_id
     * @return bool
     */
    public static function doesProductExist(int $product_id): bool
    {
        // Check if the product exists
        $stripe = new stripe();
        try {
            $stripe->product->retrieve($product_id);
            return true;
        } catch (ApiErrorException|Exception $e) {
            return false;
        }
    }

    /**
     * Create a product
     * @param int $product_id
     * @throws ApiErrorException
     * @throws Exception
     */
    public static function createProduct(int $product_id): void
    {
        // Create a new product
        $stripe = new stripe();
        $stripe->product->create(
            new stripe_product($product_id)
        );
    }

    /**
     * Create a price
     * @param int $product_id
     * @param int $unit_amount
     * @throws ApiErrorException
     */
    private function createPrice(int $product_id, int $unit_amount): void
    {
        // Create a new price
        $stripe = new stripe();
        $price = $stripe->prices->create(
            new stripe_price($product_id, $unit_amount)
        );
        $this->price_id = $price->id;
    }

    public function __toString(): string
    {
        // Return the line item as a JSON string
        return json_encode(
            self::get()
        );
    }

    public function get($type = 'payment_link'): array
    {
        if ($type === 'invoice') {
            return [
                'price' => (string)$this->price_id,
                'amount' => (int)$this->quantity,
            ];
        }
        return [
            //'product' => (int)$this->product_id,
            'price' => (string)$this->price_id,
            'quantity' => (int)$this->quantity,
        ];
    }
}