<?php
/**
* @package XenCentral Ad Server
* @author Skydevelop EU
* @copyright Drnoyan & Nalyan LDA, Portugal, EU
* @license http://www.dnf.pt/eula.html
* @link http://www.skydevelop.com
* @revision 97
* @version 2.0.0 beta 3 rev. 3
*/

class XenCentral_AdServer_Model_CreditLog extends XenCentral_AdServer_Model_Abstract
{
    public function logPayment($user_id, $dateline, $payment_info_id, $transaction_id)
    {
        $this->_getDb()->insert('xcas_credit_transaction_log', array(
            'user_id' => $user_id,
            'dateline' => $dateline,
            'payment_info_id' => $payment_info_id,
            'transaction_id' => $transaction_id
        ));
    }

    public function logAdminCredit($user_id, $dateline, $admin_id, $mode, $amount, $info='')
    {
        $this->_getDb()->insert('xcas_credit_transaction_log', array(
            'user_id' => $user_id,
            'dateline' => $dateline,
            'payment_info_id' => 0,
            'transaction_id' => 0,
            'admin_user_id'=>$admin_id,
            'manual_transaction_data'=>serialize(array(
                'mode'=>$mode,
                'amount'=>$amount,
                    'info'=>$info
            ))
        ));
    }

    public function prepareTransactionLogConditions($conditions, $fetchOptions)
    {
        $db = $this->_getDb();
        $sqlConditions = array();

        if (!empty($conditions['transaction_id'])) {
            if (is_array($conditions['transaction_id'])) {
                $sqlConditions[] = 'log.transaction_id IN (' . $db->quote($conditions['transaction_id']) . ')';
            } else {
                $sqlConditions[] = 'log.transaction_id = ' . $db->quote($conditions['transaction_id']);
            }
        }

        if (!empty($conditions['log_id'])) {
            if (is_array($conditions['log_id'])) {
                $sqlConditions[] = 'log.log_id IN (' . $db->quote($conditions['log_id']) . ')';
            } else {
                $sqlConditions[] = 'log.log_id = ' . $db->quote($conditions['log_id']);
            }
        }

        if (!empty($conditions['user_id'])) {
            if (is_array($conditions['user_id'])) {
                $sqlConditions[] = 'user.user_id IN (' . $db->quote($conditions['user_id']) . ')';
            } else {
                $sqlConditions[] = 'user.user_id = ' . $db->quote($conditions['user_id']);
            }
        }

        return $this->getConditionsForClause($sqlConditions);
    }

