<?php

namespace App\Http\Controllers\Admin;

use App\Constants\Status;
use App\Models\Deposit;
use App\Models\Gateway;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Gateway\PaymentController;
use App\Models\User;
use App\Models\Plan;
use App\Models\BvLog;
use App\Models\Transaction;
use Illuminate\Http\Request;

class DepositController extends Controller
{
    public function pending()
    {
        $pageTitle = 'Pending Deposits';
        $deposits = $this->depositData('pending');
        return view('admin.deposit.log', compact('pageTitle', 'deposits'));
    }


    public function approved()
    {
        $pageTitle = 'Approved Deposits';
        $deposits = $this->depositData('approved');
        return view('admin.deposit.log', compact('pageTitle', 'deposits'));
    }

    public function successful()
    {
        $pageTitle = 'Successful Deposits';
        $deposits = $this->depositData('successful');
        return view('admin.deposit.log', compact('pageTitle', 'deposits'));
    }

    public function rejected()
    {
        $pageTitle = 'Rejected Deposits';
        $deposits = $this->depositData('rejected');
        return view('admin.deposit.log', compact('pageTitle', 'deposits'));
    }

    public function initiated()
    {
        $pageTitle = 'Initiated Deposits';
        $deposits = $this->depositData('initiated');
        return view('admin.deposit.log', compact('pageTitle', 'deposits'));
    }

    public function deposit()
    {
        $pageTitle = 'Deposit History';
        $depositData = $this->depositData($scope = null, $summery = true);
        $deposits = $depositData['data'];
        $summery = $depositData['summery'];
        $successful = $summery['successful'];
        $pending = $summery['pending'];
        $rejected = $summery['rejected'];
        $initiated = $summery['initiated'];
        return view('admin.deposit.log', compact('pageTitle', 'deposits','successful','pending','rejected','initiated'));
    }

    protected function depositData($scope = null,$summery = false)
    {
        if ($scope) {
            $deposits = Deposit::$scope()->with(['user', 'gateway']);
        }else{
            $deposits = Deposit::with(['user', 'gateway']);
        }

        $deposits = $deposits->searchable(['trx','user:username'])->dateFilter();

        $request = request();
        //vai method
        if ($request->method) {
            $method = Gateway::where('alias',$request->method)->firstOrFail();
            $deposits = $deposits->where('method_code',$method->code);
        }

        if (!$summery) {
            return $deposits->orderBy('id','desc')->paginate(getPaginate());
        }else{
            $successful = clone $deposits;
            $pending = clone $deposits;
            $rejected = clone $deposits;
            $initiated = clone $deposits;

            $successfulSummery = $successful->where('status',Status::PAYMENT_SUCCESS)->sum('amount');
            $pendingSummery = $pending->where('status',Status::PAYMENT_PENDING)->sum('amount');
            $rejectedSummery = $rejected->where('status',Status::PAYMENT_REJECT)->sum('amount');
            $initiatedSummery = $initiated->where('status',Status::PAYMENT_INITIATE)->sum('amount');

            return [
                'data'=>$deposits->orderBy('id','desc')->paginate(getPaginate()),
                'summery'=>[
                    'successful'=>$successfulSummery,
                    'pending'=>$pendingSummery,
                    'rejected'=>$rejectedSummery,
                    'initiated'=>$initiatedSummery,
                ]
            ];
        }
    }

    public function details($id)
    {
        $general = gs();
        $deposit = Deposit::where('id', $id)->with(['user', 'gateway'])->firstOrFail();
        $pageTitle = $deposit->user->username.' requested ' . showAmount($deposit->amount) . ' '. __($general->cur_text);
        $details = ($deposit->detail != null) ? json_encode($deposit->detail) : null;
        return view('admin.deposit.detail', compact('pageTitle', 'deposit','details'));
    }


    public function approve($id)
    {
        $deposit = Deposit::where('id',$id)->where('status',Status::PAYMENT_PENDING)->firstOrFail();

        PaymentController::userDataUpdate($deposit,true);

        $notify[] = ['success', 'Deposit request approved successfully'];

        return to_route('admin.deposit.pending')->withNotify($notify);
    }
    
