<?php

/**
 * @package     VP Prime Framework
 *
 * @author      Abhishek Das <info@virtueplanet.com>
 * @link        https://www.virtueplanet.com
 * @copyright   Copyright (C) 2012-2025 Virtueplanet Services LLP. All Rights Reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Virtueplanet\Plugin\System\Prime\Framework;

use Exception;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Session\Session;
use Virtueplanet\Plugin\System\Prime\Helper\FileverifierHelper;
use Virtueplanet\Plugin\System\Prime\Helper\GoogleFontHelper;
use Virtueplanet\Plugin\System\Prime\Helper\JsonHelper;
use Virtueplanet\Plugin\System\Prime\Helper\UpdateHelper;
use Virtueplanet\Plugin\System\Prime\Helper\VirtuemartHelper;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * AjaxMethods class
 */
class AjaxMethods
{
    /**
     * Application object.
     *
     * @var    \Joomla\CMS\Application\CMSApplication
     */
    protected $app;

    /**
     * AjaxMethods instance.
     *
     * @var     AjaxMethods
     */
    protected static $instance = null;

    /**
     * AjaxMethods constructor
     */
    public function __construct()
    {
        $this->app = Factory::getApplication();
    }

    /**
     * Get an instance of AjaxMethods
     *
     * @return     AjaxMethods
     */
    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * Called by Ajax interface component for VirtueMart products field.
     *
     * @return  void
     */
    public function getVirtuemartProducts()
    {
        if ($this->app->isClient('site') || !Factory::getApplication()->getIdentity()->id) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $like  = trim($this->app->input->get('like', null));
        $items = VirtuemartHelper::searchProducts($like);

        JsonHelper::return($items);
    }

