<?php

declare(strict_types=1);

namespace CloudXM\NFe\Services;

use CloudXM\NFe\Config\Configuration;
use CloudXM\NFe\DTOs\IssueInvoiceRequest;
use CloudXM\SDK\Support\HasLogger;

/**
 * Resolves scheduling metadata from a WooCommerce order and decorates
 * an IssueInvoiceRequest with the appropriate scheduling/webhook fields.
 */
class NFeSchedulingService
{
    use HasLogger;

    public function __construct(private Configuration $config) {}

    // -------------------------------------------------------------------------
    // Task 9.2 — resolve scheduled_at from order meta
    // -------------------------------------------------------------------------

    /**
     * Read the configured date field from the order and return an ISO 8601
     * string if the date is valid and in the future, or null otherwise.
     */
    public function resolveScheduledAt(\WC_Order $order): ?string
    {
        $fieldKey = $this->config->getScheduleDateField();

        if ($fieldKey === '') {
            return null;
        }

        $rawValue = $order->get_meta($fieldKey);

        if (empty($rawValue)) {
            return null;
        }

        $parsed = $this->parseDate((string) $rawValue);

        if ($parsed === null) {
            $this->log()->warning('nfe.schedule_date_parse_failed', [
                'order_id'  => $order->get_id(),
                'field_key' => $fieldKey,
                'raw_value' => $rawValue,
            ]);
            return null;
        }

        if ($parsed->getTimestamp() <= time()) {
            $this->log()->warning('nfe.schedule_date_past', [
                'order_id'    => $order->get_id(),
                'field_key'   => $fieldKey,
                'scheduled_at' => $parsed->format(\DateTime::ATOM),
            ]);
            return null;
        }

        // Convert to ISO 8601 with configured timezone offset
        $timezone = new \DateTimeZone($this->config->getScheduleTimezone());
        $parsed->setTimezone($timezone);

        return $parsed->format(\DateTime::ATOM);
    }

    // -------------------------------------------------------------------------
    // Task 9.3 — webhook URL
    // -------------------------------------------------------------------------

    /**
     * Returns the WordPress REST URL for the NFe webhook endpoint.
     */
    public function getWebhookUrl(): string
    {
        return rest_url('cloudxm-nfe/v1/webhook');
    }

    // -------------------------------------------------------------------------
    // Task 9.4 — build scheduled request
    // -------------------------------------------------------------------------

    /**
     * Clone $base and decorate it with scheduling and webhook fields.
     */
    public function buildScheduledRequest(\WC_Order $order, IssueInvoiceRequest $base): IssueInvoiceRequest
    {
        $scheduledAt = $this->resolveScheduledAt($order);

        $decorated = clone $base;
        $decorated->issue_mode              = 'scheduled';
        $decorated->scheduled_at            = $scheduledAt;
        $decorated->timezone                = $this->config->getScheduleTimezone();
        $decorated->webhook_url             = $this->getWebhookUrl();
        $decorated->webhook_secret          = $this->config->getWebhookSecret();
        $decorated->retry_on_failure        = $this->config->getScheduleRetryOnFailure();
        $decorated->max_retries             = $this->config->getScheduleMaxRetries();
        $decorated->retry_interval_minutes  = $this->config->getScheduleRetryIntervalMinutes();

        return $decorated;
    }

    // -------------------------------------------------------------------------
    // Task 20.1 — build async request
    // -------------------------------------------------------------------------

    /**
     * Clone $base and decorate it for async mode.
     * No scheduled_at / timezone / retry fields — server queues immediately.
     */
    public function buildAsyncRequest(\WC_Order $order, IssueInvoiceRequest $base): IssueInvoiceRequest
    {
        $decorated = clone $base;
        $decorated->issue_mode     = 'async';
        $decorated->webhook_url    = $this->getWebhookUrl();
        $decorated->webhook_secret = $this->config->getWebhookSecret();

        return $decorated;
    }

    // -------------------------------------------------------------------------
    // Helpers
    // -------------------------------------------------------------------------

    /**
     * Try to parse a date string in multiple formats.
     * Returns a \DateTime in UTC on success, null on failure.
     */
    private function parseDate(string $value): ?\DateTime
    {
        // Try ISO 8601 first (handles timezone offsets)
        $dt = \DateTime::createFromFormat(\DateTime::ATOM, $value);
        if ($dt !== false) {
            return $dt;
        }

        // Y-m-d H:i:s
        $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $value, new \DateTimeZone('UTC'));
        if ($dt !== false) {
            return $dt;
        }

        // Y-m-d (midnight UTC)
        $dt = \DateTime::createFromFormat('Y-m-d', $value, new \DateTimeZone('UTC'));
        if ($dt !== false) {
            $dt->setTime(0, 0, 0);
            return $dt;
        }

        return null;
    }
}
