<?php

namespace PortalPeople\indicator\models;

use Yii;
use yii\base\Model;

class ConfigForm extends Model
{
    public string $cartClass = 'PortalPeople\\indicator\\models\\Cart';
    public string $protocol = 'sftp';
    public string $ftpHost = '';
    public int $ftpPort = 22;
    public string $ftpUser = '';
    public string $ftpPassword = '';
    public string $ftpPath = '/';
    public bool $deleteAfterDownload = false;
    public bool $moveAfterDownload = false;
    public string $moveToPath = '';
    public int $downloadInterval = 3600;
    public int $processInterval = 7200;
    public string $summaryEmail = '';
    public bool $passiveMode = true;

    /**
     * Returns the available Cart class options for the dropdown.
     *
     * @return array<string, string>
     */
    public static function cartClassOptions(): array
    {
        $options = [
            'PortalPeople\\indicator\\models\\Cart' => 'Indicator Built-in Cart (default)',
            'backend\\models\\Cart' => 'NGauge Base Cart',
            'backend\\models\\Cartsbe' => 'NGauge Backend Cart (Cartsbe)',
        ];

        if (class_exists('PortalPeople\\cart\\models\\Cart')) {
            $options['PortalPeople\\cart\\models\\Cart'] = 'NGauge Cart Module (ngauge-cart)';
        }

        return $options;
    }

    public function rules()
    {
        return [
            [['cartClass', 'protocol', 'ftpHost', 'ftpUser', 'ftpPassword', 'ftpPath'], 'required'],
            [['cartClass'], 'in', 'range' => array_keys(self::cartClassOptions())],
            [['ftpPort', 'downloadInterval', 'processInterval'], 'integer', 'min' => 1],
            [['protocol'], 'in', 'range' => ['ftp', 'ftps', 'sftp']],
            [['ftpHost', 'ftpUser', 'ftpPath'], 'string', 'max' => 255],
            [['ftpPassword'], 'string'],
            [['summaryEmail'], 'email', 'when' => fn () => !empty($this->summaryEmail)],
            [['summaryEmail'], 'string', 'max' => 255],
            [['deleteAfterDownload', 'moveAfterDownload', 'passiveMode'], 'boolean'],
            [['moveToPath'], 'string', 'max' => 255],
        ];
    }

    public function attributeLabels()
    {
        return [
            'cartClass' => 'Cart Class',
            'protocol' => 'Protocol',
            'ftpHost' => 'Hostname',
            'ftpPort' => 'Port',
            'ftpUser' => 'Username',
            'ftpPassword' => 'Password',
            'ftpPath' => 'Remote Path',
            'deleteAfterDownload' => 'Delete files after download',
            'moveAfterDownload' => 'Move files after download',
            'moveToPath' => 'Move to remote path',
            'downloadInterval' => 'Download interval (seconds)',
            'processInterval' => 'Process interval (seconds)',
            'summaryEmail' => 'Summary email address',
            'passiveMode' => 'Use passive mode (FTP)',
        ];
    }

    public function loadFromParams(): self
    {
        $indicator = Yii::$app->params['plugins']['indicator'] ?? [];

        $this->cartClass = $indicator['cartClass'] ?? 'PortalPeople\\indicator\\models\\Cart';
        $this->protocol = $indicator['protocol'] ?? 'sftp';
        $this->ftpHost = $indicator['host'] ?? '';
        $this->ftpPort = (int) ($indicator['port'] ?? 22);
        $this->ftpUser = $indicator['username'] ?? '';
        $this->ftpPassword = $this->decryptPassword($indicator['password'] ?? '');
        $this->ftpPath = $indicator['remotePath'] ?? '/';
        $this->deleteAfterDownload = (bool) ($indicator['deleteAfterDownload'] ?? false);
        $this->moveAfterDownload = (bool) ($indicator['moveAfterDownload'] ?? false);
        $this->moveToPath = $indicator['moveToPath'] ?? '';
        $this->downloadInterval = (int) ($indicator['pickupIntervalSeconds'] ?? 3600);
        $this->processInterval = (int) ($indicator['processIntervalSeconds'] ?? 7200);
        $this->summaryEmail = $indicator['summaryEmail'] ?? '';
        $this->passiveMode = (bool) ($indicator['passiveMode'] ?? true);

        return $this;
    }

    public function saveToParams(): bool
    {
        if (!$this->validate()) {
            return false;
        }

        $indicator = [
            'enabled' => true,
            'cartClass' => $this->cartClass,
            'protocol' => $this->protocol,
            'host' => $this->ftpHost,
            'port' => $this->ftpPort,
            'username' => $this->ftpUser,
            'password' => $this->encryptPassword($this->ftpPassword),
            'remotePath' => $this->ftpPath,
            'deleteAfterDownload' => $this->deleteAfterDownload,
            'moveAfterDownload' => $this->moveAfterDownload,
            'moveToPath' => $this->moveToPath,
            'pickupIntervalSeconds' => $this->downloadInterval,
            'processIntervalSeconds' => $this->processInterval,
            'summaryEmail' => $this->summaryEmail,
            'passiveMode' => $this->passiveMode,
        ];

        if (!isset(Yii::$app->params['plugins'])) {
            Yii::$app->params['plugins'] = [];
        }

        Yii::$app->params['plugins']['indicator'] = $indicator;

        // Persist to the backend params-local.php so config survives across requests
        $paramsFile = Yii::getAlias('@backend') . '/config/params-local.php';
        $currentParams = is_file($paramsFile) ? (require $paramsFile) : [];
        if (!is_array($currentParams)) {
            $currentParams = [];
        }
        if (!isset($currentParams['plugins'])) {
            $currentParams['plugins'] = [];
        }
        $currentParams['plugins']['indicator'] = $indicator;

        $content = "<?php\n\nreturn " . var_export($currentParams, true) . ";\n";
        if (file_put_contents($paramsFile, $content) === false) {
            Yii::error('Could not write Indicator config to ' . $paramsFile, 'indicator');
            $this->addError('ftpHost', 'Configuration could not be saved to disk.');

            return false;
        }

        // Also persist to console params so the console app and jobs can read the config
        $consoleParamsFile = Yii::getAlias('@console', false)
            ? Yii::getAlias('@console') . '/config/params-local.php'
            : null;

        if ($consoleParamsFile && is_file($consoleParamsFile)) {
            $consoleParams = require $consoleParamsFile;
            if (!is_array($consoleParams)) {
                $consoleParams = [];
            }
            if (!isset($consoleParams['plugins'])) {
                $consoleParams['plugins'] = [];
            }
            $consoleParams['plugins']['indicator'] = $indicator;
            file_put_contents($consoleParamsFile, "<?php\n\nreturn " . var_export($consoleParams, true) . ";\n");
        }

        return true;
    }

    private function encryptPassword(string $password): string
    {
        if (empty($password)) {
            return '';
        }

        try {
            return base64_encode(Yii::$app->security->encryptByPassword($password, 'indicator_password_key'));
        } catch (\Throwable $e) {
            Yii::error('Failed to encrypt Indicator password: ' . $e->getMessage(), 'indicator');

            return '';
        }
    }

    private function decryptPassword(string $encrypted): string
    {
        if (empty($encrypted)) {
            return '';
        }

        try {
            $binary = base64_decode($encrypted, true);
            if ($binary === false) {
                return '';
            }

            return Yii::$app->security->decryptByPassword($binary, 'indicator_password_key');
        } catch (\Throwable $e) {
            return '';
        }
    }
}
