<?php

namespace App\Models;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Yajny\Member\Models\MerchantStatusActivities;
use Yajny\Member\Models\Member;
use Yajny\Member\Models\UserExpiredAvailableAmount;
use Yajny\Member\Models\UsersBalance;

class usersdata extends Central
{
    protected $table = 'users';
    protected $primaryKey = 'user_id';
    protected $guarded = [];

    public $module = 'usersdata';
    public $timestamps = false;



    public function __construct()
    {
        parent::__construct();
    }

    public static function boot()
    {
        parent::boot();

        static::updated(function ($usersData) {
            $changes = $usersData->getChanges();

            $actionby_id=  Session::get('uid');;
            if (isset($changes['valid_merchant']) && $changes['valid_merchant'] == 1) {
                if($usersData->is_merchant==1) {
                    Member::ChangeMerchantStatus($usersData->user_id,'validate', $actionby_id);
                }
            }
            // dd($usersData, "revoked_merchant", $actionby_id, $changes);
            if(isset($changes['revoked_merchant']) && $changes['revoked_merchant'] == 1){
                if($usersData->is_merchant==0){
                    Member::ChangeMerchantStatus($usersData->user_id,'revoke', $actionby_id);
                }
            }
            if (isset($changes['type']) ) {
                if($changes['type'] == 'affiliate'){
                    if($usersData->is_merchant==1){
                        Member::declineMerchantBonuses([$usersData->user_id]);
                    }
                }
            }else{
                if (isset($changes['is_merchant'])) {
                    if ($changes['is_merchant'] == 1 ) {
                        if (isset($changes['valid_merchant']) && $changes['valid_merchant'] == 1) {
                            Member::ChangeMerchantStatus($usersData->user_id,'validate', $actionby_id);
                        }else{
                            Member::ChangeMerchantStatus($usersData->user_id,'tagged', $actionby_id);
                        }
                    }
                }
            }
        });
    }

    public static function querySelect()
    {
        return "  SELECT users.* FROM users  ";
    }

    public static function queryWhere()
    {
        return "  WHERE users.user_id IS NOT NULL ";
    }

