<?php
/**
 * Caterpoint Order REST API Controller
 *
 * @category    PortalPeople
 * @package     Caterpoint
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2026 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\caterpoint\controllers\api;

use OpenApi\Annotations as OA;
use Yii;
use yii\rest\Controller;
use yii\web\BadRequestHttpException;
use yii\web\ServerErrorHttpException;
use yii\helpers\Json;
use PortalPeople\caterpoint\Module;

/**
 * Order REST API Controller
 * 
 * Provides raw JSON/XML REST endpoints for Caterpoint order operations
 * 
 * Routes (for /api/caterpoint/*):
 *   GET    /api/caterpoint/order/index           List orders (local database)
 *   GET    /api/caterpoint/order/view?id=<id>    Get specific order
 *   POST   /api/caterpoint/order/import          Trigger manual import
 *   GET    /api/caterpoint/order/status          Get import status
 *   POST   /api/caterpoint/order/reset           Reset cursor
 *   POST   /api/caterpoint/order/mark-exported   Mark order as exported
 *   GET    /api/caterpoint/order/fetch-raw       Get raw data from Caterpoint API
 *
 * @OA\Tag(
 *   name="Caterpoint Orders",
 *   description="Caterpoint order import and status endpoints"
 * )
 */
class OrderController extends Controller
{
    /**
     * @var Module Module instance
     */
    private ?Module $caterpointModule = null;

    /**
     * Configure controller behaviors
     * 
     * @return array
     */
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        
        // Ensure JSON response format
        $behaviors['contentNegotiator']['formats'] = [
            'application/json' => \yii\web\Response::FORMAT_JSON,
        ];
        
