<?php
/**
 * RMBG PRO - PrestaShop Module
 *
 * Features:
 * - Configure RMBG.PRO API key in module configuration
 * - Add "Remove Background" button in product edit page
 * - Process one product image via AJAX and regenerate all product thumbnails
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

class Rmbgpro extends Module
{
    public const CONFIG_API_KEY = 'RMBGPRO_API_KEY';
    public const CONFIG_OUTPUT_FORMAT = 'RMBGPRO_OUTPUT_FORMAT';

    public function __construct()
    {
        $this->name = 'rmbgpro';
        $this->tab = 'administration';
        $this->version = '1.0.0';
        $this->author = 'RMBG.PRO';
        $this->need_instance = 0;
        $this->bootstrap = true;

        parent::__construct();

        $this->displayName = $this->l('RMBG PRO');
        $this->description = $this->l('Remove image backgrounds automatically using RMBG.PRO API');
        $this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => _PS_VERSION_];
    }

    public function install()
    {
        if (!parent::install()) {
            return false;
        }

        if (!$this->installConfigTab()) {
            return false;
        }

        if (!$this->installAjaxTab()) {
            return false;
        }

        if (
            !$this->registerHook('displayAdminProductsExtra')
            || !$this->registerHook('displayAdminProductsMainStepLeftColumnBottom')
            || !$this->registerHook('displayBackOfficeHeader')
            || !$this->registerHook('displayAdminAfterHeader')
        ) {
            return false;
        }

        if (!Configuration::updateValue(static::CONFIG_OUTPUT_FORMAT, 'png')) {
            return false;
        }

        return true;
    }

    public function uninstall()
    {
        Configuration::deleteByName(static::CONFIG_API_KEY);
        Configuration::deleteByName(static::CONFIG_OUTPUT_FORMAT);

        $this->uninstallAjaxTab();
        $this->uninstallConfigTab();

        return parent::uninstall();
    }

    protected function installConfigTab()
    {
        $className = 'AdminRmbgPro';
        if ((int) Tab::getIdFromClassName($className) > 0) {
            return true;
        }

        $parentId = (int) Tab::getIdFromClassName('AdminParentModulesSf');
        if ($parentId <= 0) {
            $parentId = (int) Tab::getIdFromClassName('AdminParentModules');
        }

        $tab = new Tab();
        $tab->active = 1;
        $tab->class_name = $className;
        $tab->name = [];
        foreach (Language::getLanguages(false) as $lang) {
            $tab->name[(int) $lang['id_lang']] = 'RMBG PRO';
        }
        $tab->id_parent = $parentId;
        $tab->module = $this->name;

        return (bool) $tab->add();
    }

    protected function uninstallConfigTab()
    {
        $idTab = (int) Tab::getIdFromClassName('AdminRmbgPro');
        if ($idTab <= 0) {
            return true;
        }

        $tab = new Tab($idTab);
        return (bool) $tab->delete();
    }

    protected function installAjaxTab()
    {
        $className = 'AdminRmbgAjax';
        if ((int) Tab::getIdFromClassName($className) > 0) {
            return true;
        }

        $parentId = (int) Tab::getIdFromClassName('AdminParentModulesSf');
        if ($parentId <= 0) {
            $parentId = (int) Tab::getIdFromClassName('AdminParentModules');
        }

        $tab = new Tab();
        $tab->active = 0;
        $tab->class_name = $className;
        $tab->name = [];
        foreach (Language::getLanguages(false) as $lang) {
            $tab->name[(int) $lang['id_lang']] = 'RMBG PRO (AJAX)';
        }
        $tab->id_parent = $parentId;
        $tab->module = $this->name;

        return (bool) $tab->add();
    }

    protected function uninstallAjaxTab()
    {
        $idTab = (int) Tab::getIdFromClassName('AdminRmbgAjax');
        if ($idTab <= 0) {
            return true;
        }

        $tab = new Tab($idTab);
        return (bool) $tab->delete();
    }

    public function getContent()
    {
        $this->ensureHooksRegistered();

        $output = '';

        if (Tools::isSubmit('submitRmbgproConfig')) {
            $apiKey = trim((string) Tools::getValue(static::CONFIG_API_KEY));
            $outputFormat = (string) Tools::getValue(static::CONFIG_OUTPUT_FORMAT);

            $allowedFormats = ['png', 'jpg', 'jpeg', 'webp', 'avif'];
            if (!in_array($outputFormat, $allowedFormats, true)) {
                $outputFormat = 'png';
            }

            Configuration::updateValue(static::CONFIG_API_KEY, $apiKey);
            Configuration::updateValue(static::CONFIG_OUTPUT_FORMAT, $outputFormat);

            $output .= $this->displayConfirmation($this->l('Settings updated.'));
        }

        $output .= $this->renderForm();
        $output .= $this->renderStatusPanel();
        $output .= $this->renderBulkPanel();

        return $output;
    }

    protected function renderStatusPanel()
    {
        $apiKey = (string) Configuration::get(static::CONFIG_API_KEY, '');
        $enabled = !empty($apiKey);

        $adminLink = $this->context->link->getAdminLink('AdminRmbgAjax', true);
        Media::addJsDef([
            'rmbgproStatus' => [
                'ajaxUrl' => $adminLink,
                'enabled' => $enabled,
            ],
        ]);

        $this->context->controller->addJS($this->_path . 'views/js/config-admin.js');
        $this->context->controller->addCSS($this->_path . 'views/css/admin.css');

        $disabledAttr = $enabled ? '' : 'disabled="disabled"';
        $currentStatus = $enabled ? $this->l('Not checked') : $this->l('Missing API key');

        return '
        <div class="panel">
          <h3><i class="icon-key"></i> ' . $this->l('API status') . '</h3>
          <p>
            <strong>' . $this->l('Status') . ':</strong>
            <span id="rmbgpro-api-status">' . $currentStatus . '</span>
          </p>
          <button type="button" class="btn btn-default" id="rmbgpro-validate-key" ' . $disabledAttr . '>
            ' . $this->l('Validate API key') . '
          </button>
          <span class="rmbgpro-spinner" id="rmbgpro-validate-spinner" style="display:none;margin-left:10px;"></span>
        </div>';
    }

    protected function renderBulkPanel()
    {
        $apiKey = (string) Configuration::get(static::CONFIG_API_KEY, '');
        $enabled = !empty($apiKey);

        $adminLink = $this->context->link->getAdminLink('AdminRmbgAjax', true);
        Media::addJsDef([
            'rmbgproBulk' => [
                'ajaxUrl' => $adminLink,
                'enabled' => $enabled,
            ],
        ]);

        $this->context->controller->addJS($this->_path . 'views/js/config-admin.js');
        $this->context->controller->addCSS($this->_path . 'views/css/admin.css');

        $disabledAttr = $enabled ? '' : 'disabled="disabled"';

        return '
        <div class="panel">
          <h3><i class="icon-refresh"></i> ' . $this->l('Bulk processing') . '</h3>
          <p>' . $this->l('Process product images in small batches to reduce timeouts.') . '</p>
          <button type="button" class="btn btn-default" id="rmbgpro-bulk-start" ' . $disabledAttr . '>
            ' . $this->l('Remove backgrounds for all product images') . '
          </button>
          <span class="rmbgpro-spinner" id="rmbgpro-bulk-spinner" style="display:none;margin-left:10px;"></span>
          <div id="rmbgpro-bulk-log" style="margin-top:10px;"></div>
        </div>';
    }

    protected function renderForm()
    {
        $defaultLang = (int) $this->context->language->id;

        $fieldsForm = [
            'form' => [
                'legend' => [
                    'title' => $this->l('RMBG PRO Settings'),
                    'icon' => 'icon-cogs',
                ],
                'input' => [
                    [
                        'type' => 'text',
                        'label' => $this->l('API Key'),
                        'name' => static::CONFIG_API_KEY,
                        'required' => true,
                        'desc' => $this->l('Get your API key from rmbg.pro'),
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->l('Output format'),
                        'name' => static::CONFIG_OUTPUT_FORMAT,
                        'required' => true,
                        'options' => [
                            'query' => [
                                ['id' => 'png', 'name' => 'PNG'],
                                ['id' => 'jpg', 'name' => 'JPG'],
                                ['id' => 'jpeg', 'name' => 'JPEG'],
                                ['id' => 'webp', 'name' => 'WEBP'],
                                ['id' => 'avif', 'name' => 'AVIF'],
                            ],
                            'id' => 'id',
                            'name' => 'name',
                        ],
                        'desc' => $this->l('For product images, PrestaShop keeps JPG files by default. Non-JPG results are converted to JPG before replacing the image.'),
                    ],
                ],
                'submit' => [
                    'title' => $this->l('Save'),
                ],
            ],
        ];

        $helper = new HelperForm();
        $helper->module = $this;
        $helper->name_controller = $this->name;
        $helper->identifier = $this->identifier;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
        $helper->default_form_language = $defaultLang;
        $helper->allow_employee_form_lang = $defaultLang;
        $helper->title = $this->displayName;
        $helper->submit_action = 'submitRmbgproConfig';

        $helper->fields_value[static::CONFIG_API_KEY] = Configuration::get(static::CONFIG_API_KEY, '');
        $helper->fields_value[static::CONFIG_OUTPUT_FORMAT] = Configuration::get(static::CONFIG_OUTPUT_FORMAT, 'png');

        return $helper->generateForm([$fieldsForm]);
    }

    protected function ensureHooksRegistered()
    {
        if (!$this->isRegisteredInHook('displayAdminProductsExtra')) {
            $this->registerHook('displayAdminProductsExtra');
        }
        if (!$this->isRegisteredInHook('displayAdminProductsMainStepLeftColumnBottom')) {
            $this->registerHook('displayAdminProductsMainStepLeftColumnBottom');
        }
        if (!$this->isRegisteredInHook('displayBackOfficeHeader')) {
            $this->registerHook('displayBackOfficeHeader');
        }
        if (!$this->isRegisteredInHook('displayAdminAfterHeader')) {
            $this->registerHook('displayAdminAfterHeader');
        }
    }

    public function hookDisplayBackOfficeHeader($params)
    {
        $apiKey = (string) Configuration::get(static::CONFIG_API_KEY, '');
        $enabled = !empty($apiKey);

        $adminLink = $this->context->link->getAdminLink('AdminRmbgAjax', true);
        Media::addJsDef([
            'rmbgproProductsList' => [
                'ajaxUrl' => $adminLink,
                'enabled' => $enabled,
            ],
        ]);

        $this->context->controller->addJS($this->_path . 'views/js/products-list-admin.js');
        $this->context->controller->addCSS($this->_path . 'views/css/admin.css');
    }

    public function hookDisplayAdminAfterHeader($params)
    {
        $apiKey = (string) Configuration::get(static::CONFIG_API_KEY, '');
        $enabled = !empty($apiKey);
        $adminLink = $this->context->link->getAdminLink('AdminRmbgAjax', true);

        $jsUrl = $this->_path . 'views/js/products-list-admin.js';

        $json = json_encode([
            'ajaxUrl' => $adminLink,
            'enabled' => $enabled,
        ]);

        if (!is_string($json) || $json === '') {
            return '';
        }

        return '<script>window.rmbgproProductsList=' . $json . ';</script>'
            . '<script src="' . htmlspecialchars($jsUrl, ENT_QUOTES, 'UTF-8') . '"></script>';
    }

    public function hookDisplayAdminProductsMainStepLeftColumnBottom($params)
    {
        return $this->renderProductHookPanel($params);
    }

    public function hookDisplayAdminProductsExtra($params)
    {
        return $this->renderProductHookPanel($params);
    }

    protected function renderProductHookPanel($params)
    {
        $apiKey = (string) Configuration::get(static::CONFIG_API_KEY, '');
        $enabled = !empty($apiKey);

        $idProduct = $this->extractProductId($params);
        $idShop = (int) $this->context->shop->id;
        $idLang = (int) $this->context->language->id;

        $images = [];
        if ($idProduct > 0) {
            $images = Image::getImages($idLang, $idProduct);
        }

        $adminLink = $this->context->link->getAdminLink('AdminRmbgAjax', true);

        Media::addJsDef([
            'rmbgpro' => [
                'ajaxUrl' => $adminLink,
                'idShop' => $idShop,
                'enabled' => $enabled,
            ],
        ]);

        $this->context->controller->addJS($this->_path . 'views/js/product-admin.js');
        $this->context->controller->addCSS($this->_path . 'views/css/admin.css');

        $this->context->smarty->assign([
            'rmbgpro_enabled' => $enabled,
            'rmbgpro_images' => $images,
            'rmbgpro_configure_url' => $this->context->link->getAdminLink('AdminModules', true) . '&configure=' . $this->name,
        ]);

        return $this->display(__FILE__, 'views/templates/admin/product_hook.tpl');
    }

    protected function extractProductId($params)
    {
        if (is_array($params)) {
            if (isset($params['id_product'])) {
                return (int) $params['id_product'];
            }
            if (isset($params['id'])) {
                return (int) $params['id'];
            }
        }

        $id = (int) Tools::getValue('id_product');
        if ($id > 0) {
            return $id;
        }
        $id = (int) Tools::getValue('id');
        if ($id > 0) {
            return $id;
        }

        return 0;
    }
}