    public static function queryGroup()
    {
        return "  ";
    }
    public static function getRow($id)
    {
        $emptybalance = ['cashback'=>[ "pending" =>0.0, "confirmed" =>0.0, "declined" =>0.0 ],
            'reward'=>["pending" =>0.0, "confirmed" =>0.0, "declined" =>0.0],
            'paid'=>["amount" =>0.0],
            'total'=>["pending" =>0.0, "confirmed" =>0.0, "declined" =>0.0, "paid" =>0.0]];
        $userArray=[];
        $user = \Yajny\Member\Models\Member::with(['payout_methods', 'userExpiredAvailableAmount', 'moderators'])->find($id);

        if($user){
            $userArray = $user->toArray();

            $memberCurrency = $user->getUserCurrency();
            $userBalanceModel = UsersBalance::where('user_id', $user->user_id)->first();
            if (is_null($userBalanceModel)) {
                $WalletBalance = $user->getWalletBalance();
                $userBalance = self::formatBalanceForWalletPage($WalletBalance, $memberCurrency);
                $BalanceFormatted = self::getBalanceFormatted($user);

                $userBalance["cashback"] = $BalanceFormatted["cashback"]["available"];
                $userBalance["cashback_formatted"] = $BalanceFormatted["cashback"]["available_formatted"];
                $userBalance["reward"] = $BalanceFormatted["reward"]["available"];
                $userBalance["reward_formatted"] = $BalanceFormatted["reward"]["available_formatted"];


                $userBalance["total_earned"] = $BalanceFormatted["cashback"]["available"] + $BalanceFormatted["reward"]["available"];
                if (is_null($memberCurrency) || $memberCurrency->iso_code == 'USD') {
                    $userBalance["total_earned_formatted"] = $userBalance["total_earned"] . ' USD';
                    $userBalance["total_unwithdrawn_formatted"] = 0 . ' USD';
                } else {
                    $userBalance["total_earned_formatted"] = ($userBalance["total_earned"]) . ' ' . $memberCurrency->iso_code;
                    $userBalance["total_unwithdrawn_formatted"] = 0 . ' ' . $memberCurrency->iso_code;
                }

            }
            else {
                $userBalance["balance"] = $userBalanceModel->available_amount + $userBalanceModel->pending_amount;
                if (is_null($memberCurrency) || $memberCurrency->iso_code == 'USD') {

                    $userBalance["balance_formatted"] = $userBalance["balance"] . ' USD';
                    $userBalance["pending_formatted"] = ($userBalanceModel->pending_amount) . ' USD';
                    $userBalance["available_formatted"] = $userBalanceModel->available_amount . ' USD';
                    $userBalance["bonus_formatted"] = ($userBalanceModel->confirmed_bonus + $userBalanceModel->pending_bonus) . ' USD';
                    $userBalance["cashback_formatted"] = ($userBalanceModel->confirmed_cashback) . ' USD';
                    $userBalance["reward_formatted"] = $userBalanceModel->confirmed_bonus . ' USD';

                    $userBalance["total_earned"] = $userBalanceModel->confirmed_cashback + $userBalanceModel->confirmed_bonus;
                    $userBalance["total_earned_formatted"] = $userBalance["total_earned"] . ' USD';

                    $userBalance["total_unwithdrawn_formatted"] =  UserExpiredAvailableAmount::where('user_id', $user->user_id)->sum('amount');
                    $userBalance["total_payout_formatted"] = $userBalanceModel->confirmed_payout_amount . ' USD';
                } else {
                    $availableAmountField = 'available_amount_' . strtolower($memberCurrency->iso_code);
                    $confirmedAmountField = 'confirmed_amount_' . strtolower($memberCurrency->iso_code);
                    $pendingAmountField = 'pending_amount_' . strtolower($memberCurrency->iso_code);
                    $confirmedPayoutAmountField = 'confirmed_payout_amount_' . strtolower($memberCurrency->iso_code);
                    $confirmedBonusField = 'confirmed_bonus_' . strtolower($memberCurrency->iso_code);
                    $pendingBonusField = 'pending_bonus_' . strtolower($memberCurrency->iso_code);
                    $confirmedCashbackField = 'confirmed_cashback_' . strtolower($memberCurrency->iso_code);
                    $pendingCashbackField = 'pending_cashback_' . strtolower($memberCurrency->iso_code);

                    $userBalance["balance_formatted"] = ($userBalanceModel->$availableAmountField + $userBalanceModel->$pendingAmountField) . ' ' . $memberCurrency->iso_code;
                    $userBalance["pending_formatted"] = ($userBalanceModel->$pendingAmountField) . ' ' . $memberCurrency->iso_code;
                    $userBalance["available_formatted"] = $userBalanceModel->$availableAmountField . ' ' . $memberCurrency->iso_code;
                    $userBalance["bonus_formatted"] = ($userBalanceModel->$confirmedBonusField + $userBalanceModel->$pendingBonusField) . ' ' . $memberCurrency->iso_code;
                    $userBalance["cashback_formatted"] = ($userBalanceModel->$confirmedCashbackField) . ' ' . $memberCurrency->iso_code;
                    $userBalance["reward_formatted"] = $userBalanceModel->$confirmedBonusField . ' ' . $memberCurrency->iso_code;

                    $userBalance["total_earned"] = $userBalanceModel->$confirmedCashbackField + $userBalanceModel->$confirmedBonusField;
                    $userBalance["total_earned_formatted"] = $userBalance["total_earned"] . ' ' . $memberCurrency->iso_code;
                    $userBalance["total_payout_formatted"] = $userBalanceModel->$confirmedPayoutAmountField . ' ' . $memberCurrency->iso_code;
                    $userBalance["total_unwithdrawn_formatted"] =  UserExpiredAvailableAmount::where('user_id', $user->user_id)->sum('amount_' . strtolower($memberCurrency->iso_code));
                }

                $userBalance["pending"] = $userBalanceModel->pending_amount;
                $userBalance["available"] = $userBalanceModel->available_amount;
                $userBalance["bonus"] = $userBalanceModel->confirmed_bonus + $userBalanceModel->pending_bonus;
                $userBalance["cashback"] = $userBalanceModel->confirmed_cashback + $userBalanceModel->pending_cashback;
                $userBalance["reward"] = $userBalanceModel->confirmed_bonus;
            }
            $userArray['balance'] =  $emptybalance;
            if (!is_null($userBalanceModel)) {
                $DeclinedPayoutAmount=self::getDeclinedPayoutAmount($user);

                $userArray['balance']['cashback'] = [
                    "pending" =>$userBalanceModel->pending_cashback,
                    "confirmed" =>$userBalanceModel->confirmed_cashback,
                    "declined" =>$DeclinedPayoutAmount['cashback']
                ];
                $userArray['balance']['reward'] = [
                    "pending" =>$userBalanceModel->pending_bonus,
                    "confirmed" =>$userBalanceModel->confirmed_bonus,
                    "declined" =>$DeclinedPayoutAmount['reward']
                ];
                $userArray['balance']['paid'] = ["amount" =>$userBalanceModel->confirmed_payout_amount];
                $userArray['balance']['total'] = [
                    "pending" =>$userBalanceModel->pending_amount,
                    "confirmed" =>$userBalanceModel->confirmed_amount,
                    "declined" =>$DeclinedPayoutAmount['total'],
                    "paid" =>$userBalanceModel->confirmed_payout_amount];
            }

            $userArray['user_balance'] = $userBalance;

            if($user->is_merchant){
                // calculate total sub- account balance
                $userArray['totalbalance_moderators']=$emptybalance;
                $moderators = $user->moderators ;
                foreach($moderators  as $subuser){
                    $userBalanceModer = UsersBalance::where('user_id', $subuser->user_id)->first();
                    $moderArray['balance']=$emptybalance;
                    if (!is_null($userBalanceModer)) {
                        $DeclinedPayoutAmount=self::getDeclinedPayoutAmount($user);

                        $moderArray['balance']['cashback'] = [
                            "pending" =>$userBalanceModer->pending_cashback,
                            "confirmed" =>$userBalanceModer->confirmed_cashback,
                            "declined" =>$DeclinedPayoutAmount['cashback']
                        ];
                        $moderArray['balance']['reward'] = [
                            "pending" =>$userBalanceModer->pending_bonus,
                            "confirmed" =>$userBalanceModer->confirmed_bonus,
                            "declined" =>$DeclinedPayoutAmount['reward']
                        ];
                        $moderArray['balance']['paid'] = ["amount" =>$userBalanceModer->confirmed_payout_amount];
                        $moderArray['balance']['total'] = [
                            "pending" =>$userBalanceModer->pending_amount,
                            "confirmed" =>$userBalanceModer->confirmed_amount,
                            "declined" =>$DeclinedPayoutAmount['total'],
                            "paid" =>$userBalanceModer->confirmed_payout_amount];
                    }

                    $userArray['totalbalance_moderators']['cashback']['pending']+= $moderArray['balance']['cashback']['pending']  ;
                    $userArray['totalbalance_moderators']['cashback']['confirmed']+= $moderArray['balance']['cashback']['confirmed']  ;
                    $userArray['totalbalance_moderators']['cashback']['declined']+= $moderArray['balance']['cashback'] ['declined']  ;

                    $userArray['totalbalance_moderators']['reward']['pending']+=$moderArray['balance']['reward']['pending']  ;
                    $userArray['totalbalance_moderators']['reward']['confirmed']+=$moderArray['balance']['reward']['confirmed']  ;
                    $userArray['totalbalance_moderators']['reward']['declined']+=$moderArray['balance']['reward'] ['declined']  ;

                    $userArray['totalbalance_moderators']['paid']['amount']+=$moderArray['balance']['paid']['amount'] ;

                    $userArray['totalbalance_moderators']['total']['pending']+=$moderArray['balance']['total']['pending'] ;
                    $userArray['totalbalance_moderators']['total']['confirmed']+=$moderArray['balance']['total']['confirmed'] ;
                    $userArray['totalbalance_moderators']['total']['declined']+=$moderArray['balance']['total']['declined'] ;
                    $userArray['totalbalance_moderators']['total']['paid']+=$moderArray['balance']['total']['paid'] ;
                }


                // add sub account balance to merchant balance

                $userArray['totalbalance_moderators']['cashback']['pending']+= $userArray['balance']['cashback']['pending']  ;
                $userArray['totalbalance_moderators']['cashback']['confirmed']+= $userArray['balance']['cashback']['confirmed']  ;
                $userArray['totalbalance_moderators']['cashback']['declined']+= $userArray['balance']['cashback'] ['declined']  ;

                $userArray['totalbalance_moderators']['reward']['pending']+=$userArray['balance']['reward']['pending']  ;
                $userArray['totalbalance_moderators']['reward']['confirmed']+=$userArray['balance']['reward']['confirmed']  ;
                $userArray['totalbalance_moderators']['reward']['declined']+=$userArray['balance']['reward'] ['declined']  ;

                $userArray['totalbalance_moderators']['paid']['amount']+=$userArray['balance']['paid']['amount'] ;

                $userArray['totalbalance_moderators']['total']['pending']+=$userArray['balance']['total']['pending'] ;
                $userArray['totalbalance_moderators']['total']['confirmed']+=$userArray['balance']['total']['confirmed'] ;
                $userArray['totalbalance_moderators']['total']['declined']+=$userArray['balance']['total']['declined'] ;
                $userArray['totalbalance_moderators']['total']['paid']+=$userArray['balance']['total']['paid'] ;
            }






           // dd($userArray['balance'], $userArray['totalbalance_moderators']);
        }
        return $userArray;
    }

