<?php

namespace App\Http\Controllers\Admin;

use App\Models\Transaction;
use App\Models\TransactionHistory;
use App\Models\Withdrawals;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Wallet;
use Illuminate\Support\Facades\Http;
use KingFlamez\Rave\Facades\Rave as Flutterwave;
use Carbon\Carbon;

class WithdrawalController extends Controller
{
    public function accepted()
    {
        $withdrawlogs = Withdrawals::where('status', 1)->latest()->with(['method','user','currency','merchant','agent'])->paginate(15);
        return view('admin.withdraw.withdraw_all',compact('withdrawlogs'));

    }
    public function allWithdraw()
    {

        $search = request('search');
        $range = request('range');
        $startDate = null;
        $endDate = null;

        // Validate and process date range
        if ($range) {
            $date = explode('-', $range);
            $startDate = trim($date[0] ?? null);
            $endDate = trim($date[1] ?? null);

            try {
                if ($startDate) {
                    $startDate = Carbon::createFromFormat('m/d/Y', $startDate)->format('Y-m-d');
                }
                if ($endDate) {
                    $endDate = Carbon::createFromFormat('m/d/Y', $endDate)->format('Y-m-d');
                }
            } catch (\Exception $e) {
                return back()->with('error', 'Invalid date format. Please use MM/DD/YYYY.');
            }
        }

        // Query the Withdrawals table
        $withdrawlogs = Withdrawals::latest()

            ->when($search, function ($query) use ($search) {
                return $query->where('trx', $search);
            })
            ->when($range, function ($query) use ($startDate, $endDate) {
                return $query->whereDate('created_at', '>=', $startDate)
                    ->whereDate('created_at', '<=', $endDate);
            })
            ->with(['user'])
            ->paginate(15);

        return view('admin.withdraw.withdraw_all', compact('withdrawlogs'));

    }
    public function pendingWithdraw()
    {
        $withdrawlogs = Withdrawals::where('status', 0)->latest()->with(['user'])->paginate(15);
        return view('admin.withdraw.withdraw_all',compact('withdrawlogs'));
    }
    public function failedWithdraw()
    {
        $withdrawlogs = Withdrawals::where('flw_transfer_status', 'FAILED')->latest()->with(['user'])->paginate(15);
        return view('admin.withdraw.withdraw_all',compact('withdrawlogs'));
    }
    public function successfulWithdraw()
    {
        $withdrawlogs = Withdrawals::where('flw_transfer_status', 'SUCCESSFUL')->latest()->with(['user'])->paginate(15);
        return view('admin.withdraw.withdraw_all',compact('withdrawlogs'));
    }
    public function rejected()
    {
        $withdrawlogs = Withdrawals::where('status', 2)->latest()->with(['method','user','currency','merchant','agent'])->paginate(15);
        return view('admin.withdraw.withdraw_all',compact('withdrawlogs'));
    }

    public function withdrawAccept(Withdrawals $withdraw)
    {
        $withdraw->status = 1;
        $withdraw->save();

        if($withdraw->user_id){
            $user = $withdraw->user;

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->user_id;
            $trnx->user_type   = 1;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = $withdraw->charge;
            $trnx->remark      = 'withdraw_money';
            $trnx->type        = '-';
            $trnx->details     = trans('Withdraw money');
            $trnx->save();
        }
        elseif ($withdraw->merchant_id){
            $user = $withdraw->merchant;

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->merchant_id;
            $trnx->user_type   = 2;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = $withdraw->charge;
            $trnx->remark      = 'withdraw_money';
            $trnx->type        = '-';
            $trnx->details     = trans('Withdraw money');
            $trnx->save();
        }
        else {
            $user = $withdraw->agent;

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->agent_id;
            $trnx->user_type   = 3;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = $withdraw->charge;
            $trnx->remark      = 'withdraw_money';
            $trnx->type        = '-';
            $trnx->details     = trans('Withdraw money');
            $trnx->save();
        }

        @mailSend('accept_withdraw',['amount'=>amount($withdraw->amount,$withdraw->currency->type,2), 'method' => $withdraw->withdraw->name,'trnx'=> $trnx->trnx,'curr' => $withdraw->currency->code,'method'=>$withdraw->method->name,'charge'=> amount($withdraw->charge,$withdraw->currency->type,2),'data_time'=> dateFormat($trnx->created_at)], $user);

        return back()->with('success','Withdraw Accepted Successfully');
    }

