<?php

namespace PortalPeople\zupa\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
use yii\helpers\FileHelper;
use PortalPeople\zupa\Module;
use PortalPeople\zupa\services\FtpDownloadService;
use PortalPeople\zupa\services\ProcessFilesService;

class ImportController extends Controller
{
    public $layout = '@backend/views/layouts/main';

    public function behaviors(): array
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    ['allow' => true, 'roles' => ['@']],
                ],
            ],
        ];
    }

    public function actionIndex(): string|\yii\web\Response
    {
        /** @var Module|null $module */
        $module = Yii::$app->getModule('zupa');

        $zupaBase     = Yii::getAlias('@app') . '/../console/runtime/zupa';
        $inboxDir     = $zupaBase . '/inbox';
        $processedDir = $zupaBase . '/processed';
        $failedDir    = $zupaBase . '/failed';

        foreach ([$inboxDir, $processedDir, $failedDir] as $dir) {
            if (!is_dir($dir)) {
                FileHelper::createDirectory($dir, 0755);
            }
        }

        $result = null;

        if (Yii::$app->request->isPost) {
            $selected = (array) Yii::$app->request->post('files', []);

            if (empty($selected)) {
                Yii::$app->session->addFlash('warning', 'No files selected.');
                return $this->redirect(['index']);
            }

            $stagingDir = rtrim($inboxDir, '/') . '/../staging_' . uniqid('', true);
            FileHelper::createDirectory($stagingDir, 0755);

            foreach ($selected as $filename) {
                $filename = basename((string) $filename);
                if (pathinfo($filename, PATHINFO_EXTENSION) !== 'xml') {
                    continue;
                }
                $src = $inboxDir . '/' . $filename;
                if (is_file($src)) {
                    rename($src, $stagingDir . '/' . $filename);
                }
            }

            $service = new ProcessFilesService([
                'inboxPath'     => realpath($stagingDir),
                'processedPath' => $processedDir,
                'failedPath'    => $failedDir,
                'module'        => $module,
            ]);

            $result = $service->process();

            @rmdir($stagingDir);
        }

        $files = [];
        foreach (glob($inboxDir . '/*.xml') ?: [] as $path) {
            $files[] = [
                'name'     => basename($path),
                'size'     => filesize($path),
                'modified' => filemtime($path),
            ];
        }
        usort($files, fn ($a, $b) => $b['modified'] - $a['modified']);

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

    public function actionDownload(): \yii\web\Response
    {
        /** @var Module|null $module */
        $module = Yii::$app->getModule('zupa');

        if (!$module || !$module->isConfigured()) {
            Yii::$app->session->addFlash('danger', 'Zupa module is not configured.');
            return $this->redirect(['index']);
        }

        $zupaBase = Yii::getAlias('@app') . '/../console/runtime/zupa';
        $inboxDir = $zupaBase . '/inbox';
        FileHelper::createDirectory($inboxDir, 0755);

        $service = new FtpDownloadService([
            'protocol'            => $module->protocol,
            'host'                => $module->host,
            'port'                => $module->port,
            'username'            => $module->username,
            'password'            => $module->password,
            'remotePath'          => $module->remotePath,
            'passiveMode'         => $module->passiveMode,
            'moveAfterDownload'   => $module->moveAfterDownload,
            'moveToPath'          => $module->moveToPath,
            'deleteAfterDownload' => $module->deleteAfterDownload,
            'inboxPath'           => $inboxDir,
            'limit'               => 10,
        ]);

        $result = $service->download();

        $n = count($result['downloaded']);
        if ($n > 0) {
            Yii::$app->session->addFlash('success', "{$n} file(s) downloaded to inbox.");
        } else {
            Yii::$app->session->addFlash('info', 'No new files to download.');
        }

        foreach ($result['errors'] ?? [] as $err) {
            Yii::$app->session->addFlash('warning', $err);
        }

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

    public function actionPreview(): \yii\web\Response
    {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        $filename = basename((string) Yii::$app->request->get('file', ''));
        if (!$filename || pathinfo($filename, PATHINFO_EXTENSION) !== 'xml') {
            return $this->asJson(['error' => 'Invalid filename.']);
        }

        $zupaBase = Yii::getAlias('@app') . '/../console/runtime/zupa';
        $filepath = $zupaBase . '/inbox/' . $filename;

        if (!is_file($filepath)) {
            return $this->asJson(['error' => 'File not found.']);
        }

        $content = file_get_contents($filepath);
        if ($content === false) {
            return $this->asJson(['error' => 'Cannot read file.']);
        }

        try {
            $service = new ProcessFilesService([
                'module' => Yii::$app->getModule('zupa'),
            ]);
            $orders = $service->parseXml($content);
            return $this->asJson(['orders' => $orders]);
        } catch (\Throwable $e) {
            return $this->asJson(['error' => $e->getMessage()]);
        }
    }
}
