<?php

/*
 * @component UserPoints
 * @copyright Copyright (C) 2015-2022 Bernard Gilly - Adrien Roussel - Martin Brampton
 * @license : GNU/GPL
 * @Website : https://remository.com
 */

namespace BlackSheepResearch\Component\UserPoints\Site\Controllers;

// no direct access
defined('_JEXEC') or die('Restricted access');

use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Session\Session;
use BlackSheepResearch\Component\UserPoints\Site\UserController;
use BlackSheepResearch\Component\UserPoints\Site\UserPoints;
use BlackSheepResearch\Component\UserPoints\Site\Problems\PointsDetails;
use BlackSheepResearch\Component\UserPoints\Site\Problems\Rule;
use BlackSheepResearch\Component\UserPoints\Site\Problems\SQL;

/**
 * @package UserPoints
 */
class PurchaseControl extends UserController {

    protected $task = '';

    public function getModel($name = '', $prefix = '', $config = array('ignore_request' => true)) {
        $return = parent::getModel($name, $prefix, array('ignore_request' => false));
        return $return;
    }

    public function display($cachable = false, $urlparams = []) {
        $params = ComponentHelper::getParams('com_userpoints');
        if ($params->get('No_details_for_purchases',0) OR $this->checkForProblems()) {
            return;
        }
        $this->task = Factory::getApplication()->input->get('task', 'startform', 'string');
        $maximum_points = intval($params->get('maximum_points', 0));
        $maximum_spend = intval($params->get('Maximum_spend', 100));
        if ($maximum_points) {
            $points_to_buy = max(0, $maximum_points - ceil($this->getUserPoints()));
            $maximum_spend = min($maximum_spend, ($points_to_buy / (float) $params->get('Points_per_unit',1.0)));
        } else {
            $maximum_spend = 0;
        }

        $this->callViewWithExtras($maximum_spend);
        return;
    }

    private function getUserPoints() {
        return UserPoints::getCurrentTotalPoints('', UserPoints::getUser()->id);
    }

    public function payment() {
        if (!Session::checkToken()) {
            throw new \Exception(Text::_('JINVALID_TOKEN_NOTICE'), 403);
        } if ($this->checkForProblems()) {
            return;
        }
        $getinput = Factory::getApplication()->input;
        $payamount = $getinput->get('howmany', '1', 'string');
        $itemname = $getinput->get('itemname', 'UserPoints', 'string');
        $this->callViewWithExtras(0.0, $payamount, $itemname);
        return;
    }

    public function complete() {
        if (!file_exists(JPATH_ADMINISTRATOR . '/components/com_payage/api.php')) {
            Factory::getApplication()->enqueueMessage(Text::_('COM_PAYAGE_TEST_NOT_INSTALLED'));
            return;
        }
        require_once JPATH_ADMINISTRATOR . '/components/com_payage/api.php';
        $tid = Factory::getApplication()->input->get('tid', '', 'string');
        $result = \PayageApi::get_payment_data($tid);
        // PayageApi::Get_Status_Description($payment_data->pg_status_code);
        $codes = [
            LAPG_STATUS_NONE => 'AUP_LAPG_STATUS_NONE',
            LAPG_STATUS_SUCCESS => 'AUP_LAPG_STATUS_SUCCESS',
            LAPG_STATUS_PENDING => 'AUP_LAPG_STATUS_PENDING',
            LAPG_STATUS_FAILED => 'AUP_LAPG_STATUS_FAILED',
            LAPG_STATUS_CANCELLED => 'AUP_LAPG_STATUS_CANCELLED',
            LAPG_STATUS_REFUNDED => 'AUP_LAPG_STATUS_REFUNDED',
        ];
        if (isset($result->app_transaction_details[1])) {
            $detail = new PointsDetails((int) $result->app_transaction_details[1]);
        }
        if (!isset($detail) OR !$detail->id OR 'sysplgup_buypoints' != $detail->rule_id) {
            Factory::getApplication()->enqueueMessage(Text::_('COM_PAYAGE_INTERNAL_ERROR'));
            return;
        }
        $detail->referreid = $result->app_transaction_details[0];
        $detail->rule_id = 'sysplgup_buypoints';
        $detail->points = $this->calcPointsBought($result);
        $detail->insert_date = SQL::datetimeSQL();
        $detail->status = 1;
        $detail->approved = (LAPG_STATUS_SUCCESS == $result->pg_status_code) ? 1 : 0;
        $detail->keyreference = $tid;
        $detail->datareference = Text::_($codes[$result->pg_status_code]);
        $detail->enabled = 1;
        if ($detail->save()) {
            $report = Text::_($codes[$result->pg_status_code]);
            if (LAPG_STATUS_PENDING == $result->pg_status_code) {
                $report .= " ($result->gw_pending_reason)";
            }
            echo Text::_('AUP_PURCHASE_PROCESSED') . " $report";
        }
    }

    private function calcPointsBought($result) {
        if (LAPG_STATUS_SUCCESS != $result->pg_status_code) {
            return 0.0;
        }
        $params = ComponentHelper::getParams('com_userpoints');
        return $result->gross_amount * (float) $params->get('Points_per_unit');
    }

    private function callViewWithExtras($maximum_spend = 0.0, $payamount = 0.0, $itemname = 'UserPoints') {
        $task = Factory::getApplication()->input->get('task', 'startform', 'string');
        $view = $this->getView('purchase', 'html');
        $params = ComponentHelper::getParams('com_userpoints');
        $currency = $params->get('Payment_Currency', '');
        if ($currency) {
            $userpoints = $this->getUserPoints();
            $fpoints = UserPoints::getFormattedPoints($userpoints);
            $view->_displaylist($task, $currency, $payamount, $itemname, $fpoints, $maximum_spend, (float) $params->get('Points_per_unit',1.0));
        } else {
            Factory::getApplication()->enqueueMessage(Text::_('AUP_PURCHASE_NO_CURRENCY'));
        }
    }

    private function checkForProblems() {
        $app = Factory::getApplication();
        if (!file_exists(JPATH_ADMINISTRATOR . '/components/com_payage/api.php')) {
            $app->enqueueMessage(Text::_('COM_PAYAGE_TEST_NOT_INSTALLED'));
            return true;
        }
        if (!UserPoints::getUser()->id) {
            $app->enqueueMessage(Text::_('AUP_PURCHASE_LOGIN_REQUIRED'));
            return true;
        }
        $rule = Rule::withRuleName('sysplgup_buypoints');
        if (!is_object($rule) OR !$rule->published) {
            $app->enqueueMessage(Text::_('AUP_PURCHASE_RULE_NOT_PUBLISHED'));
            return true;
        }
        return false;
    }
}
