<?php

namespace Licenzo\Modules\EDD;

use Licenzo\Helper\Settings;

if (!defined('ABSPATH')) {
    exit;
}

class EddCheckoutPolicyService
{
    /**
     * @var EddStripeCompatibilityService
     */
    private $stripeCompatibility;

    public function __construct(?EddStripeCompatibilityService $stripeCompatibility = null)
    {
        $this->stripeCompatibility = $stripeCompatibility ?? new EddStripeCompatibilityService();
    }

    public function register(): void
    {
        add_action('edd_checkout_error_checks', [$this, 'validateCheckout'], 10, 2);
    }

    /**
     * Validate checkout rules for subscription purchases.
     *
     * Enforced at checkout (not add-to-cart) because EDD's edd_pre_add_to_cart
     * is an action that cannot prevent item addition.
     *
     * @param array $validData
     * @param array $postData
     */
    public function validateCheckout($validData, $postData): void
    {
        if (!$this->cartHasRecurringItem()) {
            return;
        }

        $this->validateSingleSubscriptionItem();
        $this->validateLoginRequirement($postData);
    }

    private function validateSingleSubscriptionItem(): void
    {
        $recurringCount = $this->countRecurringItemsInCart();

        edd_set_error(
            'licenzo_single_subscription',
            __('Only one subscription item is allowed per checkout. Please remove extra subscription items from your cart.', 'licenzo')
        );
    }

    private function validateLoginRequirement(array $postData): void
    {
        if (is_user_logged_in()) {
            return;
        }

        $settings = Settings::getSubscriptionSettings();

        if (($settings['allow_guest_checkout'] ?? 'no') !== 'yes') {
            edd_set_error(
                'licenzo_login_required',
                __('You are trying to buy a subscription. You must be logged in to continue.', 'licenzo')
            );
            return;
        }

        if (($settings['enforce_login'] ?? 'yes') === 'yes') {
            $createAccount = false;
            if (isset($postData['edd_create_account'])) {
                $raw = strtolower(sanitize_text_field(wp_unslash($postData['edd_create_account'])));
                $createAccount = in_array($raw, ['1', 'true', 'yes', 'on'], true);
            }

            edd_set_error(
                'licenzo_account_required',
                __('You are trying to buy a subscription. Please log in or create an account to continue.', 'licenzo')
            );
        }
    }

    private function cartHasRecurringItem(): bool
    {
        return $this->countRecurringItemsInCart() > 0;
    }

    private function countRecurringItemsInCart(): int
    {
        $cart = edd_get_cart_contents() ?: [];

        if (!is_array($cart)) {
            return 0;
        }

        $count = 0;
        foreach ($cart as $cartItem) {
            $downloadId = (int) ($cartItem['id'] ?? 0);
            $priceId = isset($cartItem['options']['price_id']) ? (int) $cartItem['options']['price_id'] : null;

            if ($this->stripeCompatibility->isRecurringMappedProductInLicenzo($downloadId, $priceId)) {
                $count++;
            }
        }

        return $count;
    }
}
