<?php
/**
 * Finds the orders a withdrawal may relate to.
 *
 * @package SkyServers\Retragere
 */

declare(strict_types=1);

namespace SkyServers\Retragere\Wc;

use DateTimeImmutable;
use DateTimeZone;
use SkyServers\Retragere\Wp\Settings;
use WC_Order;

/**
 * Every query here is bounded by a date window. A shop with hundreds of
 * thousands of orders must never have its whole history scanned to render a
 * dropdown.
 */
final class OrderLookup
{
    private const LIMIT = 50;

    /**
     * @return WC_Order[]
     */
    public static function forCustomer(int $userId): array
    {
        if ($userId <= 0) {
            return [];
        }

        // A unix timestamp, not a formatted string: WooCommerce parses the date
        // argument itself and a timestamp leaves no room for interpretation.
        $after = time() - (Settings::lookupDays() * DAY_IN_SECONDS);

        $orders = wc_get_orders(
            [
                'customer_id'  => $userId,
                'status'       => Settings::eligibleStatuses(),
                'date_created' => '>' . $after,
                'limit'        => self::LIMIT,
                'orderby'      => 'date',
                'order'        => 'DESC',
                'type'         => 'shop_order',
            ]
        );

        return is_array($orders) ? $orders : [];
    }

    /**
     * Primary key read. Constant cost regardless of shop size.
     *
     * @return WC_Order|null
     */
    public static function byId(int $orderId)
    {
        if ($orderId <= 0) {
            return null;
        }

        $order = wc_get_order($orderId);

        return $order instanceof WC_Order ? $order : null;
    }

    /**
     * The date the withdrawal window runs from.
     *
     * The law counts from physical possession. WooCommerce has no delivery
     * date, so we fall back through the closest proxies: completion, which most
     * Romanian shops set when the parcel ships, then payment, then creation.
     *
     * @param WC_Order $order
     */
    public static function referenceDate($order): ?DateTimeImmutable
    {
        $candidates = [
            $order->get_date_completed(),
            $order->get_date_paid(),
            $order->get_date_created(),
        ];

        foreach ($candidates as $date) {
            if (null !== $date) {
                return new DateTimeImmutable(
                    gmdate('Y-m-d H:i:s', $date->getTimestamp()),
                    new DateTimeZone('UTC')
                );
            }
        }

        return null;
    }
}
