<?php
/**
 * BookiFlex Stripe Payment Extension
 *
 * @package    BookiFlex
 * @subpackage StripePayment
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Extensions\StripePayment\ValueObject;

defined( 'ABSPATH' ) || exit;

/**
 * Type-safe representation of a Stripe Checkout Session line_item.
 *
 * This value object encapsulates the structure required by Stripe's Checkout Session API
 * for a single line item with pricing and product data.
 *
 * @package BookiFlex\Extensions\StripePayment\Pro\ValueObject
 */
final class StripeLineItem
{
    /**
     * Create a new Stripe line item.
     *
     * @param string $name Product name displayed to customer
     * @param int $quantity Number of units (nights for accommodation, count for services)
     * @param string $currency Currency code in lowercase (e.g., 'eur', 'usd')
     * @param int $unitAmountCents Unit price in minor units (cents)
     * @param string|null $description Long-form product description (optional)
     * @param array<string> $images Array of image URLs (max 8, must be publicly accessible)
     * @param array<string, string> $metadata Custom key-value pairs for tracking
     */
    public function __construct(
        private readonly string $name,
        private readonly int $quantity,
        private readonly string $currency,
        private readonly int $unitAmountCents,
        private readonly ?string $description = null,
        private readonly array $images = [],
        private readonly array $metadata = []
    ) {
    }

    /**
     * Convert to Stripe API array format.
     *
     * Returns the structure expected by Stripe's Checkout Session line_items parameter.
     *
     * @return array<string, mixed> Stripe-compatible line item array
     */
    public function toArray(): array
    {
        $productData = [
            'name' => $this->name,
        ];

        // Add optional fields only if provided
        if ($this->description !== null && $this->description !== '') {
            $productData['description'] = $this->description;
        }

        if (!empty($this->images)) {
            $productData['images'] = $this->images;
        }

        if (!empty($this->metadata)) {
            $productData['metadata'] = $this->metadata;
        }

        return [
            'quantity' => $this->quantity,
            'price_data' => [
                'currency' => $this->currency,
                'unit_amount' => $this->unitAmountCents,
                'product_data' => $productData,
            ],
        ];
    }

    /**
     * Get product name.
     *
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Get quantity.
     *
     * @return int
     */
    public function getQuantity(): int
    {
        return $this->quantity;
    }

    /**
     * Get currency code.
     *
     * @return string
     */
    public function getCurrency(): string
    {
        return $this->currency;
    }

    /**
     * Get unit amount in cents.
     *
     * @return int
     */
    public function getUnitAmountCents(): int
    {
        return $this->unitAmountCents;
    }

    /**
     * Get description.
     *
     * @return string|null
     */
    public function getDescription(): ?string
    {
        return $this->description;
    }

    /**
     * Get image URLs.
     *
     * @return array<string>
     */
    public function getImages(): array
    {
        return $this->images;
    }

    /**
     * Get metadata.
     *
     * @return array<string, string>
     */
    public function getMetadata(): array
    {
        return $this->metadata;
    }
}