<?php
/**
 * Caterpoint Order Importer
 * 
 * Creates backend orders from normalized Caterpoint data
 * Independent implementation - does not rely on ahs-magento module
 *
 * @category    PortalPeople
 * @package     Caterpoint
 */

namespace PortalPeople\caterpoint\components;

use Yii;
use backend\models\Address;
use backend\models\Cartlines;
use backend\models\Cartsbe;
use backend\models\Paymentresponsesbe;
use backend\models\Productsbe;
use backend\models\Shipment;

/**
 * Import normalized Caterpoint orders into backend system
 */
class OrderImporter
{
    /**
     * Create a backend order from normalized Caterpoint data
     * 
     * Transforms normalized order data into a backend\models\Cartsbe record
     * with associated cart lines, shipment, and payment information.
     * 
     * This is the Caterpoint-specific equivalent of ahs-magento\models\Carts::NewMagentoOrder()
     * but operates independently without dependency on the magento module.
     * 
    * @param array $orderData Normalized order data (from DataNormalizer)
    * @param array $productMappings Optional item index => product ID overrides from the bulk import UI
     * @return Cartsbe|null The created and saved cart model, or null on failure
     */
    public static function newCaterPointOrder(array $orderData, array $productMappings = []): ?Cartsbe
    {
        try {
            // Reject certain payment methods if needed
            $paymentMethod = $orderData['payment']['method'] ?? null;
            if ($paymentMethod === 'stripe_payments_invoice') {
                Yii::warning('Order rejected: payment method stripe_payments_invoice is awaiting payment.', 'caterpoint-import');
                return null;
            }

            // Create base cart model
            $model = new Cartsbe();
            $model->sourceurl = $orderData['order_source'] ?? 'caterpoint';
            $model->id = $model::tempId() ?? \Yii::$app->security->generateRandomString(16);
            $model->status = 'Paid'; // Caterpoint orders are pre-approved
            $model->dateordered = strtotime($orderData['order']['updated_at']);
            $model->email = $orderData['customer']['email'];
            $model->contact = trim($orderData['customer']['firstname'] . ' ' . $orderData['customer']['lastname']);

            // Set up addresses
            $fulladdresses = [];
            
            $billingAddress = new Address();
            $billingAddress->address1 = $orderData['billing_address']['street'] ?? '';
            $billingAddress->town = $orderData['billing_address']['city'] ?? '';
            $billingAddress->postcode = $orderData['billing_address']['postcode'] ?? '';
            $billingAddress->telephone = $orderData['billing_address']['telephone'] ?? '';
            
            $shippingAddress = new Address();
            $shippingAddress->address1 = $orderData['shipping_address']['street'] ?? '';
            $shippingAddress->town = $orderData['shipping_address']['city'] ?? '';
            $shippingAddress->postcode = $orderData['shipping_address']['postcode'] ?? '';
            $shippingAddress->telephone = $orderData['shipping_address']['telephone'] ?? '';
            
            $fulladdresses['billing'] = $billingAddress;
            $fulladdresses['shipping'] = $shippingAddress;
            $model->fulladdresses = $fulladdresses;

            // Add cart lines from order items
            foreach ($orderData['items'] as $itemIndex => $item) {
                $selectedProductId = isset($productMappings[$itemIndex]) ? (string) $productMappings[$itemIndex] : null;
                $product = ProductLookup::resolveProduct($item, $selectedProductId);
                if ($product) {
                    $cartline = new Cartlines();
                    $cartline->basketid = $model->id;
                    $cartline->productid = $product->id;
                    $cartline->product_name = $item['name'] ?? $product->product_name;
                    $cartline->qty = $item['qty_ordered'];
                    $cartline->price = ($item['row_total_incl_tax'] ?? 0) / max($item['qty_ordered'], 1);
                    $cartline->dispatch = 0;
                    $cartline->requested_date = $orderData['shipping_fields']['shipping_date'] ?? null;
                    
                    if (($item['discount_amount'] ?? 0) > 0) {
                        $cartline->disc = $item['discount_amount'] / max($item['qty_ordered'], 1);
                    }
                    
                    $cartline->save();
                } else {
                    $sku = $item['sku'] ?? 'unknown';
                    $name = $item['name'] ?? 'unknown';
                    Yii::warning("Product not found for Caterpoint item. SKU: {$sku}; Name: {$name}", 'caterpoint-import');
                }
            }

            // Set delivery information
            $model->delivery_date = $orderData['shipping_fields']['shipping_date'] ?? null;
            $model->delivery_message = $orderData['shipping_fields']['shipping_message'] ?? 'Caterpoint Order';

            // Create shipment record
            $shipment = new Shipment();
            $shipment->shipment_type = 0;
            $shipment->cart_id = $model->id;
            $shipment->delivery = $orderData['shipping_method']['description'] ?? 'Caterpoint Delivery';
            $shipment->shipment_date = $orderData['shipping_fields']['shipping_date'] ?? null;
            $shipment->save();

            // Handle payment method
            $method = $orderData['payment']['method'] ?? 'caterpoint_order';
            
            if ($method === 'paypal_express') {
                self::handlePayPalPayment($model->id, $orderData);
            } elseif ($method === 'stripe_payments') {
                self::handleStripePayment($model->id, $orderData);
            } else {
                // Default payment handling for Caterpoint orders
                self::handleCaterpointPayment($model->id, $orderData);
            }

            // Set billing status if payment was successful
            $lastPayment = Paymentresponsesbe::find()
                ->where(['basketid' => $model->id])
                ->orderBy(['id' => SORT_DESC])
                ->one();
            
            if ($lastPayment && $lastPayment->status === 'Paid') {
                $model->billingstatus = 'Paid';
            }

            // Save and return model
            if ($model->save()) {
                Yii::info("Backend order created from Caterpoint: {$model->id}", 'caterpoint-import');
                return $model;
            } else {
                Yii::error("Failed to save cart model: " . json_encode($model->errors), 'caterpoint-import');
                return null;
            }
        } catch (\Throwable $e) {
            Yii::error("Exception in newCaterPointOrder: {$e->getMessage()}", 'caterpoint-import');
            return null;
        }
    }

