<?php

namespace EasyLinkAutomations\Triggers\WooCommerce;

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

use EasyLinkAutomations\Triggers\BaseTrigger;

/**
 * Trigger that fires when a WooCommerce order status changes.
 */
final class OrderStatusChangedTrigger extends BaseTrigger
{
    public static function getSlug(): string
    {
        return 'woocommerce/order_status_changed';
    }

    public static function getName(): string
    {
        return __('Order status changed', 'easylink-automations');
    }

    public static function getDescription(): string
    {
        return __('Triggers when a WooCommerce order status changes from one status to another', 'easylink-automations');
    }

    public static function getCategory(): string
    {
        return 'WooCommerce';
    }

    public static function getIcon(): string
    {
        return 'woocommerce';
    }


    public static function isAvailable(): bool
    {
        return class_exists('WooCommerce');
    }

    public static function getOutputFields(): array
    {
        return [
            'order_id'                   => ['label' => 'Order ID', 'type' => 'number'],
            'order_number'               => ['label' => 'Order Number', 'type' => 'string'],
            'from_status'                => ['label' => 'From Status', 'type' => 'string'],
            'to_status'                  => ['label' => 'To Status', 'type' => 'string'],
            'order_total'                => ['label' => 'Order Total', 'type' => 'string'],
            'order_subtotal'             => ['label' => 'Order Subtotal', 'type' => 'string'],
            'order_tax'                  => ['label' => 'Order Tax', 'type' => 'string'],
            'order_shipping'             => ['label' => 'Order Shipping', 'type' => 'string'],
            'order_currency'             => ['label' => 'Order Currency', 'type' => 'string'],
            'order_date'                 => ['label' => 'Order Date', 'type' => 'datetime'],
            'order_payment_method'       => ['label' => 'Payment Method', 'type' => 'string'],
            'order_payment_method_title' => ['label' => 'Payment Method Title', 'type' => 'string'],
            'billing_first_name'         => ['label' => 'Billing First Name', 'type' => 'string'],
            'billing_last_name'          => ['label' => 'Billing Last Name', 'type' => 'string'],
            'billing_email'              => ['label' => 'Billing Email', 'type' => 'email'],
            'billing_phone'              => ['label' => 'Billing Phone', 'type' => 'string'],
            'billing_address_1'          => ['label' => 'Billing Address 1', 'type' => 'string'],
            'billing_city'               => ['label' => 'Billing City', 'type' => 'string'],
            'billing_state'              => ['label' => 'Billing State', 'type' => 'string'],
            'billing_postcode'           => ['label' => 'Billing Postcode', 'type' => 'string'],
            'billing_country'            => ['label' => 'Billing Country', 'type' => 'string'],
            'shipping_address_1'         => ['label' => 'Shipping Address 1', 'type' => 'string'],
            'shipping_city'              => ['label' => 'Shipping City', 'type' => 'string'],
            'shipping_state'             => ['label' => 'Shipping State', 'type' => 'string'],
            'shipping_postcode'          => ['label' => 'Shipping Postcode', 'type' => 'string'],
            'shipping_country'           => ['label' => 'Shipping Country', 'type' => 'string'],
            'products'                   => ['label' => 'Products (JSON)', 'type' => 'json'],
            'user_id'                    => ['label' => 'Customer User ID', 'type' => 'number'],
            'user_email'                 => ['label' => 'Customer Email', 'type' => 'email'],
            'first_name'                 => ['label' => 'Customer First Name', 'type' => 'string'],
            'last_name'                  => ['label' => 'Customer Last Name', 'type' => 'string'],
        ];
    }