    public function purchasePlan($user_id,$amount)
    {
        $user = User::where('id',$user_id)->firstOrFail();
        $plan = Plan::where('id','1')->firstOrFail();
        $trx =  getTrx();
       // $amount=amount;

        $oldPlan = $user->plan_id;
        $user->plan_id = $plan->id;
        $user->balance -= $amount;
        $user->total_invest += $amount;
        $user->save();

        $transaction = new Transaction();
        $transaction->user_id = $user->id;
        $transaction->amount = $amount;
        $transaction->trx_type = '-';
        $transaction->details = 'Purchased ' . $plan->name;
        $transaction->remark = 'purchased_plan';
        $transaction->trx = $trx;
        $transaction->post_balance = $user->balance;
        $transaction->save();

        notify($user, 'PLAN_PURCHASED', [
            'plan_name' => $plan->name,
            'price' => showAmount($amount),
            'trx' => $transaction->trx,
            'post_balance' => showAmount($user->balance)
        ]);

        if ($oldPlan == 0) {
            $this->updatePaidCount($user->id);
        }

        if ($plan->bv) {
            $this->updateBv3($amount);
        }

        if ($plan->tree_com > 0) {
      //      $this->treeCommission();
        }

        $this->referralCommission($amount);
        $this->binaryCommission($amount);
    }
    public function updatePaidCount($user_id)
    {
        $user =  User::where('id',$user_id)->firstOrFail();
        while (0 == 0) {
            $upper = User::where('id', $user->pos_id)->first();
            if (!$upper) {
                break;
            }

            $extra = $upper->userExtra;
            if ($user->position == 1) {
                $extra->free_left -= 1;
                $extra->paid_left += 1;
            } else {
                $extra->free_right -= 1;
                $extra->paid_right += 1;
            }
            $extra->save();
            $user = $upper;
        }
    }
    
    public function updateBv3($user_id,$amount)
    {
        $user = User::where('id',$user_id)->firstOrFail();
        $plan=Plan::where('id','1')->firstOrFail();
        $bv = $plan->bv;
        while (0 == 0) {
            $upper = User::where('id', $user->pos_id)->first();
            if (!$upper) {
                break;
            }
            if ($upper->plan_id == 0) {
                $user = $upper;
                continue;
            }

            $bvlog = new BvLog();
            $bvlog->user_id = $upper->id;
            $bvlog->trx_type = '+';
            $extra = $upper->userExtra;
            if ($user->position == 1) {
                $extra->bv_left += $bv;
                $bvlog->position = '1';
            } else {
                $extra->bv_right += $bv;
                $bvlog->position = '2';
            }
            $extra->save();
            $bvlog->amount = $bv;
            $bvlog->inv_amount = $amount;
            $bvlog->details = 'from ' . auth()->user()->username;
            $bvlog->save();

            $user = $upper;
        }
    }
    
     public function referralCommission($user_id,$amount)
    {
        $user =  User::where('id',$user_id)->firstOrFail();
        $referrer = $user->referrer;
        $plan = @$referrer->plan;
        if ($plan) {
            $amount1=$amount;
            $amount = $amount1*$plan->ref_com/100;
            $referrer->balance += $amount;
            $referrer->total_ref_com += $amount;
            $referrer->save();

            $trx =  getTrx();
            $transaction = new Transaction();
            $transaction->user_id = $referrer->id;
            $transaction->amount = $amount;
            $transaction->post_balance = $referrer->balance;
            $transaction->charge = 0;
            $transaction->trx_type = '+';
            $transaction->details = 'Direct referral commission from ' . $user->username;
            $transaction->trx =  $trx;
            $transaction->remark = 'referral_commission';
            $transaction->save();

            notify($referrer, 'REFERRAL_COMMISSION', [
                'amount' => showAmount($amount),
                'username' => $user->username,
                'post_balance' => $referrer->balance,
                'trx' => $trx
            ]);
        }
    }
    
