<?php

namespace PortalPeople\magento\controllers;

use yii\data\ArrayDataProvider;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\web\Response;
use Yii;
use PortalPeople\magento\services\OrderImportService;
use PortalPeople\magento\services\OrderSnapshotService;
use PortalPeople\magento\models\Cart;

class DefaultController extends Controller
{
    public function behaviors(): array
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    ['allow' => true, 'roles' => ['@']],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'download-order' => ['GET'],
                    'download-orders' => ['POST'],
                    'import-order' => ['POST'],
                    'import-orders' => ['POST'],
                    'download-payments' => ['POST'],
                    'import-payments' => ['POST'],
                ],
            ],
        ];
    }

    public function actionIndex()
    {
        return $this->renderContent('Magento module is ready.');
    }

    public function actionOrders()
    {
        $orderImportService = new OrderImportService();
        $module = $orderImportService->getConfiguredModule();
        if ($module === null) {
            Yii::$app->session->setFlash('error', 'Magento integration is not configured.');

            return $this->render('/orders/index', [
                'dataProvider' => new ArrayDataProvider([
                    'allModels' => [],
                    'pagination' => false,
                ]),
                'totalCount' => 0,
                'paymentCount' => 0,
                'isCached' => false,
            ]);
        }

        $orders = $this->loadOrdersSnapshot($module, Yii::$app->request->get('refresh', '0') === '1');
        $payments = $this->loadPaymentSnapshots($module, $orders);
        $importedOrderNumbers = Cart::findImportedMagentoOrderNumbers('GAR001');

        $items = $orders['items'] ?? [];

        $dataProvider = new ArrayDataProvider([
            'allModels' => is_array($items) ? $items : [],
            'pagination' => [
                'pageSize' => 25,
            ],
        ]);

        return $this->render('/orders/index', [
            'dataProvider' => $dataProvider,
            'totalCount' => (int) ($orders['total_count'] ?? count($items)),
            'paymentCount' => count($payments),
            'isCached' => Yii::$app->has('cache', true),
            'importedOrderNumbers' => $importedOrderNumbers,
        ]);
    }
    public function actionNewOrders()
    {
        $orderImportService = new OrderImportService();
        $module = $orderImportService->getConfiguredModule();
        if ($module === null) {
            Yii::$app->session->setFlash('error', 'Magento integration is not configured.');

            return $this->render('/orders/index', [
                'dataProvider' => new ArrayDataProvider([
                    'allModels' => [],
                    'pagination' => false,
                ]),
                'totalCount' => 0,
                'paymentCount' => 0,
                'isCached' => false,
            ]);
        }

        $orders = $this->loadNewOrdersSnapshot($module, Yii::$app->request->get('refresh', '0') === '1');
        $payments = $this->loadPaymentSnapshots($module, $orders);
        $importedOrderNumbers = Cart::findImportedMagentoOrderNumbers('GAR001');

        $items = $orders['items'] ?? [];

        $dataProvider = new ArrayDataProvider([
            'allModels' => is_array($items) ? $items : [],
            'pagination' => [
                'pageSize' => 25,
            ],
        ]);

        return $this->render('/orders/index', [
            'dataProvider' => $dataProvider,
            'totalCount' => (int) ($orders['total_count'] ?? count($items)),
            'paymentCount' => count($payments),
            'isCached' => Yii::$app->has('cache', true),
            'importedOrderNumbers' => $importedOrderNumbers,
        ]);
    }

    public function actionDownloadOrder(int $id)
    {
        $module = (new OrderImportService())->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(['orders']);
        }

        try {
            $order = (new OrderImportService())->getOrder($module, $id);
            yii::warning($order, 'magento.order RAW');
        } catch (\Throwable $e) {
            Yii::warning('Magento order lookup failed for ' . $id . ': ' . $e->getMessage(), 'magento');
            $order = [];
        }

        if ($order === []) {
            throw new NotFoundHttpException('Magento order not found.');
        }

        $incrementId = (string) ($order['increment_id'] ?? $id);
        $payload = json_encode($order, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

        if ($payload === false) {
            throw new BadRequestHttpException('Failed to encode Magento order payload.');
        }

        return Yii::$app->response->sendContentAsFile(
            $payload,
            'magento-order-' . $incrementId . '.json',
            ['mimeType' => 'application/json']
        );
    }

    public function actionImportOrder(int $id)
    {
        $orderImportService = new OrderImportService();
        $module = $orderImportService->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(Yii::$app->request->referrer ?? ['orders']);
        }

        try {
            $order = $orderImportService->getOrder($module, $id);
        } catch (\Throwable $e) {
            Yii::warning('Magento order lookup failed for ' . $id . ': ' . $e->getMessage(), 'magento');
            $order = [];
        }

        if ($order === []) {
            throw new NotFoundHttpException('Magento order not found.');
        }

        try {
            $importResult = $orderImportService->importOrder($order);
            $message = 'Imported Magento order ' . (string) ($order['increment_id'] ?? $id) . '.';

            if (Yii::$app->request->isAjax) {
                Yii::$app->response->format = Response::FORMAT_JSON;

                return [
                    'success' => true,
                    'message' => $message,
                    'result' => $importResult['result'],
                ];
            }

            Yii::$app->session->setFlash('success', $message);
        } catch (\Throwable $e) {
            $message = 'Failed to import Magento order ' . (string) ($order['increment_id'] ?? $id) . ': ' . $e->getMessage();
            $debug = $orderImportService->buildImportDebug($order, $e);

            Yii::error([
                'message' => $message,
                'debug' => $debug,
            ], 'magento.import');

            if (Yii::$app->request->isAjax) {
                Yii::$app->response->format = Response::FORMAT_JSON;

                return [
                    'success' => false,
                    'message' => $message,
                    'debug' => $debug,
                ];
            }

            Yii::$app->session->setFlash('error', $message);
        }

        return $this->redirect(['orders']);
    }

    public function actionDownloadOrders()
    {
        $module = (new OrderImportService())->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(['orders']);
        }

        $orders = $this->loadOrdersSnapshot($module, true);
        Yii::$app->session->setFlash('success', 'Downloaded ' . count($orders['items'] ?? []) . ' Magento order(s).');

        return $this->redirect(['orders']);
    }

    public function actionImportOrders()
    {
        $orderImportService = new OrderImportService();
        $module = $orderImportService->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(['orders']);
        }

        $orders = $this->loadOrdersSnapshot($module, false);
        $importSummary = $orderImportService->importOrders($orders['items'] ?? []);
        $imported = $importSummary['imported'];
        $failed = $importSummary['failed'];
        $errors = $importSummary['errors'];

        $message = 'Imported ' . $imported . ' Magento order(s); failed ' . $failed . '.';

        if (Yii::$app->request->isAjax) {
            Yii::$app->response->format = Response::FORMAT_JSON;

            return [
                'success' => $failed === 0,
                'message' => $message,
                'imported' => $imported,
                'failed' => $failed,
                'errors' => $errors ?? [],
            ];
        }

        Yii::$app->session->setFlash($failed === 0 ? 'success' : 'error', $message);

        return $this->redirect(Yii::$app->request->referrer ?? ['orders']);
    }

    public function actionDownloadPayments()
    {
        $module = (new OrderImportService())->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(Yii::$app->request->referrer ?? ['orders']);
        }

        $orders = $this->loadOrdersSnapshot($module, false);
        $payments = $this->loadPaymentSnapshots($module, $orders);

        Yii::$app->session->setFlash('success', 'Downloaded ' . count($payments) . ' Magento payment snapshot(s).');

        return $this->redirect(['orders']);
    }

    public function actionImportPayments()
    {
        $orderImportService = new OrderImportService();
        $module = $orderImportService->getConfiguredModule();
        if ($module === null) {
            return $this->redirect(['orders']);
        }

        $payments = $this->loadPaymentSnapshots($module);
        $paymentSummary = $orderImportService->importPayments($payments);
        $updated = $paymentSummary['updated'];
        $skipped = $paymentSummary['skipped'];

        Yii::$app->session->setFlash(
            'success',
            'Imported ' . $updated . ' Magento payment snapshot(s); skipped ' . $skipped . '.'
        );

        return $this->redirect(['orders']);
    }

    private function loadOrdersSnapshot(\PortalPeople\magento\Module $module, bool $refresh = false): array
    {
        return (new OrderSnapshotService())->loadOrdersSnapshot($module, $refresh);
    }
    private function loadNewOrdersSnapshot(\PortalPeople\magento\Module $module, bool $refresh = false): array
    {
        return (new OrderSnapshotService())->loadNewOrdersSnapshot($module, $refresh);
    }

    private function loadPaymentSnapshots(\PortalPeople\magento\Module $module, ?array $orders = null): array
    {
        return (new OrderSnapshotService())->loadPaymentSnapshots($module, $orders);
    }

}