    public static function getConfigFields(): array
    {
        return [
            'from_status' => [
                'label'   => 'From Status (optional)',
                'type'    => 'select',
                'options' => [
                    ['value' => 'any',        'label' => 'Any'],
                    ['value' => 'pending',    'label' => 'Pending payment'],
                    ['value' => 'processing', 'label' => 'Processing'],
                    ['value' => 'on-hold',    'label' => 'On hold'],
                    ['value' => 'completed',  'label' => 'Completed'],
                    ['value' => 'cancelled',  'label' => 'Cancelled'],
                    ['value' => 'refunded',   'label' => 'Refunded'],
                    ['value' => 'failed',     'label' => 'Failed'],
                ],
                'default' => 'any',
            ],
            'to_status' => [
                'label'   => 'To Status (optional)',
                'type'    => 'select',
                'options' => [
                    ['value' => 'any',        'label' => 'Any'],
                    ['value' => 'pending',    'label' => 'Pending payment'],
                    ['value' => 'processing', 'label' => 'Processing'],
                    ['value' => 'on-hold',    'label' => 'On hold'],
                    ['value' => 'completed',  'label' => 'Completed'],
                    ['value' => 'cancelled',  'label' => 'Cancelled'],
                    ['value' => 'refunded',   'label' => 'Refunded'],
                    ['value' => 'failed',     'label' => 'Failed'],
                ],
                'default' => 'any',
            ],
        ];
    }

    public function register(callable $callback): void
    {
        $this->callback = $callback;

        add_action('woocommerce_order_status_changed', function (int $orderId, string $fromStatus, string $toStatus, \WC_Order $order): void {
            $data = $this->handle($orderId, $fromStatus, $toStatus);
            $this->fire($data);
        }, 10, 4);
    }

    public function handle(mixed ...$args): array
    {
        $orderId    = (int) $args[0];
        $fromStatus = (string) $args[1];
        $toStatus   = (string) $args[2];

        $order = wc_get_order($orderId);

        if (!$order instanceof \WC_Order) {
            return [];
        }

        $userId  = (int) $order->get_customer_id();
        $user    = $userId ? get_userdata($userId) : null;
        $dateObj = $order->get_date_created();

        $products = [];
        foreach ($order->get_items() as $item) {
            $productId   = (int) $item->get_product_id();
            $product     = wc_get_product($productId);
            $categories  = wp_get_post_terms($productId, 'product_cat', ['fields' => 'names']);
            $tags        = wp_get_post_terms($productId, 'product_tag', ['fields' => 'names']);
            $products[]  = [
                'product_id'   => $productId,
                'product_name' => $item->get_name(),
                'quantity'     => $item->get_quantity(),
                'total'        => $item->get_total(),
                'sku'          => $product ? $product->get_sku() : '',
                'category'     => implode(', ', $categories),
                'tag'          => implode(', ', $tags),
            ];
        }

        return [
            'order_id'                   => $orderId,
            'order_number'               => $order->get_order_number(),
            'from_status'                => 'wc-' . $fromStatus,
            'to_status'                  => 'wc-' . $toStatus,
            'order_total'                => $order->get_total(),
            'order_subtotal'             => $order->get_subtotal(),
            'order_tax'                  => $order->get_total_tax(),
            'order_shipping'             => $order->get_shipping_total(),
            'order_currency'             => $order->get_currency(),
            'order_date'                 => $dateObj ? $dateObj->format('Y-m-d H:i:s') : '',
            'order_payment_method'       => $order->get_payment_method(),
            'order_payment_method_title' => $order->get_payment_method_title(),
            'billing_first_name'         => $order->get_billing_first_name(),
            'billing_last_name'          => $order->get_billing_last_name(),
            'billing_email'              => $order->get_billing_email(),
            'billing_phone'              => $order->get_billing_phone(),
            'billing_address_1'          => $order->get_billing_address_1(),
            'billing_city'               => $order->get_billing_city(),
            'billing_state'              => $order->get_billing_state(),
            'billing_postcode'           => $order->get_billing_postcode(),
            'billing_country'            => $order->get_billing_country(),
            'shipping_address_1'         => $order->get_shipping_address_1(),
            'shipping_city'              => $order->get_shipping_city(),
            'shipping_state'             => $order->get_shipping_state(),
            'shipping_postcode'          => $order->get_shipping_postcode(),
            'shipping_country'           => $order->get_shipping_country(),
            'products'                   => $products,
            'user_id'                    => $userId,
            'user_email'                 => $user->user_email ?? $order->get_billing_email(),
            'first_name'                 => $user->first_name ?? $order->get_billing_first_name(),
            'last_name'                  => $user->last_name ?? $order->get_billing_last_name(),
        ];
    }
}