     public function binaryCommission($user_id,$amountt){
         $user = User::where('id',$user_id)->firstOrFail();
         while (0 == 0) {
                $upper = User::where('id', $user->pos_id)->first();
                 if (!$upper) {
                break;
            }
            $amount=$amountt*0.025;
            $usid=$upper->id;
            
            
             $extra = $upper->userExtra;
             $bvleft=$extra->bv_left;
            $bvright=$extra->bv_right;
            
             if ($user->position == 1) {
                 //for bv left increase
                 if($bvright > 0){
                   if( $bvright >= $bvleft){
                         $firstleg=BvLog::where('user_id',$upper->id)->where('position','1')->where('status','0')->where('trx_type','+')->first();
                         $secondleg=BvLog::where('user_id',$upper->id)->where('position','2')->where('status','0')->where('trx_type','+')->first();
                          $sumamount=$firstleg->inv_amount +$secondleg->inv_amount ;
                          $fiveper=$sumamount*0.025;
                         
                         
                         $upper->balance += $fiveper;
                         $upper->total_binary_com += $fiveper;
                         $upper->save();
             
                         $trx = getTrx();
                         $transaction = new Transaction();
                         $transaction->user_id = $upper->id;
                         $transaction->amount = $fiveper;
                         $transaction->post_balance = $upper->balance;
                         $transaction->charge = 0;
                         $transaction->trx_type = '+';
                         $transaction->details = 'Binary commission from '. $firstleg->details .' and '. $secondleg->details;
                         $transaction->remark = 'binary_commission';
                         $transaction->trx =  $trx;
                         $transaction->save();
                         
                         $firstleg->status=1;
                         $firstleg->save();
                         $secondleg->status=1;
                         $secondleg->save();
                   }
                     
                 }
                 
            } else {
              //  for bv right increase
              if($bvleft > 0){
                   if( $bvleft >= $bvright){
                        $firstleg=BvLog::where('user_id',$upper->id)->where('position','1')->where('status','0')->where('trx_type','+')->first();
                        $secondleg=BvLog::where('user_id',$upper->id)->where('position','2')->where('status','0')->where('trx_type','+')->first();
                          $sumamount=$firstleg->inv_amount +$secondleg->inv_amount ;
                          $fiveper=$sumamount*0.025;
                       
                       $upper->balance += $fiveper;
                        $upper->total_binary_com += $fiveper;
                        $upper->save();
            
                        $trx = getTrx();
                        $transaction = new Transaction();
                        $transaction->user_id = $upper->id;
                        $transaction->amount = $fiveper;
                        $transaction->post_balance = $upper->balance;
                        $transaction->charge = 0;
                        $transaction->trx_type = '+';
                        $transaction->details = 'Binary commission from '. $firstleg->details .' and '. $secondleg->details;
                        $transaction->remark = 'binary_commission';
                        $transaction->trx =  $trx;
                        $transaction->save();
                        
                        $firstleg->status=1;
                        $firstleg->save();
                        $secondleg->status=1;
                        $secondleg->save();
                   }
            }
            
            
         }
          $user = $upper;
    }
    }
    
      public function makeInvest2($user, $plan, $amount, $profit, $trx): void
    {
        $invest = new Investment();
        $invest->user_id = $user->id;
        $invest->plan_id = $plan->id;
        $invest->amount = $amount;
        $invest->profit = $profit;
        $invest->maturity = 100;
        $invest->point_in_time = 720;
        $invest->point_in_text = "Monthly";
        $invest->afterward = Carbon::parse(now())->addHours($plan->schedule);
        $invest->status = 1;
        $invest->capital_back = 0;
        $invest->trx = $trx;
        $invest->save();
    }

    public function reject(Request $request)
    {
        $request->validate([
            'id' => 'required|integer',
            'message' => 'required|string|max:255'
        ]);
        $deposit = Deposit::where('id',$request->id)->where('status',Status::PAYMENT_PENDING)->firstOrFail();

        $deposit->admin_feedback = $request->message;
        $deposit->status = Status::PAYMENT_REJECT;
        $deposit->save();

        notify($deposit->user, 'DEPOSIT_REJECT', [
            'method_name' => $deposit->gatewayCurrency()->name,
            'method_currency' => $deposit->method_currency,
            'method_amount' => showAmount($deposit->final_amo),
            'amount' => showAmount($deposit->amount),
            'charge' => showAmount($deposit->charge),
            'rate' => showAmount($deposit->rate),
            'trx' => $deposit->trx,
            'rejection_message' => $request->message
        ]);

        $notify[] = ['success', 'Deposit request rejected successfully'];
        return  to_route('admin.deposit.pending')->withNotify($notify);

    }
}