    /**
     * Update Google Fonts file.
     * Called by Ajax interface component.
     *
     * @return  void
     */
    public function updateGoogleFonts()
    {
        if ($this->app->isClient('site') || !Factory::getApplication()->getIdentity()->id) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $file = urldecode($this->app->input->get('file', '', 'STRING'));

        try {
            GoogleFontHelper::update($file);
        } catch (Exception $e) {
            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => '']);
        }

        JsonHelper::return(['error' => false, 'message' => 'Google fonts updated.', 'data' => '']);
    }

    /**
     * Get items from Google Fonts.
     * Called by Ajax interface component.
     *
     * @return  void
     */
    public function getGoogleFontDetails()
    {
        if ($this->app->isClient('site') || !Factory::getApplication()->getIdentity()->id) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $file = urldecode($this->app->input->get('file', '', 'STRING'));
        $name = urldecode($this->app->input->get('name', '', 'STRING'));

        if (!$name) {
            JsonHelper::return(['error' => false, 'message' => '', 'data' => []]);
        }

        try {
            $data = GoogleFontHelper::getItem($file, $name);
        } catch (Exception $e) {
            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => []]);
        }

        if (!$data) {
            JsonHelper::return(['error' => true, 'message' => 'No data found', 'data' => []]);
        }

        JsonHelper::return(['error' => false, 'message' => '', 'data' => $data]);
    }

    /**
     * Get the extension update.
     *
     * @return  void
     */
    public function getExtensionUpdate()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $extensionId    = $this->app->input->getInt('extension_id', 0);
        $currentVersion = $this->app->input->getCmd('current_version', '');
        $data           = ['has_update' => false, 'version' => $currentVersion, 'infourl' => ''];

        if (empty($extensionId)) {
            JsonHelper::return(['error' => true, 'message' => 'Extension ID not provided.', 'data' => $data]);
        }

        if (empty($currentVersion)) {
            JsonHelper::return(['error' => true, 'message' => 'Current version not provided.', 'data' => $data]);
        }

        try {
            $update = UpdateHelper::getCurrentVersion($extensionId);
        } catch (Exception $e) {
            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => $data]);
        }

        if (!empty($update) && version_compare($update->version, $currentVersion, '>')) {
            $data['has_update'] = true;
            $data['version']    = $update->version;
            $data['infourl']    = $update->infourl;

            JsonHelper::return(['error' => false, 'message' => '', 'data' => $data]);
        }

        JsonHelper::return(['error' => false, 'message' => '', 'data' => $data]);
    }

    /**
     * Validate Download Key.
     *
     * @return  void
     */
    public function validateDlk()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $templateStyleId = $this->app->input->getInt('template_style_id', 0);
        $uname           = $this->app->input->get('uname', '', 'USERNAME');
        $dlk             = $this->app->input->get('dlk', '', 'STRING');
        $dlk             = UpdateHelper::cleanDlk($dlk);
        $data            = ['access_code' => 0, 'is_warning' => false, 'dlk' => $dlk, 'last_checked' => ''];
        $errorInfo       = ['file' => '', 'line' => ''];

        if (empty($templateStyleId)) {
            JsonHelper::return(['error' => true, 'message' => 'Template style ID not provided.', 'data' => $data, 'error_info' => $errorInfo]);
        }

        if (empty($uname)) {
            JsonHelper::return(['error' => true, 'message' => 'Please enter a valid Username.', 'data' => $data, 'error_info' => $errorInfo]);
        }

        if (empty($dlk)) {
            JsonHelper::return(['error' => true, 'message' => 'Please enter a valid Download Key.', 'data' => $data, 'error_info' => $errorInfo]);
        }

        try {
            UpdateHelper::validate($templateStyleId, $uname, $dlk);
        } catch (Exception $e) {
            if ($e->getCode() === UpdateHelper::EXCEPTION_CODE_WARNING) {
                $data['is_warning'] = true;
            }

            $data['access_code'] = UpdateHelper::getAccessCode();

            $date = UpdateHelper::getDate();

            if ($date) {
                $data['last_checked'] = HTMLHelper::_('date', $date, 'F d, Y H:i:s');
            }

            // $errorInfo['file']   = $e->getFile();
            // $errorInfo['line']   = $e->getLine();

            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => $data, 'error_info' => $errorInfo]);
        }

        $data['access_code'] = UpdateHelper::getAccessCode();

        $date = UpdateHelper::getDate();

        if ($date) {
            $data['last_checked'] = HTMLHelper::_('date', $date, 'F d, Y H:i:s');
        }

        JsonHelper::return(['error' => false, 'message' => 'Download key has been added successfully.', 'data' => $data, 'error_info' => $errorInfo]);
    }

    /**
     * Revalidate Download Key.
     *
     * @return  void
     */
    public function revalidateDlk()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $templateStyleId = $this->app->input->getInt('template_style_id', 0);
        $data            = ['access_code' => 0, 'is_warning' => false, 'last_checked' => ''];
        $errorInfo       = ['file' => '', 'line' => ''];

        if (empty($templateStyleId)) {
            JsonHelper::return(['error' => true, 'message' => 'Template style ID not provided.', 'data' => $data, 'error_info' => $errorInfo]);
        }

        try {
            UpdateHelper::validate($templateStyleId);
        } catch (Exception $e) {
            if ($e->getCode() === UpdateHelper::EXCEPTION_CODE_WARNING) {
                $data['is_warning'] = true;
            }

            $data['access_code'] = UpdateHelper::getAccessCode();

            $date = UpdateHelper::getDate();

            if ($date) {
                $data['last_checked'] = HTMLHelper::_('date', $date, 'F d, Y H:i:s');
            }

            // $errorInfo['file']   = $e->getFile();
            // $errorInfo['line']   = $e->getLine();

            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => $data, 'error_info' => $errorInfo]);
        }

        $data['access_code'] = UpdateHelper::getAccessCode();

        $date = UpdateHelper::getDate();

        if ($date) {
            $data['last_checked'] = HTMLHelper::_('date', $date, 'F d, Y H:i:s');
        }

        JsonHelper::return(['error' => false, 'message' => 'Download key has been revalidated successfully.', 'data' => $data, 'error_info' => $errorInfo]);
    }

    /**
     * Remove Download Key.
     *
     * @return  void
     */
    public function removeDlk()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $templateStyleId = $this->app->input->getInt('template_style_id', 0);
        $data            = ['access_code' => 0, 'is_warning' => false];
        $errorInfo       = ['file' => '', 'line' => ''];

        if (empty($templateStyleId)) {
            JsonHelper::return(['error' => true, 'message' => 'Template style ID not provided.', 'data' => $data, 'error_info' => $errorInfo]);
        }

        try {
            UpdateHelper::deleteDlk($templateStyleId);
        } catch (Exception $e) {
            // $errorInfo['file']   = $e->getFile();
            // $errorInfo['line']   = $e->getLine();

            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => $data, 'error_info' => $errorInfo]);
        }

        JsonHelper::return(['error' => false, 'message' => 'Download key has been deleted successfully.', 'data' => $data, 'error_info' => $errorInfo]);
    }

    /**
     * Build files hashes.
     *
     * @return  void
     */
    public function buildFilesHashes()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $templateStyleId = $this->app->input->getInt('template_style_id', 0);

        if (empty($templateStyleId)) {
            JsonHelper::return(['error' => true, 'message' => 'Template style ID not provided.', 'data' => '']);
        }

        try {
            FileverifierHelper::buildHashes($templateStyleId);
        } catch (Exception $e) {
            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => '']);
        }

        JsonHelper::return(['error' => false, 'message' => 'Hashes created and saved successfully.', 'data' => '']);
    }

    /**
     * Compare files hashes.
     *
     * @return  void
     */
    public function compareFileHashes()
    {
        if ($this->app->isClient('site')) {
            JsonHelper::return(['error' => true, 'message' => 'You do not have access to this resource.', 'data' => '']);
        }

        $this->checkToken();

        $templateStyleId = $this->app->input->getInt('template_style_id', 0);

        if (empty($templateStyleId)) {
            JsonHelper::return(['error' => true, 'message' => 'Template style ID not provided.', 'data' => '']);
        }

        try {
            $result = FileverifierHelper::compareHashes($templateStyleId);
        } catch (Exception $e) {
            JsonHelper::return(['error' => true, 'message' => $e->getMessage(), 'data' => '']);
        }

        JsonHelper::return(['error' => false, 'message' => '', 'data' => $result]);
    }

    /**
     * Check token.
     *
     * @return  bool
     */
    protected function checkToken()
    {
        $method = $this->app->input->getMethod();
        $method = !empty($method) ? $method : 'get';
        $valid  = Session::checkToken($method);

        if (!$valid) {
            JsonHelper::return(['error' => true, 'message' => Text::_('JINVALID_TOKEN'), 'data' => '']);
        }

        return $valid;
    }
}
