<?php

namespace Licenzo\Modules\EDD;

use Licenzo\Model\Customer;
use Licenzo\Model\Subscription;
use Licenzo\Model\SubscriptionMeta;
use Licenzo\Model\SubscriptionProduct;

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

/**
 * Creates EDD order records for Licenzo-managed subscription renewals.
 *
 * When SubscriptionRenewalService charges a renewal via Stripe, this service
 * writes the corresponding EDD order so the store owner can manage refunds,
 * view sales reports, and reconcile revenue entirely within the EDD admin.
 */
class EddRenewalOrderService
{
    /**
     * Create an EDD renewal order after a successful Licenzo charge.
     *
     * @return int|null The new EDD order ID, or null on failure.
     */
    public static function createRenewalOrder(
        Subscription $subscription,
        array $chargeResult,
        float $amountDollars,
        string $currency
    ): ?int {


        $customer = $subscription->customer;

        if (!$customer) {
            return null;
        }

        $eddCustomerId = static::resolveEddCustomerId($customer, $subscription);
        $wpUserId = (int) ($customer->user_id ?? 0);
        $email = (string) ($customer->email ?? '');

        $subProduct = $subscription->subscriptionProducts
            ? $subscription->subscriptionProducts->first()
            : SubscriptionProduct::where('subscription_id', $subscription->id)->first();

        $intentId = $chargeResult['intent']['id'] ?? '';
        $paymentMode = edd_is_test_mode() ? 'test' : 'live';

        $orderId = edd_add_order([
            'parent'      => 0,
            'status'      => 'complete',
            'type'        => 'sale',
            'user_id'     => $wpUserId,
            'customer_id' => $eddCustomerId,
            'email'       => $email,
            'ip'          => '',
            'gateway'     => 'stripe',
            'mode'        => $paymentMode,
            'currency'    => strtoupper($currency),
            'payment_key' => md5(sprintf('licenzo_renewal_%d_%s', $subscription->id, wp_generate_uuid4())),
            'subtotal'    => $amountDollars,
            'discount'    => 0,
            'tax'         => 0,
            'total'       => $amountDollars,
        ]);

        if (!$orderId || $orderId <= 0) {
            return null;
        }

        static::addOrderItem($orderId, $subProduct, $amountDollars);
        static::addOrderTransaction($orderId, $intentId, $amountDollars);
        static::addOrderMeta($orderId, $subscription);
        static::addOrderNote($orderId, $subscription, $amountDollars, $currency);

        return (int) $orderId;
    }

    private static function addOrderItem(int $orderId, ?SubscriptionProduct $subProduct, float $amountDollars): void
    {
        $downloadId = 0;
        $priceId = null;
        $productName = 'Subscription Renewal';

        if ($subProduct) {
            $downloadId = static::resolveDownloadId($subProduct);
            $priceId = static::resolvePriceId($subProduct);
            $productName = !empty($subProduct->product_name)
                ? (string) $subProduct->product_name
                : $productName;
        }

        edd_add_order_item([
            'order_id'     => $orderId,
            'product_id'   => $downloadId,
            'product_name' => $productName,
            'price_id'     => $priceId,
            'cart_index'   => 0,
            'type'         => 'download',
            'status'       => 'complete',
            'quantity'     => 1,
            'amount'       => $amountDollars,
            'subtotal'     => $amountDollars,
            'discount'     => 0,
            'tax'          => 0,
            'total'        => $amountDollars,
        ]);
    }

    private static function addOrderTransaction(int $orderId, string $intentId, float $amountDollars): void
    {
        if ($intentId === '') {
            return;
        }

        edd_add_order_transaction([
            'object_id'      => $orderId,
            'object_type'    => 'order',
            'transaction_id' => $intentId,
            'gateway'        => 'stripe',
            'status'         => 'complete',
            'total'          => $amountDollars,
        ]);
    }

    private static function addOrderMeta(int $orderId, Subscription $subscription): void
    {
        edd_update_order_meta($orderId, '_licenzo_renewal', '1');
        edd_update_order_meta($orderId, '_licenzo_subscription_id', (int) $subscription->id);

        $sourceOrderId = SubscriptionMeta::getMeta($subscription->id, 'edd_source_order_id');

        if ($sourceOrderId) {
            edd_update_order_meta($orderId, '_licenzo_parent_order_id', (int) $sourceOrderId);
        }
    }

    private static function addOrderNote(int $orderId, Subscription $subscription, float $amountDollars, string $currency): void
    {

        edd_add_note([
            'object_id'   => $orderId,
            'object_type' => 'order',
            'content'     => sprintf(
                'Auto-renewal by Licenzo — Subscription #%d, %s %s.',
                (int) $subscription->id,
                number_format($amountDollars, 2),
                strtoupper($currency)
            ),
        ]);
    }

    /**
     * Resolve the EDD customer ID from the Licenzo customer or subscription meta.
     */
    private static function resolveEddCustomerId(Customer $customer, Subscription $subscription): int
    {
        if ($customer->provider === 'edd' && (int) ($customer->provider_id ?? 0) > 0) {
            return (int) $customer->provider_id;
        }

        $sourceOrderId = SubscriptionMeta::getMeta($subscription->id, 'edd_source_order_id');
        if ($sourceOrderId) {
            $originalOrder = edd_get_order((int) $sourceOrderId);
            if ($originalOrder && (int) ($originalOrder->customer_id ?? 0) > 0) {
                return (int) $originalOrder->customer_id;
            }
        }

        if (!empty($customer->email)) {
            $eddCustomer = edd_get_customer_by('email', $customer->email);
            if ($eddCustomer && (int) ($eddCustomer->id ?? 0) > 0) {
                return (int) $eddCustomer->id;
            }
        }

        return 0;
    }

    /**
     * Resolve the EDD download ID from the subscription product chain.
     */
    private static function resolveDownloadId(SubscriptionProduct $subProduct): int
    {
        if ($subProduct->product && !empty($subProduct->product->provider_id)) {
            return (int) $subProduct->product->provider_id;
        }

        return 0;
    }

    /**
     * Resolve the EDD price ID (variation) from the subscription product chain.
     */
    private static function resolvePriceId(SubscriptionProduct $subProduct): ?int
    {
        if ($subProduct->variation && !empty($subProduct->variation->provider_id)) {
            return (int) $subProduct->variation->provider_id;
        }

        return null;
    }
}
