<?php

namespace PortalPeople\netsuite\controllers\api;

use Yii;
use yii\web\Controller;
use yii\filters\VerbFilter;
use PortalPeople\netsuite\models\NetsuiteDecoder;

/**
 * Handles inbound requests from NetSuite SuiteScript webhooks.
 */
class NetsuiteController extends Controller
{
    /**
     * CSRF validation is not applicable for inbound webhook endpoints.
     */
    public $enableCsrfValidation = false;

    /**
     * {@inheritdoc}
     */
    public function behaviors(): array
    {
        $behaviors = parent::behaviors();

        $behaviors['verbs'] = [
            'class'   => VerbFilter::class,
            'actions' => [
                'updateorder' => ['POST'],
                'pickorder' => ['POST'],
            ],
        ];

        return $behaviors;
    }

    /**
     * Receive a Sales Order change payload from NetSuite PP_Order_Change.
     *
     * Decodes the payload via NetsuiteDecoder (handles json, json+gzip,
     * json+aes-cbc and json+gzip+aes-cbc formats) then logs the decoded
     * data for inspection.
     *
     * @return array JSON response.
     */
    public function actionUpdateorder(): array
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $rawBody = Yii::$app->request->rawBody;

        $decoder = new NetsuiteDecoder();
        $data    = $decoder->decode($rawBody);

        if ($data === null) {
            Yii::$app->response->statusCode = 400;
            return ['status' => 'error', 'message' => 'Failed to decode payload'];
        }
        $cart = \backend\models\Cartsbe::find()->where(['id' => $data['NGauge_OrderID']])->one();
        if ($cart->account_code == 'SCR001' && class_exists('\PortalPeople\virtualstock\models\Cart')) {
            $cart = \PortalPeople\virtualstock\models\Cart::find()->where(['id' => $data['NGauge_OrderID']])->one();
            
            $cart->status = match($data['previous']['body']['statusRef']['value']) {
                //'pendingApproval' => fn() => $cart->status = 'Pending Approval',
                'closed' => 'Closed',
                'cancelled' => 'Cancelled',
            };
            // Ensure cart JSON fields are deserialized
            if ($cart && method_exists($cart, 'loadJson') && !is_object($cart->data)) {
                try {
                    $cart->loadJson();
                } catch (\Throwable $_) {
                    // ignore
                }
            }
            if (is_object($cart->data)) {
                if (empty($cart->data->netsuite->deliveryid)) {
                    $cart->data->netsuite->deliveryid = $data['record']['id'];
                }
            }
            foreach ($data['changes']['items']['updated'] as $item) {

            }
            $cart->save();            
        }


        return ['status' => 'ok'];
    }
    /**
     * Receive a Sales Order change payload from NetSuite PP_Order_Change.
     *
     * Decodes the payload via NetsuiteDecoder (handles json, json+gzip,
     * json+aes-cbc and json+gzip+aes-cbc formats) then logs the decoded
     * data for inspection.
     *
     * @return array JSON response.
     */
    public function actionWebhook(): array
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $rawBody = Yii::$app->request->rawBody;

        $decoder = new NetsuiteDecoder();
        $data    = $decoder->decode($rawBody);

        if ($data === null) {
            Yii::$app->response->statusCode = 400;
            return ['status' => 'error', 'message' => 'Failed to decode payload'];
        }
        $cart = \backend\models\Cartsbe::find()->where(['id' => $data['externalId']])->one();
        if (!$cart) {
            Yii::$app->response->statusCode = 404;
            return ['status' => 'error', 'message' => 'Cart not found for externalId: ' . $data['externalId']];
        }
        $cart->status = match($data['newStatus']) {
            'Closed' => 'Closed',
            'Cancelled' => 'Cancelled',
            default => $cart->status,
        };
        
        // Ensure cart JSON fields are deserialized
        if ($cart && method_exists($cart, 'loadJson') && !is_object($cart->data)) {
            try {
                $cart->loadJson();
            } catch (\Throwable $_) {
                // ignore
            }
        }
        if (is_object($cart->data)) {
            if (empty($cart->data->netsuite->deliveryid)) {
                $cart->data->netsuite->deliveryid = $data['salesOrderId'];
                $cart->data->netsuite->orderno = $data['orderNo'];
            }
        }
        $cart->save();
        if ($cart->status !== $data['newStatus']) {
            Yii::$app->trigger('cart-status-change-'.$cart->account_code, new \common\events\UserDataEvent(['model' => $cart, 'customData' => ['status' => $data['newStatus']]]));
        }
        return ['status' => 'ok'];
    }
    /**
     * Receive a Sales Order change payload from NetSuite PP_Order_Change.
     *
     * Decodes the payload via NetsuiteDecoder (handles json, json+gzip,
     * json+aes-cbc and json+gzip+aes-cbc formats) then logs the decoded
     * data for inspection.
     *
     * @return array JSON response.
     */
    public function actionPickorder(): array
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $rawBody = Yii::$app->request->rawBody;

        // quick check: is the raw body valid JSON? log and reject early if not.
        $rawIsJson = false;
        if (is_string($rawBody) && $rawBody !== '') {
            json_decode($rawBody);
            $rawIsJson = (json_last_error() === JSON_ERROR_NONE);
            $data = $rawBody;
        }
        if (is_array($rawBody)) {
            $data = $rawBody;
        }
        if (!$rawIsJson) {
            $decoder = new NetsuiteDecoder();
            $data    = $decoder->decode($rawBody);
        } else {
            $data = json_decode($rawBody, true);
        }


        if ($data === null) {
            Yii::$app->response->statusCode = 400;
            return ['status' => 'error', 'message' => 'Failed to decode payload'];
        }
        try{
            $results = \PortalPeople\netsuite\models\Carts::printLabels($data);
        } catch (\Exception $e) {
            Yii::$app->response->statusCode = 500;
            return [
                'status' => 'error',
                'message' => 'Error processing pick order: ' . $e->getMessage(),
            ];
        }
       
        if ($results === null) {
            Yii::$app->response->statusCode = 500;
            return [
                'status' => 'error',
                'message' => 'No tracking numbers found to print labels for Order. ',
                //'trackinginfo' => $trackingInfo,
            ];
        }
       // Yii::warning($results, 'netsuite.pickorder.labels');
        $base64 = (string) ($results['data'] ?? '');
        if ($base64 === '') {
            throw new \RuntimeException('Provider returned an empty PDF payload.');
        }

        if (strpos($base64, 'base64,') !== false) {
            $parts = explode('base64,', $base64, 2);
            $base64 = $parts[1] ?? $base64;
        }
        
        $pdfBinary = $base64;
        if ($pdfBinary === false) {
            throw new \RuntimeException('label data is not valid Base64 PDF data.');
        }
        Yii::$app->response->statusCode = 200;
        return [
            'status' => 'ok',
            'message' => 'Pick order processed',
            'trackinginfo' => $results[0]['trackingNumbers'] ?? 'No tracking info',
            'body' => $pdfBinary,
        ];
    }
}