    public static function getDeclinedPayoutAmount($user)
    {

        $amts = $user->payouts()->whereIn('status', ['declined'])->selectRaw('SUM(amount) amount, SUM(cashback_amount) cashback, SUM(reward_amount) reward')->first()->toArray();
        $declined_amounts['cashback'] = $amts['cashback'] + 0;
        $declined_amounts['reward'] = $amts['reward'] + 0;
        $declined_amounts['total'] = $amts['cashback'] + $amts['reward'] ;
        return $declined_amounts;
    }


    public function getExportHeaders() : array
    {
        return [
            'User ID' => 'users.user_id',
            'First Name' => 'users.first_name',
            'Last Name' => 'users.last_name',
            'Email' => 'users.email',
            'Region' => 'users.region_code',
            'Country' => 'users.country_code',
            'Platform' => 'users.platform',
            'Created At' => 'users.created_at',
            'Is Merchant' => DB::raw("IF(`users`.`is_merchant`, 'Yes', 'No')"),
            'Lang' => 'users.user_lang',
            'Sign Up Via' => 'users.signup_via'
        ];
    }


    public static function formatBalanceForWalletPage(array $balance, $memberCurrency): array
    {
        $dataFormatted = [];
        foreach ($balance as $key => $value) {
            $dataFormatted[$key] = round($value * $memberCurrency->conversion_rate, 2);
            $dataFormatted[$key . '_formatted'] = self::currencyValueFormatted($value * $memberCurrency->conversion_rate, $memberCurrency);
        }

        return $dataFormatted;
    }