    public function withdrawRetry($withdrawId)
    {

        $withdraw = Withdrawals::where('trx',$withdrawId)->where('flw_transfer_status','FAILED')->first();
        if($withdraw){
            $retry= Flutterwave::transfers()->retry($withdraw->flw_transfer_id);

            if ($retry) {
                if ($retry['status'] == 'success') {
                    $data = $retry['data'];
                    $withdraw->status = 0;
                    $withdraw->flw_transfer_id= $data['id'];
                    $withdraw->flw_transfer_status = $data['status'];
                    $withdraw->flw_complete_message = $data['complete_message'];
                    $withdraw->flw_trans_charges = $data['fee'];

                    $withdraw->save();

                    return back()->with('success', 'Withdraw Retry Successfully');
                } else {


                    return back()->with('error', 'Operation Failed!! Partner Error');
                }
            }else{
                return back()->with('error', 'Operation Failed');
            }


        }

    }
    public function withdrawRequery($withdrawId)
    {

        $withdraw = Withdrawals::where('trx', $withdrawId)->first();

        if ($withdraw) {

            $transfer = Flutterwave::transfers()->fetch($withdraw->flw_transfer_id);

            if ($transfer) {
                if ($transfer['status'] == 'success') {
                    $data = $transfer['data'];

                    $transaction = TransactionHistory::where('transaction_ref', $withdraw->trx)->first();
                    if ($transfer['data']['status'] === 'SUCCESSFUL') {


                        $withdraw->flw_transfer_status = $data['status'];
                        $withdraw->flw_complete_message = $data['complete_message'];
                        $withdraw->flw_is_approved = $data['is_approved'];
                        $withdraw->status = 1;
                       if($transaction) {
                           $transaction->status = 'success';
                           $transaction->status_reason = $withdraw->flw_complete_message;
                       }

                        // update transfer status to successful in your db

                    } else if ($transfer['data']['status'] === 'FAILED') {
                        // update transfer status to failed in your db
                        $withdraw->flw_transfer_status = $data['status'];
                        $withdraw->flw_complete_message = $data['complete_message'];
                        $withdraw->flw_is_approved = $data['is_approved'];
                        $withdraw->status = 2;
                           if($transaction) {
                               $transaction->status = 'failed';
                               $transaction->status_reason = $withdraw->flw_complete_message;
                           }
                        // revert customer balance back
                    } else if ($transfer['data']['status'] === 'PENDING') {
                        // update transfer status to pending in your db
                        $withdraw->flw_transfer_status = $data['status'];
                        $withdraw->flw_complete_message = $data['complete_message'];
                        $withdraw->flw_is_approved = $data['is_approved'];

                    }
                    if($transaction) {
                        $transaction->save();
                    }
                    $withdraw->save();
                    return back()->with('success', 'Operation Successfully');
                }

            } else {
                return back()->with('error', 'Operation Failed. Partner Error');

            }
        }else{
            return back()->with('error', 'Operation Failed');
        }
    }

    public function withdrawRefund($withdrawId)
    {

        $withdraw = Withdrawals::where('trx', $withdrawId)->where('flw_transfer_status', 'FAILED')->first();
        if ($withdraw) {
            TransactionHistory::create([
                'descriptions' =>'Refund of failed withdraw with Transaction Reference of  '.$withdraw->trx .'('.toMoney($withdraw->amount).') to your wallet',
                'trade_id' => null,
                'request_id' =>"R2TREF-".$withdraw->trx,
                'tradedcard_details_id' => null,
                'transaction_ref' =>'R2TREF-'.$withdraw->trx,
                'user_id' => $withdraw->user_id,
                'amount' =>$withdraw->amount,
                'exchange_rate'=>1,
                'transaction_amount_in_usd'=>1,
                'transaction_type' => 'Credit',
                'created_by' => auth()->user()->id,
                'source' => 'Withdraw',
                'status' => 'success',
                'status_at' => now(),
                'status_by' => auth()->user()->id,
                'status_reason' => 'Refund Successful' ,

                'rate' => null,
                'currency' => "NGN",
            ]);
            $userWallet = Wallet::where('user_id', $withdraw->user_id)->first();
            if($userWallet){
                $userWallet->balance += $withdraw->amount+$withdraw->charge;
                $userWallet->save();
            }
            $withdraw->status='3';
            $withdraw->flw_complete_message='Refund';
            $withdraw->save();

            return back()->with('success','Operation Successfully');


        }else{
            return back()->with('error','Operation Failed');
        }
    }


    public function withdrawReject(Request $request, Withdrawals $withdraw)
    {
        $request->validate(['reason_of_reject' => 'required']);

        $withdraw->status = 2;
        $withdraw->reject_reason = $request->reason_of_reject;
        $withdraw->save();

        if($withdraw->user_id){
            $user = $withdraw->user;
            $wallet = Wallet::where('user_id',$withdraw->user_id)->where('user_type',1)->where('currency_id',$withdraw->currency_id)->firstOrFail();

            $wallet->balance += $withdraw->total_amount;
            $wallet->save();

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->user_id;
            $trnx->user_type   = 1;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = 0;
            $trnx->remark      = 'withdraw_reject';
            $trnx->type        = '+';
            $trnx->details     = trans('Withdraw request rejected');
            $trnx->save();

        } elseif ($withdraw->merchant_id){
            $user = $withdraw->merchant;
            $wallet = Wallet::where('user_id',$withdraw->merchant_id)->where('user_type',2)->where('currency_id',$withdraw->currency_id)->firstOrFail();

            $wallet->balance += $withdraw->total_amount;
            $wallet->save();

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->merchant_id;
            $trnx->user_type   = 2;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = 0;
            $trnx->remark      = 'withdraw_reject';
            $trnx->type        = '+';
            $trnx->details     = trans('Withdraw request rejected');
            $trnx->save();

        } else {
            $user = $withdraw->agent;
            $wallet = Wallet::where('user_id',$withdraw->agent_id)->where('user_type',3)->where('currency_id',$withdraw->currency_id)->firstOrFail();

            $wallet->balance += $withdraw->total_amount;
            $wallet->save();

            $trnx              = new Transaction();
            $trnx->trnx        = str_rand();
            $trnx->user_id     = $withdraw->agent_id;
            $trnx->user_type   = 3;
            $trnx->currency_id = $withdraw->currency->id;
            $trnx->amount      = $withdraw->amount;
            $trnx->charge      = 0;
            $trnx->remark      = 'withdraw_reject';
            $trnx->type        = '+';
            $trnx->details     = trans('Withdraw request rejected');
            $trnx->save();

        }

        @mailSend('reject_withdraw',['amount'=> amount($withdraw->amount,$withdraw->currency->type,2), 'method' => $withdraw->withdraw->name,'trnx'=> $trnx->trnx,'curr' => $withdraw->currency->code,'method'=>$withdraw->method->name,'reason'=>$withdraw->reject_reason,'data_time'=> dateFormat($trnx->created_at)],$user);

        return back()->with('success','Withdraw Rejected Successfully');
    }
}
