<?php

/**
 * Configuration Controller – VirtualStock Module
 *
 * @category    PortalPeople
 * @package     VirtualStock
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2026 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\virtualstock\controllers;

use Yii;
use yii\web\Controller;
use yii\web\Response;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use PortalPeople\virtualstock\models\ConfigForm;

/**
 * ConfigController
 *
 * Provides a web UI for managing VirtualStock module settings, testing the
 * API connection, and triggering an on-demand order import.
 */
class ConfigController extends Controller
{
    /** @inheritdoc */
    public function behaviors(): array
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                ],
            ],
            'verbs' => [
                'class'   => VerbFilter::class,
                'actions' => [
                    'save'             => ['POST'],
                    'test-connection'  => ['POST'],
                    'import'           => ['POST'],
                    'api-get-orders'       => ['POST'],
                    'api-get-order'        => ['POST'],
                    'api-get-item'         => ['POST'],
                    'api-list-customers'   => ['POST'],
                    'approve-order-import' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Display and process the configuration form.
     *
     * @return string|\yii\web\Response
     */
    public function actionIndex()
    {
        $model = new ConfigForm();
        $model->loadFromParams();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->saveToParams()) {
                Yii::$app->session->setFlash('success', 'VirtualStock configuration saved successfully.');
                return $this->refresh();
            }
            Yii::$app->session->setFlash('error', 'Failed to save configuration. Check file permissions.');
        }

        return $this->render('index', ['model' => $model]);
    }

    /**
     * AJAX: test API connection with the submitted form values.
     *
     * @return array
     */
    public function actionTestConnection(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        $model = new ConfigForm();

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            $result = $model->testConnection();
            return [
                'success' => $result['success'],
                'message' => $result['message'],
            ];
        }

        return [
            'success' => false,
            'message' => 'Invalid configuration data.',
            'errors'  => $model->errors,
        ];
    }

    /**
     * AJAX: return current module status including cursor position.
     *
     * @return array
     */
    public function actionStatus(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        /** @var \PortalPeople\virtualstock\Module $module */
        $module = Yii::$app->getModule('virtualstock');

        if (!$module) {
            return ['success' => false, 'configured' => false, 'cursor' => null];
        }

        $cursor = null;
        try {
            $cursorStore = $module->createCursorStore();
            $cursor      = $cursorStore->get();
        } catch (\Throwable $e) {
            Yii::warning('VirtualStock status: could not read cursor — ' . $e->getMessage(), 'virtualstock');
        }

        return [
            'success'    => true,
            'configured' => $module->isConfigured(),
            'cursor'     => $cursor,
            'pollLimit'  => $module->pollLimit,
        ];
    }

    /**
     * AJAX POST: trigger an on-demand order import (dry-run optional).
     *
     * Accepts: { dryRun: 1|0, limit: <int> }
     *
     * @return array
     */
    public function actionImport(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        /** @var \PortalPeople\virtualstock\Module $module */
        $module = Yii::$app->getModule('virtualstock');

        if (!$module || !$module->isConfigured()) {
            return [
                'success' => false,
                'message' => 'VirtualStock is not configured. Save valid settings first.',
            ];
        }

        $request = Yii::$app->request;
        $dryRun  = (bool) $request->post('dryRun', 0);
        $limit   = (int)  $request->post('limit', $module->pollLimit);

        try {
            $service = $module->createOrderImportService();
            $stats   = $service->run(null, $limit, $dryRun);

            return [
                'success' => true,
                'dryRun'  => $dryRun,
                'stats'   => $stats,
                'message' => $dryRun
                    ? "Dry run complete. {$stats['fetched']} orders fetched, {$stats['created']} would be created, {$stats['updated']} would be updated."
                    : "{$stats['created']} order(s) created, {$stats['updated']} updated, {$stats['failed']} failed.",
            ];
        } catch (\Throwable $e) {
            Yii::error('VirtualStock import error: ' . $e->getMessage(), 'virtualstock');
            return [
                'success' => false,
                'message' => 'Import failed: ' . $e->getMessage(),
            ];
        }
    }

    /**
     * Render the API Explorer control panel.
     */
    public function actionApiExplorer(): string
    {
        return $this->render('api-explorer');
    }

    /**
     * AJAX POST: fetch orders from the live API.
     */
    public function actionApiGetOrders(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $module = $this->getConfiguredModule();
        if ($module === null) {
            return ['success' => false, 'message' => 'VirtualStock is not configured.'];
        }
        try {
            $client = $module->createClient();
            $cursor = Yii::$app->request->post('cursor') ?: null;
            $limit  = (int) Yii::$app->request->post('limit', 10);
            $result = $client->getOrdersUpdatedSince($cursor, $limit);
            return ['success' => true, 'data' => $result];
        } catch (\Throwable $e) {
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * AJAX POST: fetch a single order from the live API.
     */
    public function actionApiGetOrder(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $module = $this->getConfiguredModule();
        if ($module === null) {
            return ['success' => false, 'message' => 'VirtualStock is not configured.'];
        }
        try {
            $orderNo = trim((string) Yii::$app->request->post('orderNo', ''));
            if ($orderNo === '') {
                return ['success' => false, 'message' => 'Order number is required.'];
            }
            $result = $module->createClient()->getOrder($orderNo);
            return ['success' => true, 'data' => $result];
        } catch (\Throwable $e) {
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * AJAX POST: fetch a single item by numeric ID from the live API.
     */
    public function actionApiGetItem(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $module = $this->getConfiguredModule();
        if ($module === null) {
            return ['success' => false, 'message' => 'VirtualStock is not configured.'];
        }
        try {
            $itemId = trim((string) Yii::$app->request->post('itemId', ''));
            if ($itemId === '') {
                return ['success' => false, 'message' => 'Item ID is required.'];
            }
            $result = $module->createClient()->getItem($itemId);
            return ['success' => true, 'data' => $result];
        } catch (\Throwable $e) {
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * AJAX POST: list customers/retailers from the live API.
     */
    public function actionApiListCustomers(): array
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $module = $this->getConfiguredModule();
        if ($module === null) {
            return ['success' => false, 'message' => 'VirtualStock is not configured.'];
        }
        try {
            $rawFilters = trim((string) Yii::$app->request->post('filters', '{}'));
            $filters = [];
            if ($rawFilters !== '' && $rawFilters !== '{}') {
                $decoded = \yii\helpers\Json::decode($rawFilters, true);
                if (is_array($decoded)) {
                    $filters = $decoded;
                }
            }
            $result = $module->createClient()->listCustomers($filters);
            return ['success' => true, 'data' => $result];
        } catch (\Throwable $e) {
            return ['success' => false, 'message' => $e->getMessage()];
        }
    }

    /**
     * GET: Fetch pending orders from the VirtualStock API and show a preview.
     * Stores the cursor used in session so the approve step re-imports the same batch.
     *
     * @return string|\yii\web\Response
     */
    public function actionOrderImportAll()
    {
        $module = $this->getConfiguredModule();
        if ($module === null) {
            Yii::$app->session->setFlash('error', 'VirtualStock is not configured. Save valid API settings first.');
            return $this->redirect(['/virtualstock/config/index']);
        }

        $limit = (int) Yii::$app->request->get('limit', $module->pollLimit);

        $allOrders = null;
        $error = null;
        try {
            $client = $module->createClient();
            $fetched = $client->getOrdersUpdatedSince(null, $limit);
            $allOrders = $fetched['orders'] ?? [];
            // pass through cursor info if present
            $cursor = $fetched['cursor'] ?? null;
            $nextCursor = $fetched['nextCursor'] ?? null;
        } catch (\Throwable $e) {
            Yii::error('VirtualStock fetch all orders error: ' . $e->getMessage(), 'virtualstock');
            $error = 'Could not fetch orders: ' . $e->getMessage();
        }

        return $this->render('@vendor/portalpeople/ngauge-virtualstock/src/views/config/order-import-all.php', [
            'allOrders' => $allOrders,
            'error' => $error,
            'limit' => $limit,
            'pollLimit' => $module->pollLimit,
            'cursor' => $cursor ?? null,
            'nextCursor' => $nextCursor ?? null,
        ]);
    }
    

    /**
     * Return the configured VirtualStock module, or null if unavailable.
     *
     * @return \PortalPeople\virtualstock\Module|null
     */
    private function getConfiguredModule(): ?\PortalPeople\virtualstock\Module
    {
        /** @var \PortalPeople\virtualstock\Module|null $module */
        $module = Yii::$app->getModule('virtualstock');
        if (!$module || !$module->isConfigured()) {
            return null;
        }
        return $module;
    }
}
