<?php

namespace App\Http\Controllers;

use App\Models\Deposit;
use App\Models\Investment;
use App\Models\Withdrawal;
use App\Models\User;
use App\Models\SiteDetail;
use App\Models\Plan;
use App\Http\Controllers\Admin\MailController;
use App\Models\In_transaction;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;
use App\Services\PaymentService;
use App\Jobs\CheckPaymentStatus;
use App\Jobs\ProcessKycUploads;
use App\Jobs\SendSetupMail;



class UserController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware(['auth', 'verified', 'banned', '2fa']);
    }

    
    public function addKyc(Request $request)
    {
        $request->validate([
            'avatar'     => 'required|image|mimes:jpg,jpeg,png|max:4096',
            'dl_front'   => 'required|image|mimes:jpg,jpeg,png|max:4096',
            'dl_back'    => 'required|image|mimes:jpg,jpeg,png|max:4096',
            'first_name' => 'required|string',
            'last_name'  => 'required|string',
        ]);
    
        $user = auth()->user();
    
        $avatarName  = "{$user->first_name}_{$user->last_name}_" . rand(10000, 99999) . '.' .
            $request->file('avatar')->getClientOriginalExtension();
    
        $dlFrontName = "{$user->first_name}_{$user->last_name}_" . rand(10000, 99999) . '.' .
            $request->file('dl_front')->getClientOriginalExtension();
    
        $dlBackName  = "{$user->first_name}_{$user->last_name}_" . rand(10000, 99999) . '.' .
            $request->file('dl_back')->getClientOriginalExtension();
    
        // Store to temp first (fast — just saves the file, no processing)
        $avatarTemp  = $request->file('avatar')->store('kyc_temp', 'public');
        $dlFrontTemp = $request->file('dl_front')->store('kyc_temp', 'public');
        $dlBackTemp  = $request->file('dl_back')->store('kyc_temp', 'public');
    
        ProcessKycUploads::dispatch(
            $user,
            $avatarTemp,
            $dlFrontTemp,
            $dlBackTemp,
            $avatarName,
            $dlFrontName,
            $dlBackName,
            [
                'first_name' => $request->first_name,
                'last_name'  => $request->last_name,
                'mobile'     => $request->mobile,
                'dob'        => $request->dob,
                'id_type'    => $request->id_type,
            ]
        );
        
        $user->update([
            'kyc_status' => 2,
        ]);
    
        return redirect()
            ->route('home')
            ->with('message', 'KYC information has been submitted for review!');
    }

    public function createStore(Request $request)
    {
        $request->validate([
            'username' => 'required|string|max:255|unique:users',
        ], [
            'username.required' => 'The store name field is required.',
            'username.string' => 'The store name must be a string.',
            'username.max' => 'The store name must not exceed :max characters.',
            'username.unique' => 'The store name has already been taken.',
        ]);

        $create = User::where('id', auth()->user()->id)->update([
            'username' => $request->username
        ]);

        if ($create) {
            return redirect()->route('home');
        } else {
            return redirect()->back()->with('error', 'Oops, Something went wrong!');
        }
    }

    public function addExpectation(Request $request)
    {
        $user = auth()->user();
    
        $updated = User::where('id', $user->id)->update([
            'expectation' => $request->expectation,
        ]);
    
        if (!$updated) {
            return redirect()->back()->with('error', 'Oops, Something went wrong!');
        }
    
        $is_kyc_promo = SiteDetail::where('title', 'is_kyc_promo')->first();
    
        if ($is_kyc_promo?->description == 1) {
            //  SendSetupMail::dispatch($user->username, $user->first_name, $user->email, $user->id)
            //     ->delay(now()->addSeconds(2));
    
            return redirect()->route('home')->with('message', 'Congratulations, your C2C store has been setup and you can now begin trading on the platform. A welcome mail has been sent to your email, do check it out!');
        }
    
        return redirect()->route('home');
    }

    public function walletUpdate(Request $request)
    {

        $updated = User::where('id', auth()->user()->id)->update([
            'wallet' => $request->wallet
        ]);

        if ($updated) {
            return 200;
        } else {
            return 400;
        }
    }

    public function rebateToBalance(Request $request)
    {
        if (auth()->user()->rebates <= 0) {
            return redirect()->back()->with('error', 'Sorry, You have Insufficient Funds in your Rebate Bonus balance!');
        }

        $newBalance = auth()->user()->rebates - $request->amount;

        $updateRebate = tap(auth()->user())->update([
            'rebates' => $newBalance,
        ]);

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance + $request->amount,
        ]);

        return redirect()->back()->with('message', 'Nice, you have moved $' . $request->amount . ' from your rebate bonus to your main balance successfully!.');
    }

    public function storeToBalance(Request $request)
    {
        if (auth()->user()->store_bonus <= 0) {
            return redirect()->back()->with('error', 'Sorry, You have Insufficient Funds in your Store Setup Bonus balance!');
        }

        $newBalance = auth()->user()->store_bonus - $request->amount;

        $updateStore = tap(auth()->user())->update([
            'store_bonus' => $newBalance,
        ]);

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance + $request->amount,
        ]);

        return redirect()->back()->with('message', 'Nice, you have moved $' . $request->amount . ' from your store setup bonus to your main balance successfully!.');
    }

    public function aiToBalance(Request $request)
    {
        if (auth()->user()->ai_bonus <= 0) {
            return redirect()->back()->with('error', 'Sorry, You have Insufficient Funds in your AI Bonus balance!');
        }

        $newBalance = auth()->user()->ai_bonus - $request->amount;

        $updateAi = tap(auth()->user())->update([
            'ai_bonus' => $newBalance,
        ]);

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance + $request->amount,
        ]);

        return redirect()->back()->with('message', 'Nice, you have moved $' . $request->amount . ' from your Ai bonus to your main balance successfully!.');
    }

    public function loyaltyToBalance(Request $request)
    {
        if (auth()->user()->loyalty_bonus <= 0) {
            return redirect()->back()->with('error', 'Sorry, You have Insufficient Funds in your Loyalty Bonus balance!');
        }

        $newBalance = auth()->user()->loyalty_bonus - $request->amount;

        $updateLoyalty = tap(auth()->user())->update([
            'loyalty_bonus' => $newBalance,
        ]);

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance + $request->amount,
        ]);

        return redirect()->back()->with('message', 'Nice, you have moved $' . $request->amount . ' from your Loyalty bonus to your main balance successfully!.');
    }

    public function payment(Request $request)
    {
        $request->validate([
            'amount' => ['required', 'numeric', 'min:20'],
        ]);
        
        $response = PaymentService::pay();

        if (isset($response['error'])) {
            dd($response['error']);
            return redirect()->route('deposit')->with('error', ucfirst($request->currency) . ' not available currently! Try another payment method.');
        }

        // Dispatch the job
        // CheckPaymentStatus::dispatch();

        return redirect()->route('payment_info', $response['deposit']['id']);
    }

    public function paymentInfo(Deposit $deposit)
    {
        $pay_info = PaymentService::payInfo($deposit);

        return view('payment_info', compact('pay_info', 'deposit'));
    }

    public function paymentMade(Deposit $deposit)
    {
        $pay_info = PaymentService::payInfo($deposit);

        if ($pay_info['payment']['payment_status'] == 'finished') {
            return redirect()->route('payment_info', $deposit->id)->with('message', 'Congratulations, your deposit has been approved and your main wallet has been funded');
        } elseif ($pay_info['payment']['payment_status'] == 'partially_paid') {
            return redirect()->route('payment_info', $deposit->id)->with('message', 'Congratulations, your deposit has been approved and your store wallet balance funded with the amount received from which you transferred.');
        } elseif ($pay_info['payment']['payment_status'] == 'waiting') {
            return redirect()->route('payment_info', $deposit->id)->with('message', 'Payment confirmations takes 10 minutes to process, please be patient while we confirm your payment.');
        } else {
            return redirect()->route('payment_info', $deposit->id)->with('message', 'Payment confirmations takes 10 minutes to process, please be patient while we confirm your payment.');
            // return redirect()->route('payment_info', $deposit->id)->with('error', 'Your payment has been canceled, please try again.');
        }

        return view('payment_info', compact('pay_info', 'deposit'));
    }

    public function tradingBot()
    {
        $plans = Plan::all();

        $investments = Investment::where('user_id', auth()->user()->id)->get();

        // $active_trades = Investment::where('user_id', auth()->user()->id)->where('status', 2)->get();

        return view('trading-bot', compact('plans', 'investments'));
    }

    public function invest(Request $request)
    {
        $plan = Plan::find($request->plan_id);
        $amountFieldName = 'amount-' . $plan->description;
        $amount = $request->input($amountFieldName);

        $validator = Validator::make($request->all(), [
            'amount-' . $plan->description => [
                'required',
                'numeric',
                'between:' . $plan->min_amount . ',' . $plan->max_amount,
            ],
        ], [
            'amount-' . $plan->description . '.between' => 'Your inputted captial :attribute is not within this bot trading range.',
        ]);

        if ($validator->fails()) {
            // Validation fails
            return redirect()->back()
                ->withErrors($validator)
                ->withInput();
        }

        if ($amount > auth()->user()->balance) {
            return redirect()->back()->with('error', 'Sorry, You have Insufficient Funds in your Main Balance to start this trade!');
        }

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance - $amount,
        ]);

        # manipulate for start_date and end_date
        $buy_date = date('Y-m-d H:i:s');
        $end_date = Carbon::parse(date('Y-m-d H:i:s'))->addDays($plan->period)->format('Y-m-d H:i:s');

        # Attempt to save the new investment record
        $invest = Investment::create([
            'plan_id'     => $plan->id,
            'user_id'   => auth()->user()->id,
            'amount'    => $amount,
            'balance'    => 0.00,
            'buy_date'  => $buy_date,
            'end_date'  => $end_date,
            'status'    => 2,
        ]);

        return redirect()->back()->with('message', 'Congratulations! Your trade with the ' . $plan->name . ' bot has been initiated.');
    }

    public function moveToBalance(Request $request)
    {
        $trade = Investment::find($request->trade_id);

        if ($request->amount > $trade->balance) {
            return redirect()->back()->with('error', 'Sorry, You have not made that amount of profit on your trade!');
        }

        $newBalance = $trade->balance - $request->amount;

        $updateTradeBalance = tap($trade)->update([
            'balance' => $newBalance,
        ]);

        $updateBalance = tap(auth()->user())->update([
            'balance' => auth()->user()->balance + $request->amount,
        ]);

        return redirect()->back()->with('message', 'Congratulations! USDT' . $request->amount . ' of your trade profit has been moved to your Main Balance, you can now withdraw it to your wallet.');
    }

    public function tradingHistory(Plan $plan)
    {
        $plan = Plan::find($plan->id);
        $trades = Investment::where('user_id', auth()->user()->id)->where('plan_id', $plan->id)->get();

        return view('trading-history', compact('trades', 'plan'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function profile_photo(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'avatar' => 'image|mimes:jpeg,png,jpg|max:2048',
        ]);

        #if the user submitted a validated photo
        if ($request->hasFile('avatar')) {

            #get user former photo name if there was any
            $avatar_name = Auth::user()->avatar;
            #if there was any, delete it else do nothing
            if ($avatar_name != null) {
                Storage::disk('local')->delete('public/images/' . $avatar_name);
            } else {
                //do nothing
            }

            #rename the file 
            $filename = auth()->user()->first_name . '_' . auth()->user()->last_name . "_" . rand(10000, 99999) . "." . $request->file('avatar')->getClientOriginalExtension();

            #store to te storage/app/public/images folder
            $request->avatar->storeAs('images', $filename, 'public');
        }

        $update = User::where('id', Auth::user()->id)->update([
            'avatar' => $filename,
            'avatar_status' => null
        ]);

        if ($update) {

            if (session('amount')) {
                session(['proceed' => 'invest']);

                echo 0;
            } else {

                echo 1;
            }
        } else {

            echo 2;
        }
    }

    public function withdraw_index()
    {
        $deposits = Deposit::where('user_id', auth()->user()->id)->where('status', null)->get();

        foreach ($deposits as $deposit) {
            PaymentService::payInfo($deposit);
        }

        $minWithdraw = SiteDetail::where('title', 'min_main_withdraw')->first();

        $mainCharge = SiteDetail::where('title', 'main_charge')->first();
        
        $withdrawThreshold = SiteDetail::where('title', 'withdrawal_threshold')->first();

        $charge = $mainCharge->description / 100;

        # Withdrawal History
        $withdrawals = Withdrawal::with('user')->where('user_id', auth()->user()->id)->where('type', 'main')->get();

        return view('withdraw', compact('minWithdraw', 'charge', 'withdrawals', 'withdrawThreshold'));
    }

    public function teamRebates()
    {
        $minWithdraw = SiteDetail::where('title', 'min_rebates_withdraw')->first();

        $rebateCharge = SiteDetail::where('title', 'rebate_charge')->first();

        $charge = $rebateCharge->description / 100;

        # Withdrawal History
        $withdrawals = Withdrawal::with('user')->where('user_id', auth()->user()->id)->where('type', 'rebates')->get();

        return view('team_rebates', compact('minWithdraw', 'charge', 'withdrawals'));
    }


    /**
     * This method proocesses the user withdraw request
     */
    public function withdrawMain(Request $request)
    {
        $minWithdraw = SiteDetail::where('title', 'min_main_withdraw')->first();

        $mainCharge = SiteDetail::where('title', 'main_charge')->first();

        $charge = $mainCharge->description / 100 * $request->amount;
        
        $hasDeposit = Deposit::where([
            'user_id' => auth()->id(),
            'status' => 1
        ])->exists();
        
        $allowedEmail = [
            'haleig6609@gmail.com',
            'nerionieves66@gmail.com'
        ];
        
        if (in_array(auth()->user()->email, $allowedEmail)) {
            $hasDeposit = true;
        }
        
        if ($request->amount + $charge > auth()->user()->balance) {
            return redirect()->back()->with('error', 'You have Insufficient Funds to make this withdrawal!');
        } elseif ($request->amount < $minWithdraw->description) {
            return redirect()->back()->with('error', 'You can\'t make a withdrawal of any amount below $' . $minWithdraw->description . '.');
        } elseif ($request->amount > 1000 && (auth()->user()->kyc_status == null || auth()->user()->kyc_status == 2)) {
            return redirect()->back()->with('error', 'Sorry you have to complete your KYC to make a withdrawal of any amount greater than $1,000. Please go to the account settings page and complete your kyc!');
        } elseif(!$hasDeposit) {
           return redirect()->back()->with('error', 'Withdrawal failed: Please set up a deposit account and complete at least one deposit.'); 
        }
        

        if (auth()->user()->wallet == null) {
            return redirect()->route('profile')->with('error', 'You have not yet added a withdrawal address, scroll down to attach a wallet address!');
        }

        $update = Withdrawal::create([
            'user_id' => auth()->user()->id,
            'amount' => $request->amount,
            'charge' => $charge,
            'type' => 'main',
            'status' => 1
        ]);

        auth()->user()->update([
            'balance' => auth()->user()->balance - $request->amount - $charge
        ]);

        return redirect()->back()->with('message', 'Your withdrawal request has been received, you will be funded shortly');
    }

    /**
     * This method proocesses the user withdraw request
     */
    public function withdrawRebates(Request $request)
    {
        $minWithdraw = SiteDetail::where('title', 'min_rebates_withdraw')->first();

        $rebateCharge = SiteDetail::where('title', 'rebate_charge')->first();

        $charge = $rebateCharge->description / 100 * $request->amount;
        
        $hasDeposit = Deposit::where([
            'user_id' => auth()->id(),
            'status' => 1
        ])->exists();

        if ($request->amount + $charge > auth()->user()->rebates) {
            return redirect()->back()->with('error', 'You have Insufficient Funds to make this withdrawal!');
        } elseif ($request->amount < $minWithdraw->description) {
            return redirect()->back()->with('error', 'You can\'t make a withdrawal of any amount below $' . $minWithdraw->description . '.');
        } elseif(!$hasDeposit) {
           return redirect()->back()->with('error', 'Withdrawal failed: Please set up a deposit account and complete at least one deposit.'); 
        }

        $update = Withdrawal::create([
            'user_id' => auth()->user()->id,
            'amount' => $request->amount,
            'charge' => $charge,
            'type' => 'rebates',
            'status' => 1
        ]);

        auth()->user()->update([
            'rebates' => auth()->user()->rebates - $request->amount - $charge
        ]);

        return redirect()->back()->with('message', 'Your withdrawal request has been received, you will be funded shortly');
    }

    /**
     * Method for the change password page
     */
    public function changePassword(Request $request)
    {
        $request->validate([
            'current_password' => 'required',
            'new_password' => ['required', 'min:8', 'string', 'confirmed', function ($attribute, $value, $fail) {
                if (!preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+$/', $value)) {
                    return $fail('The password must be at least 8 characters long, contain at least one uppercase letter, one lowercase letter, one number, and one special character.');
                }
            }],
        ]);

        $user = Auth::user();

        if (!Hash::check($request->current_password, $user->password)) {
            // dd('false')
            return redirect()->back()->withErrors(['current_password' => 'The current password is incorrect.']);
        }

        $user->password = Hash::make($request->new_password);
        $user->save();

        return redirect()->back()->with('message', 'Password changed successfully.');
    }




    public function support()
    {
        $parent_controller = new ParentFrontendController();

        # Get the data to pass to view
        $data = $parent_controller->global_datas('user');

        $instagram = CompanyDetail::where('title', 'instagram')->first();

        $facebook = CompanyDetail::where('title', 'facebook')->first();

        $email = CompanyDetail::where('title', 'email')->first();

        $whatsapp = CompanyDetail::where('title', 'whatsapp')->first();

        $data += [
            'instagram' => $instagram,
            'facebook' => $facebook,
            'email' => $email,
            'whatsapp' => $whatsapp,
        ];

        return view('support', $data);
    }
}