<?php
/**
 * GGM Commerce Order Tools
 *
 * MCP Tools for order management operations
 * Tools are executable actions that AI can invoke
 *
 * @package GGM_Commerce
 * @since 1.0.0
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter

class GGM_Commerce_Order_Tools {

    /**
     * MCP Server instance
     * @var GGM_Commerce_MCP_Server
     */
    private $server;

    /**
     * Constructor
     *
     * @param GGM_Commerce_MCP_Server $server MCP server instance
     */
    public function __construct($server) {
        $this->server = $server;
        $this->register_tools();
    }

    /**
     * Register all order tools
     */
    private function register_tools() {
        // Create order
        $this->server->register_tool(
            'create_order',
            'Create a new order from cart or specified items',
            [
                'type' => 'object',
                'properties' => [
                    'customer' => [
                        'type' => 'object',
                        'description' => 'Customer information',
                        'properties' => [
                            'email' => ['type' => 'string', 'format' => 'email'],
                            'first_name' => ['type' => 'string'],
                            'last_name' => ['type' => 'string'],
                            'phone' => ['type' => 'string'],
                            'billing_address_1' => ['type' => 'string'],
                            'billing_city' => ['type' => 'string'],
                            'billing_state' => ['type' => 'string'],
                            'billing_postcode' => ['type' => 'string'],
                            'billing_country' => ['type' => 'string']
                        ],
                        'required' => ['email', 'first_name', 'last_name']
                    ],
                    'items' => [
                        'type' => 'array',
                        'description' => 'Order items',
                        'items' => [
                            'type' => 'object',
                            'properties' => [
                                'product_id' => ['type' => 'integer', 'minimum' => 1],
                                'quantity' => ['type' => 'integer', 'minimum' => 1]
                            ],
                            'required' => ['product_id', 'quantity']
                        ]
                    ],
                    'notes' => [
                        'type' => 'string',
                        'description' => 'Order notes'
                    ]
                ],
                'required' => ['customer', 'items']
            ],
            [$this, 'create_order']
        );

        // Update order status
        $this->server->register_tool(
            'update_order_status',
            'Update order status and/or payment status (admin only)',
            [
                'type' => 'object',
                'properties' => [
                    'order_id' => [
                        'type' => 'integer',
                        'description' => 'Order ID to update',
                        'minimum' => 1
                    ],
                    'status' => [
                        'type' => 'string',
                        'description' => 'New order status',
                        'enum' => ['pending', 'processing', 'completed', 'cancelled']
                    ],
                    'payment_status' => [
                        'type' => 'string',
                        'description' => 'New payment status',
                        'enum' => ['pending', 'paid', 'failed', 'refunded']
                    ]
                ],
                'required' => ['order_id']
            ],
            [$this, 'update_order_status']
        );

        // Cancel order
        $this->server->register_tool(
            'cancel_order',
            'Cancel an order and restore inventory',
            [
                'type' => 'object',
                'properties' => [
                    'order_id' => [
                        'type' => 'integer',
                        'description' => 'Order ID to cancel',
                        'minimum' => 1
                    ],
                    'reason' => [
                        'type' => 'string',
                        'description' => 'Cancellation reason'
                    ]
                ],
                'required' => ['order_id']
            ],
            [$this, 'cancel_order']
        );

        // Generate order invoice
        $this->server->register_tool(
            'generate_order_invoice',
            'Generate a formatted invoice for an order',
            [
                'type' => 'object',
                'properties' => [
                    'order_id' => [
                        'type' => 'integer',
                        'description' => 'Order ID',
                        'minimum' => 1
                    ]
                ],
                'required' => ['order_id']
            ],
            [$this, 'generate_order_invoice']
        );
    }

    /**
     * Create a new order
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function create_order($args) {
        // Load orders class
        require_once plugin_dir_path(dirname(__FILE__)) . 'orders.php';
        $orders = GGM_Commerce_Orders::get_instance();

        $customer_data = $args['customer'];
        $cart_items = $args['items'];
        $notes = isset($args['notes']) ? $args['notes'] : '';

        // Create the order
        $result = $orders->create_order($customer_data, $cart_items, $notes);

        if (is_wp_error($result)) {
            return [
                'success' => false,
                'error' => $result->get_error_message()
            ];
        }

        return [
            'success' => true,
            'message' => 'Order created successfully',
            'order' => $result
        ];
    }

    /**
     * Update order status
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function update_order_status($args) {
        $order_id = intval($args['order_id']);

        global $wpdb;

        // Get current order
        $order = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_orders WHERE id = %d",
            $order_id
        ));

        if (!$order) {
            return [
                'success' => false,
                'error' => 'Order not found'
            ];
        }

        // Build update array
        $update_data = [];

        if (isset($args['status'])) {
            $update_data['status'] = sanitize_text_field($args['status']);
        }

        if (isset($args['payment_status'])) {
            $update_data['payment_status'] = sanitize_text_field($args['payment_status']);
        }

        if (empty($update_data)) {
            return [
                'success' => false,
                'error' => 'No updates provided'
            ];
        }

        $update_data['updated_at'] = current_time('mysql');

        // Update order
        $updated = $wpdb->update(
            "{$wpdb->prefix}ggmc_orders",
            $update_data,
            ['id' => $order_id]
        );

        if ($updated === false) {
            return [
                'success' => false,
                'error' => 'Failed to update order'
            ];
        }

        // Get updated order
        $updated_order = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_orders WHERE id = %d",
            $order_id
        ));

        return [
            'success' => true,
            'message' => 'Order updated successfully',
            'order' => $updated_order
        ];
    }

    /**
     * Cancel an order
     *
     * @param array $args Tool arguments
     * @return array Result
     */
    public function cancel_order($args) {
        $order_id = intval($args['order_id']);
        $reason = isset($args['reason']) ? sanitize_textarea_field($args['reason']) : '';

        global $wpdb;

        // Get order
        $order = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_orders WHERE id = %d",
            $order_id
        ));

        if (!$order) {
            return [
                'success' => false,
                'error' => 'Order not found'
            ];
        }

        // Check if already cancelled
        if ($order->status === 'cancelled') {
            return [
                'success' => false,
                'error' => 'Order is already cancelled'
            ];
        }

        // Start transaction
        $wpdb->query('START TRANSACTION');

        try {
            // Update order status
            $wpdb->update(
                "{$wpdb->prefix}ggmc_orders",
                [
                    'status' => 'cancelled',
                    'updated_at' => current_time('mysql')
                ],
                ['id' => $order_id]
            );

            // Add cancellation note using the new notes system
            $cancel_note = 'Order cancelled via MCP';
            if (!empty($reason)) {
                $cancel_note .= ': ' . $reason;
            }
            GGM_Commerce_Order_Notes::add_system_note($order_id, $cancel_note);

            // Restore inventory for order items
            $items = $wpdb->get_results($wpdb->prepare(
                "SELECT product_id, quantity FROM {$wpdb->prefix}ggmc_order_items WHERE order_id = %d",
                $order_id
            ));

            foreach ($items as $item) {
                $wpdb->query($wpdb->prepare(
                    "UPDATE {$wpdb->prefix}ggmc_products
                    SET stock = stock + %d
                    WHERE id = %d",
                    $item->quantity,
                    $item->product_id
                ));
            }

            $wpdb->query('COMMIT');

            return [
                'success' => true,
                'message' => 'Order cancelled and inventory restored',
                'order_number' => $order->order_number,
                'items_restored' => count($items)
            ];

        } catch (Exception $e) {
            $wpdb->query('ROLLBACK');

            return [
                'success' => false,
                'error' => 'Failed to cancel order: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Generate order invoice
     *
     * @param array $args Tool arguments
     * @return string Formatted invoice
     */
    public function generate_order_invoice($args) {
        $order_id = intval($args['order_id']);

        global $wpdb;

        // Get order
        $order = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}ggmc_orders WHERE id = %d",
            $order_id
        ));

        if (!$order) {
            return [
                'success' => false,
                'error' => 'Order not found'
            ];
        }

        // Get order items
        $items = $wpdb->get_results($wpdb->prepare(
            "SELECT
                oi.*,
                p.name as product_name,
                p.sku as product_sku
            FROM {$wpdb->prefix}ggmc_order_items oi
            LEFT JOIN {$wpdb->prefix}ggmc_products p ON oi.product_id = p.id
            WHERE oi.order_id = %d",
            $order_id
        ));

        // Generate invoice text
        $invoice = "═════════════════════════════════════════\n";
        $invoice .= "          INVOICE\n";
        $invoice .= "═════════════════════════════════════════\n\n";
        $invoice .= "Order #: " . $order->order_number . "\n";
        $invoice .= "Date: " . gmdate('F j, Y', strtotime($order->created_at)) . "\n";
        $invoice .= "Status: " . strtoupper($order->status) . "\n";
        $invoice .= "Payment: " . strtoupper($order->payment_status) . "\n\n";

        $invoice .= "BILL TO:\n";
        $invoice .= "─────────────────────────────────────────\n";
        $invoice .= $order->customer_first_name . " " . $order->customer_last_name . "\n";
        $invoice .= $order->customer_email . "\n";
        if (!empty($order->customer_phone)) {
            $invoice .= $order->customer_phone . "\n";
        }
        if (!empty($order->billing_address_1)) {
            $invoice .= $order->billing_address_1 . "\n";
            if (!empty($order->billing_address_2)) {
                $invoice .= $order->billing_address_2 . "\n";
            }
            $invoice .= $order->billing_city . ", " . $order->billing_state . " " . $order->billing_postcode . "\n";
            $invoice .= $order->billing_country . "\n";
        }

        $invoice .= "\nITEMS:\n";
        $invoice .= "─────────────────────────────────────────\n";

        foreach ($items as $item) {
            $item_total = $item->price * $item->quantity;
            $invoice .= sprintf(
                "%-30s x%-3d $%8.2f\n",
                substr($item->product_name, 0, 30),
                $item->quantity,
                $item_total
            );
            if (!empty($item->product_sku)) {
                $invoice .= "  SKU: " . $item->product_sku . "\n";
            }
        }

        $invoice .= "\n─────────────────────────────────────────\n";
        $invoice .= sprintf("Subtotal:                       $%8.2f\n", $order->subtotal ?? 0);

        if (isset($order->tax_amount) && $order->tax_amount > 0) {
            $invoice .= sprintf("Tax:                            $%8.2f\n", $order->tax_amount);
        }

        if (isset($order->shipping_amount) && $order->shipping_amount > 0) {
            $invoice .= sprintf("Shipping:                       $%8.2f\n", $order->shipping_amount);
        }

        if (isset($order->discount_amount) && $order->discount_amount > 0) {
            $invoice .= sprintf("Discount:                      -$%8.2f\n", $order->discount_amount);
        }

        $invoice .= "─────────────────────────────────────────\n";
        $invoice .= sprintf("TOTAL:                          $%8.2f\n", $order->total_amount);
        $invoice .= "═════════════════════════════════════════\n";

        // Get customer-visible notes only
        $customer_notes = GGM_Commerce_Order_Notes::get_customer_notes($order_id);
        if (!empty($customer_notes)) {
            $invoice .= "\nNOTES:\n";
            foreach ($customer_notes as $note) {
                $invoice .= $note->content . "\n";
            }
        }

        $invoice .= "\nThank you for your business!\n";

        return [
            'success' => true,
            'invoice' => $invoice,
            'order_number' => $order->order_number
        ];
    }
}
