<?php
/**
 * Author: lopiu
 * Date: 03.07.2020
 * Time: 07:24
 */

class Bank
{
    public $user_id;
    public $money = 0;
    public $status = '';

    const BANK_COMISSION = 0.05; //5%
    const SUCCESS = "Успешная операция!";
    const ERROR_NO_MONEY_IN_WALLET = "Ошибка! Нет денег в кошельке!";
    const ERROR_NO_BANK_ACCOUNT = "Ошибка! Счёта не существует!";
    const ERROR_NO_MONEY_IN_BANK_ACCOUNT = "Ошибка! Нет денег на счету!";
    const ERROR_WRONG_AMOUNT = "Ошибка! Сумма должна быть положительной!";
    const LOG_SEND = "Банк: Перевод средств на другой счёт.";
    const LOG_RECEIVE = "Банк: Получение средств.";
    const LOG_DEPOSIT = "Пополнение счёта.";
    const LOG_WITHDRAW = "Снятие денег со счёта.";

    public function __construct($row)
    {
        $bank_row = db::c()->query('SELECT user_id, money FROM bank WHERE user_id = ?i', $row)->fetch_assoc();
        foreach ($this as $key => $value) {
            if (isset($bank_row[$key])) {
                $this->$key = $bank_row[$key];
            }
        }
        // Если ВДРУГ у человека нет счёта в банке - создаём.
        if (empty($this->user_id)) {
            db::c()->query('INSERT INTO bank (user_id) VALUES (?i)', $row);
            $this->user_id = $row;
        }
    }

    /**
     * Комиссия: self::BANK_COMISSION от переводимой суммы, но не менее 1 кр.
     * @param $amount
     * @return int
     */
    private function bankComission($amount)
    {
        $bankComission = round($amount * self::BANK_COMISSION);
        if ($bankComission < 1) {
            return 1;
        } else {
            return (int)$bankComission;
        }
    }

    /**
     * Пишем банковское событие в лог в БД
     * @param $receiverId - user_id получателя
     * @param $amount
     * @param $operationType
     * @throws \Krugozor\Database\Mysql\Exception
     */
    private function bankLogs($receiverId, $amount, $operationType)
    {
        $text = '';
        if ($operationType === "sendMoney") {
            $text = self::LOG_SEND . " Комиссия: " . $this->bankComission($amount);
        } elseif ($operationType === "depositMoney") {
            $receiverId = $this->user_id;
            $text = self::LOG_DEPOSIT;
        } elseif ($operationType === "withdrawMoney") {
            $receiverId = $this->user_id;
            $text = self::LOG_WITHDRAW . " Комиссия: " . $this->bankComission($amount);
        }

        db::c()->query('INSERT INTO `bank_logs` (sender_id, receiver_id, amount, type, text) 
                            VALUES (?i, ?i, ?i, "?s", "?s")', $this->user_id, $receiverId, $amount, $operationType, $text);

    }

    /**
     * Перевод денег между бансковскими счетами игроков с банковской комиссией.
     * @param $receiver - получатель
     * @param $amount   - сумма
     * @return string
     * @throws \Krugozor\Database\Mysql\Exception
     */
    public function sendMoney($receiver, $amount)
    {
        if ($amount > 0) {
            if (db::c()->query('SELECT `user_id` FROM `bank` WHERE `id` = ?i', $receiver)) {
                $amountWithComission = $amount + $this->bankComission($amount);
                if ($amountWithComission <= $this->money) {
                    // Снимаем сумму с комиссией у отправителя
                    db::c()->query('UPDATE bank SET money = money - ?i WHERE `user_id` = ?i', $amountWithComission, $this->user_id);
                    // Отдаём сумму на счёт получателю
                    db::c()->query('UPDATE bank SET money = money + ?i WHERE `user_id` = ?i', $amount, $receiver);
                    $this->bankLogs($receiver,$amount,"sendMoney");
                    $this->status = self::SUCCESS;
                } else {
                    $this->status = self::ERROR_NO_MONEY_IN_BANK_ACCOUNT;
                }
            } else {
                $this->status = self::ERROR_NO_BANK_ACCOUNT;
            }
        } else {
            $this->status = self::ERROR_WRONG_AMOUNT;
        }
        return $this->status;
    }

    /**
     * Пополнение банковского счёта игрока
     * @param $amount - сумма
     * @return string
     * @throws \Krugozor\Database\Mysql\Exception
     */
    public function depositMoney($amount)
    {
        if ($amount > 0) {
            $row = db::c()->query('SELECT money FROM users WHERE id = ?i', $this->user_id)->fetch_assoc();
            if ($amount >= $row['money']) {
                // Забираем деньги из кошелька получателя
                db::c()->query('UPDATE users SET money = money - ?i WHERE `id` = ?i', $amount, $this->user_id);
                // Отдаём сумму на счёт получателю
                db::c()->query('UPDATE bank SET money = money + ?i WHERE `user_id` = ?i', $amount, $this->user_id);
                $this->bankLogs(0, $amount, "depositMoney");
                $this->status = self::SUCCESS;
            } else {
                $this->status = self::ERROR_NO_MONEY_IN_WALLET;
            }
        } else {
            $this->status = self::ERROR_WRONG_AMOUNT;
        }
        return $this->status;
    }

    /**
     * Снятие денег с банковского счёта игрока с банковской комиссией.
     * @param $amount - сумма
     * @return string
     * @throws \Krugozor\Database\Mysql\Exception
     */
    public function withdrawMoney($amount)
    {
        if ($amount > 0) {
            $amountWithComission = $amount + $this->bankComission($amount);
            if ($amountWithComission <= $this->money) {
                // Снимаем сумму с комиссией у отправителя
                db::c()->query('UPDATE bank SET money = money - ?i WHERE `user_id` = ?i', $amountWithComission, $this->user_id);
                // Отдаём сумму в кошелёк получателя
                db::c()->query('UPDATE users SET money = money + ?i WHERE `id` = ?i', $amount, $this->user_id);
                $this->bankLogs(0, $amount, "withdrawMoney");
                $this->status = self::SUCCESS;
            } else {
                $this->status = self::ERROR_NO_MONEY_IN_BANK_ACCOUNT;
            }
        } else {
            $this->status = self::ERROR_WRONG_AMOUNT;
        }
        return $this->status;
    }
}