        return $behaviors;
    }

    /**
     * Initialize the controller
     * 
     * @throws \Exception
     */
    public function init()
    {
        parent::init();

        try {
            $this->caterpointModule = Yii::$app->getModule('caterpoint');
        } catch (\Exception $e) {
            throw new ServerErrorHttpException('Caterpoint module not configured: ' . $e->getMessage());
        }

        if ($this->caterpointModule === null) {
            throw new ServerErrorHttpException('Caterpoint module not found');
        }
    }

    /**
     * Get list of orders
     * 
     * Optional query parameters:
     *   - page: Page number (default 1)
     *   - per-page: Orders per page (default 20)
     *   - sort: Sort field
    *
    * @OA\Get(
    *   path="/api/caterpoint/order/index",
    *   tags={"Caterpoint Orders"},
    *   summary="List orders",
    *   @OA\Response(response=200, description="Order list")
    * )
     * 
     * @return array
     */
    public function actionIndex(): array
    {
        // TODO: Implement based on your Order model
        return [
            'message' => 'Order list endpoint - implement based on your system',
            'orders' => [],
            'total' => 0,
        ];
    }

    /**
     * Get a specific order
        *
        * @OA\Get(
        *   path="/api/caterpoint/order/view",
        *   tags={"Caterpoint Orders"},
        *   summary="Get order by ID",
        *   @OA\Parameter(name="id", in="query", required=true, @OA\Schema(type="string")),
        *   @OA\Response(response=200, description="Order details")
        * )
     * 
     * @param mixed $id Order ID
     * @return array
     */
    public function actionView($id): array
    {
        // TODO: Implement based on your Order model
        return [
            'message' => 'Order view endpoint - implement based on your system',
            'id' => $id,
            'order' => null,
        ];
    }

    /**
     * Trigger a manual import of orders from Caterpoint
     * 
     * POST body parameters:
     *   - cursor: Optional cursor to start from
     *   - limit: Optional limit (max orders to import)
     *   - dryRun: If true, preview only without persisting
     *   - reset: If true, reset cursor and start from beginning
    *
    * @OA\Post(
    *   path="/api/caterpoint/order/import",
    *   tags={"Caterpoint Orders"},
    *   summary="Trigger manual order import",
    *   @OA\Response(response=200, description="Import result")
    * )
     * 
     * @return array
     * @throws BadRequestHttpException
     * @throws ServerErrorHttpException
     */
    public function actionImport(): array
    {
        $request = Yii::$app->request;
        
        if (!$request->isPost) {
            throw new BadRequestHttpException('POST request required');
        }

        // Check module configuration
        if (!$this->caterpointModule->isConfigured()) {
            throw new ServerErrorHttpException('Caterpoint module is not configured');
        }

        // Get request parameters
        $cursor = $request->post('cursor');
        $limit = (int) $request->post('limit', 0);
        $dryRun = (bool) $request->post('dryRun', false);
        $reset = (bool) $request->post('reset', false);

        try {
            $service = $this->caterpointModule->createOrderImportService();

            // Reset cursor if requested
            if ($reset) {
                $service->cursorStore->clear();
            }

            // Run import
            $result = $service->run($cursor, $limit, $dryRun);

            return [
                'success' => true,
                'message' => 'Import completed',
                'result' => $result,
            ];
        } catch (\Throwable $e) {
            Yii::error('Order import failed: ' . $e->getMessage(), 'caterpoint.import');
            throw new ServerErrorHttpException('Import failed: ' . $e->getMessage());
        }
    }

    /**
     * Get import status and next cursor
        *
        * @OA\Get(
        *   path="/api/caterpoint/order/status",
        *   tags={"Caterpoint Orders"},
        *   summary="Get import status",
        *   @OA\Response(response=200, description="Import status")
        * )
     * 
     * @return array
     * @throws ServerErrorHttpException
     */
    public function actionStatus(): array
    {
        try {
            $service = $this->caterpointModule->createOrderImportService();
            $cursor = $service->cursorStore->get();

            return [
                'success' => true,
                'currentCursor' => $cursor,
                'configured' => $this->caterpointModule->isConfigured(),
            ];
        } catch (\Throwable $e) {
            throw new ServerErrorHttpException('Failed to get status: ' . $e->getMessage());
        }
    }

    /**
     * Reset the import cursor
        *
        * @OA\Post(
        *   path="/api/caterpoint/order/reset",
        *   tags={"Caterpoint Orders"},
        *   summary="Reset import cursor",
        *   @OA\Response(response=200, description="Cursor reset")
        * )
     * 
     * @return array
     * @throws ServerErrorHttpException
     */
    public function actionReset(): array
    {
        try {
            $service = $this->caterpointModule->createOrderImportService();
            $service->cursorStore->clear();

            return [
                'success' => true,
                'message' => 'Import cursor reset successfully',
            ];
        } catch (\Throwable $e) {
            throw new ServerErrorHttpException('Failed to reset cursor: ' . $e->getMessage());
        }
    }

    /**
     * Mark a specific order as exported
        *
        * @OA\Post(
        *   path="/api/caterpoint/order/mark-exported",
        *   tags={"Caterpoint Orders"},
        *   summary="Mark order as exported",
        *   @OA\Parameter(name="id", in="query", required=true, @OA\Schema(type="string")),
        *   @OA\Response(response=200, description="Order marked exported")
        * )
     * 
     * @param string $id Caterpoint order ID
     * @return array
     * @throws BadRequestHttpException
     * @throws ServerErrorHttpException
     */
    public function actionMarkExported($id): array
    {
        if (empty($id)) {
            throw new BadRequestHttpException('Order ID is required');
        }

        try {
            $client = $this->caterpointModule->createClient();
            $result = $client->markOrderExported($id);

            return [
                'success' => true,
                'message' => "Order {$id} marked as exported",
                'result' => $result,
            ];
        } catch (\Throwable $e) {
            throw new ServerErrorHttpException('Failed to mark order as exported: ' . $e->getMessage());
        }
    }

    /**
     * Get raw order data from Caterpoint API
     * 
     * Query parameters:
     *   - cursor: Optional cursor for pagination
     *   - limit: Limit per request (default 100)
    *
    * @OA\Get(
    *   path="/api/caterpoint/order/fetch-raw",
    *   tags={"Caterpoint Orders"},
    *   summary="Fetch raw order data from Caterpoint",
    *   @OA\Response(response=200, description="Raw data payload")
    * )
     * 
     * @return array
     * @throws ServerErrorHttpException
     */
    public function actionFetchRaw(): array
    {
        $request = Yii::$app->request;
        $cursor = $request->get('cursor');
        $limit = (int) $request->get('limit', 100);
        $client = null;

        try {
            $client = $this->caterpointModule->createClient();
            $result = $client->getOrdersUpdatedSince($cursor, $limit);

            return [
                'success' => true,
                'message' => 'Raw orders fetched from Caterpoint API',
                'sourceFormat' => $client->getLastResponseFormat(),
                'data' => $result,
            ];
        } catch (\Throwable $e) {
            Yii::$app->response->statusCode = 502;

            return [
                'success' => false,
                'message' => 'Failed to fetch orders: ' . $e->getMessage(),
                'sourceFormat' => $client !== null ? $client->getLastResponseFormat() : null,
                'data' => null,
            ];
        }
    }
}