    public function countTransactionLogs(array $conditions = array())
    {
        $fetchOptions = array();
        $whereClause = $this->prepareTransactionLogConditions($conditions, $fetchOptions);

        // joins are needed for conditions
        return $this->_getDb()->fetchOne("
			SELECT COUNT(*)
            FROM xcas_credit_transaction_log AS log
            LEFT JOIN xcfw_paymentapi_transaction AS info ON info.id=log.payment_info_id
            LEFT JOIN xcfw_paymentapi_transactionlog AS transaction_log ON transaction_log.infoid=log.payment_info_id AND transaction_log.transactionid=log.transaction_id
            LEFT JOIN xf_user AS admin_user ON admin_user.user_id=log.admin_user_id
            LEFT JOIN xf_user AS user ON user.user_id=log.user_id
            WHERE " . $whereClause . "
		");
    }

    public function getUserTransactions($conditions=array(), $fetchOptions=array())
    {
        $whereClause = $this->prepareTransactionLogConditions($conditions, $fetchOptions);
        $limitOptions = $this->prepareLimitFetchOptions($fetchOptions);

        $transactions = $this->fetchAllKeyed(
                $this->limitQueryResults("
                    SELECT log.*, user.username, admin_user.username AS admin_username, info.method, info.initinfo, transaction_log.status
                    FROM xcas_credit_transaction_log AS log
                    LEFT JOIN xcfw_paymentapi_transaction AS info ON info.id=log.payment_info_id
                    LEFT JOIN xcfw_paymentapi_transactionlog AS transaction_log ON transaction_log.infoid=log.payment_info_id AND transaction_log.transactionid=log.transaction_id
                    LEFT JOIN xf_user AS admin_user ON admin_user.user_id=log.admin_user_id
                    LEFT JOIN xf_user AS user ON user.user_id=log.user_id
                    WHERE " . $whereClause . "
                    ORDER BY log.dateline DESC
                ", $limitOptions['limit'], $limitOptions['offset']), 'log_id'
        );

        foreach ($transactions AS &$transaction) {
            $transaction = $this->_prepareUserTransaction($transaction);
        }

        $this->_loadPhrases($transactions);

        return $transactions;
    }

    public function getUserTransactionById($logId)
    {
        $transactions = $this->getUserTransactions(array(
            'log_id'=>$logId
        ));

        return reset($transactions);
    }

    protected function _loadPhrases($array)
    {
        foreach ($array AS $index => $value) {
            if (is_array($value)) {
                $this->_loadPhrases($value);
                continue;
            }
            if (is_object($value) && $value instanceof XenForo_Phrase) {
                XenForo_Phrase::preloadPhrase($value->getPhraseName());
            }
        }
    }

    /**
     * @param $transaction
     * @return mixed
     */
    protected function _prepareUserTransaction($transaction)
    {
        if(!is_array($transaction)) {
            return array();
        }

        $transaction['amount']=0;

        if ($transaction['payment_info_id']) {
            if ($transaction['initinfo']) {
                $transaction['initinfo'] = unserialize($transaction['initinfo']);
                $transactionInfo = $transaction['initinfo']['info'];
            } else {
                $transactionInfo = array();
            }

            if ($transaction['status'] == 'payment') {
                $action = new XenForo_Phrase('xcas_credit_added');
            } else if ($transaction['status'] == 'refund') {
                $action = new XenForo_Phrase('xcas_credit_removed');
            } else {
                $action = $transaction['status'];
            }

            $transaction['amount']= $transactionInfo['amount'];

            $action .= ' ' . XenForo_Locale::numberFormat($transactionInfo['amount'], 2) . ' ' . $transactionInfo['currency_code'];

            $method = explode('_', $transaction['method']);
            $method = end($method);
            try {
                $methodObject = XenCentral_PaymentApi_Module::getInstance()->getMethod($method);
                $method = $methodObject->getMethodIdentifier(true);
            } catch (Exception $ex) {
                // do nothing
            }
            $transaction['method'] = $method;
        } else {
            // admin credit transaction
            try {
                $transactionInfo = unserialize($transaction['manual_transaction_data']);
            } catch (Exception $ex) {
                $transactionInfo = array(
                        'mode' => $transaction['manual_transaction_data'],
                        'amount' => 0
                );
            }
            if ($transactionInfo['mode'] == 'add') {
                $action = new XenForo_Phrase('xcas_credit_added');
            } else if ($transactionInfo['mode'] == 'subtract') {
                $action = new XenForo_Phrase('xcas_credit_removed');
            } else if ($transactionInfo['mode'] == 'set') {
                $action = new XenForo_Phrase('xcas_credits_set');
            } else {
                $action = $transactionInfo['mode'];
            }

            if (!$transaction['admin_username']) {
                $transaction['admin_username'] = 'Admin #' . $transaction['admin_user_id'];
            }

            if (!empty($transactionInfo['info'])) {
                $transaction['admin_username'] .= ' (' . $transactionInfo['info'] . ')';
            }

            $transactionInfo['currency_code'] = $this->_getOptionsModel()->transaction_currency();
            $action .= ' ' . XenForo_Locale::numberFormat($transactionInfo['amount'], 2) . ' ' . $transactionInfo['currency_code'];

            $action = new XenForo_Phrase('xcas_credits_action_by_username', array(
                    'action' => $action,
                    'username' => $transaction['admin_username']
            ));

            $transaction['method'] = new XenForo_Phrase('xcas_manual');
        }

        $transaction['action'] = $action;
        $transaction['date'] = XenForo_Locale::dateTime($transaction['dateline']);
        return $transaction;
    }
}