<?php 
/**
 * @package    Proxim
 * @author     Davison Pro, Chris Mugo <davisonpro.coder@gmail.com>
 * @copyright  2019 Proxim
 * @version    1.5.0
 * @since      File available since Release 1.0.0
 */

namespace Proxim\User;

use Db;
use Exception;
use Proxim\Cache\Cache;
use Proxim\Configuration;
use Proxim\Currency;
use Proxim\Database\DbQuery;
use Proxim\Module\PaymentModule;
use Proxim\ObjectModel;
use Proxim\Tools;
use Proxim\Util\DateUtils;
use Proxim\Validate;

class Wallet extends ObjectModel
{
    public $id;

    public $customer_id;

    public $wallet_balance = 0;

    public $date_upd;

    public $date_add;

    /**
     * @see ObjectModel::$definition
     */
    public static $definition = array(
        'table' => 'customer_wallet',
        'primary' => 'wallet_id',
        'fields' => array(
            'customer_id' => array('type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'),
            'wallet_balance' => array('type' => self::TYPE_FLOAT, 'validate' => 'isPrice'),
            'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDateOrNull'),
            'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate')
        )
    );

    /**
     * constructor.
     *
     * @param null $id
     */
    public function __construct($id = null)
    {
        parent::__construct($id);
    }
    
    public static function getIdByCustomerId( $customerId ) {
        $cacheId = 'Wallet::getIdByCustomerId_' . (int) $customerId;
        if (!Cache::isStored($cacheId)) {
            $sql = new DbQuery();
            $sql->select('cw.wallet_id');
            $sql->from('customer_wallet', 'cw');
            $sql->where('cw.`customer_id` = ' . (int) $customerId );

            $result = (int) Db::getInstance(PROX_USE_SQL_SLAVE)->getValue($sql);
            Cache::store($cacheId, $result);

            return $result;
        }

        return Cache::retrieve($cacheId);
    }

    public static function chargeWallet(
        $customer_id,
        $total, 
        $currency_id, 
        $node_id,
        $node
    ) {
        $wallet_id = self::getIdByCustomerId( $customer_id );
        $wallet = new Wallet( (int) $wallet_id );

        if(
            !Validate::isLoadedObject($wallet) ||
            $total > $wallet->wallet_balance
        ) {
            throw new Exception("You don't have enough balance in your wallet");
        }

        $currency = new Currency( (int) $currency_id );
        if(!Validate::isLoadedObject($currency)) {
            throw new Exception("Invalid Currency");
        }

        $transaction_id = Tools::randomGen(10);

        $result = Db::getInstance()->insert(
            'wallet_transaction',
            array(
                'wallet_id' => $wallet->id,
                'currency_id' => $currency->id,
                'transaction_id' => $transaction_id, 
                'source' => $node,
                'payment_method' => "wallet",
                'amount' => $total,
                'date_add' => DateUtils::now(),
            )
        );

        PaymentModule::processPayment(
            $node_id,
            $node,
            array(
                'amount' => $total,
                'payment_method' => 'wallet',
                'currency' => $currency->iso_code,
                'paymentId' => $transaction_id
            )
        );

        if(!$result) {
            return false;
        }

        // minus the wallet balance
        $wallet->wallet_balance = $wallet->wallet_balance - $total;
        $wallet->update();

        return true;
    }

}