    private static function currencyValueFormatted($value, $currency): string
    {
        $value = round($value, 2);
        $formattedValue = "{$value} {$currency->symbol}";
        if ($currency->display_as == 'prefix')
            $formattedValue = "{$currency->symbol} {$value}";
        return $formattedValue;
    }


    /**
     * @return array
     */
    public static function getBalanceFormatted($user): array
    {
        $balanceB =  self::getBalance($user);
        $balanceB['cashback']['total'] = ($balanceB['cashback']['pending'] ?? 0) + ($balanceB['cashback']['confirmed'] ?? 0);
        $balanceB['cashback']['available'] = ($balanceB['cashback']['confirmed'] ?? 0) - ($balanceB['paid']['cashback'] ?? 0);
        $balanceB['reward']['total'] = ($balanceB['reward']['pending'] ?? 0) + ($balanceB['reward']['confirmed'] ?? 0);
        $balanceB['reward']['available'] = ($balanceB['reward']['confirmed'] ?? 0) - ($balanceB['paid']['reward'] ?? 0);
        $balanceB['available'] = $user->confirmed_balance;
        $memberCurrency = $user->getUserCurrency();
        foreach ($balanceB as $key => $valueTypes) {
            if (is_array($valueTypes)) {
                foreach ($valueTypes as $type => $valueType) {
                    $balanceB[$key][$type] = round($valueType * $memberCurrency->conversion_rate, 2);
                    $balanceB[$key]["{$type}_formatted"] = self::currencyValueFormatted($valueType * $memberCurrency->conversion_rate, $memberCurrency);
                }
            } else {
                $balanceB[$key] = round($valueTypes * $memberCurrency->conversion_rate, 2);
                $balanceB["{$key}_formatted"] = self::currencyValueFormatted($valueTypes * $memberCurrency->conversion_rate, $memberCurrency);
            }
        }
        return $balanceB;
    }




    /**
     * @return array
     */
    public static function getBalance($user): array
    {
        return $user->getBalances();
    }
}