    /**
     * Handle PayPal payment
     * 
     * @param string $cartId Cart ID
     * @param array $orderData Order data
     */
    private static function handlePayPalPayment(string $cartId, array $orderData): void
    {
        $paymentStatus = 'Pending';
        $paymentRef = null;

        if (isset($orderData['payment']['additional_information'])) {
            $additionalInfo = $orderData['payment']['additional_information'];
            
            if (isset($additionalInfo['paypal_pending_reason'])) {
                $paymentStatus = $additionalInfo['paypal_pending_reason'] === 'authorization' ? 'Paid' : 'Pending';
            }
            
            if (isset($additionalInfo['paypal_correlation_id'])) {
                $paymentRef = $additionalInfo['paypal_correlation_id'];
            }
        }

        $pay = new Paymentresponsesbe();
        $pay->basketid = $cartId;
        $pay->paymentmethod = 'PayPal';
        $pay->status = $paymentStatus;
        $pay->paymentref = $paymentRef;
        $pay->source = $orderData['order_source'] ?? 'caterpoint';
        $pay->amount = $orderData['order']['grand_total'] ?? 0;
        $pay->save();
    }

    /**
     * Handle Stripe payment
     * 
     * @param string $cartId Cart ID
     * @param array $orderData Order data
     */
    private static function handleStripePayment(string $cartId, array $orderData): void
    {
        $paymentStatus = 'Pending';
        $paymentRef = null;

        if (isset($orderData['payment']['additional_information'])) {
            $additionalInfo = $orderData['payment']['additional_information'];
            
            if (isset($additionalInfo['is_transaction_pending'])) {
                $paymentStatus = $additionalInfo['is_transaction_pending'] === false ? 'Paid' : 'Pending';
            }
            
            if (isset($additionalInfo['payment_intent_id'])) {
                $paymentRef = $additionalInfo['payment_intent_id'];
            }
        }

        $pay = new Paymentresponsesbe();
        $pay->basketid = $cartId;
        $pay->paymentmethod = 'Stripe';
        $pay->status = $paymentStatus;
        $pay->paymentref = $paymentRef;
        $pay->source = $orderData['order_source'] ?? 'caterpoint';
        $pay->amount = $orderData['order']['grand_total'] ?? 0;
        $pay->save();
    }

    /**
     * Handle Caterpoint payment (default)
     * 
     * Caterpoint orders are always marked as paid
     * 
     * @param string $cartId Cart ID
     * @param array $orderData Order data
     */
    private static function handleCaterpointPayment(string $cartId, array $orderData): void
    {
        $pay = new Paymentresponsesbe();
        $pay->basketid = $cartId;
        $pay->paymentmethod = $orderData['payment']['method'] ?? 'Caterpoint';
        $pay->status = 'Paid'; // Caterpoint orders are always paid
        $pay->paymentref = $orderData['order']['id'] ?? null;
        $pay->source = $orderData['order_source'] ?? 'caterpoint';
        $pay->amount = $orderData['order']['grand_total'] ?? 0;
        $pay->save();
    }
}
