<?php

namespace App\Http\Controllers\user;

use App\Http\Controllers\Controller;
use App\Http\Services\PaymentServices;
use App\Models\PaymentMethod;
use App\Models\Purchase;
use App\Models\User;
use App\Models\Deposit; 
use App\Models\Setting;
use App\Models\UserLedger;
use App\Models\Withdrawal;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;

/**
 * Laravel/Symfony Developer
 * Name: bukar mai 
 * Telegram: @MB_TECH_Admin
 * Hire me via Telegram: @MB_TECH_Admin
 */
class WithdrawController extends Controller
{
    /**
     * Helper function to check if the user has already withdrawn today (Asia/Manila time).
     * Resets daily at 12:00 AM.
     */
    protected function hasAlreadyWithdrawnToday($userId)
    {
        // Get the start of today (12:00 AM) specifically in Asia/Manila timezone
        $startOfDayManila = Carbon::now('Asia/Manila')->startOfDay();

        // Convert that specific time instance to UTC (or your application's DB timezone) for accurate matching
        $startOfDayInDbTimezone = $startOfDayManila->setTimezone(config('app.timezone', 'UTC'));

        return Withdrawal::where('user_id', $userId)
            ->where('created_at', '>=', $startOfDayInDbTimezone)
            // Optional: Include this if rejected withdrawals shouldn't block their daily attempt
            ->whereIn('status', ['pending', 'approved']) 
            ->exists();
    }

    public function withdraw()
    {
        if (Auth::user()->gateway_method == null && Auth::user()->gateway_address == null) {
            return redirect()->route('user.bank');
        }
        return view('app.main.withdraw.index');
    }

    public function usdt_withdraw()
    {
        return view('app.main.withdraw.usdt');
    }

    public function withdrawConfirmSubmit(Request $request, PaymentServices $payment)
    {
        $validate = Validator::make($request->all(), [
            'amount' => 'required|numeric'
        ]);
        if ($request->amount == '' || $request->amount < 1) {
            return back()->with('error', 'Withdraw Amount required.');
        }

        if (Auth::user()->gateway_method == null && Auth::user()->gateway_address == null) {
            return back()->with('success', 'Please setup your bank');
        }
        
        $user = User::find(\auth()->user()->id);

        // --- ONCE A DAY LIMIT CHECK ---
        if ($this->hasAlreadyWithdrawnToday($user->id)) {
            return redirect()->back()->with('error', 'You can only withdraw once a day. Daily limit resets at 12:00 AM Philippines time.');
        }

        $setting = Setting::first();

        /*/Check user payment or not
        $payments = Deposit::where('user_id', $user->id)->where('status', 'approved')->get();
        if ($payments->count() < 1) {
            return redirect()->back()->with('success', "You can't withdraw before deposit");
        }*/
        
        // Check if user has invest
        $invest1 = Purchase::where('user_id', $user->id)->first();
        if (!$invest1) {
            return redirect()->back()->with('error', "You need to invest before you withdraw");
        }

        // Verify Payment Method
        $paymenMethod = PaymentMethod::where('tag', $setting->auto_transfer_default)->first();

        if (!$paymenMethod) {
            return redirect()->back()->with('error', "You can't withdraw now, Payment method not available");
        }

        // Verify if Withdraw Allowed
        if ($setting->open_transfer != 1) {
            return redirect()->back()->with('error', "You can't withdraw now, Service not available. Try again later.");
        }

        $status_id = 'pending';
        $status_text = 'Withdraw under review it we take within 5 minutes or less';
        $reference = rand(00000,99999);

        if ($request->amount <= $user->balance) {
            // Note: Fixed minor bugs here referencing undefined variables $maximum_withdraw/$minimum_withdraw
            if ($request->amount >= setting('minimum_withdraw')) {
                if ($request->amount <= setting('maximum_withdraw')) {
                    $charge = 0;
                    if (setting('withdraw_charge') > 0) {
                        $charge = ($request->amount * setting('withdraw_charge')) / 100;
                    }

                    // Debit Wallet
                    $debit_wallet = debit_user_wallet($user->id, 2, 'NGN', $request->amount);

                    if($debit_wallet['status'] == false){
                        return redirect()->back()->with('error', $debit_wallet['message']);
                    }

                    $finalAmount = $request->amount - $charge;

                    // Auto Payout
                    if($setting->auto_transfer) {
                        // Transfer Payment
                        $transferPayment = $payment->payout($reference, "NGN", $finalAmount, $setting->auto_transfer_default, $user->gateway_method, $user->gateway_address, $user->realname);

                        // Exception
                        if($transferPayment['status'] == false) {
                            // Refund Amount
                            credit_user_wallet($user->id, 2, 'NGN', $request->amount);
                            return redirect()->back()->with("error", $transferPayment['message']);
                        }

                        $status_id = 'approved';
                        $status_text = 'Your withdraw request has been approved';
                    }

                    $account_info = [
                        'bank_account' => $user->gateway_address,
                        'full_name' => $user->realname,
                        'bank_name' => $user->bank_name,
                        'bank_code' => $user->gateway_method,
                    ];

                    //Withdraw
                    $withdrawal = new Withdrawal();
                    $withdrawal->user_id = $user->id;
                    $withdrawal->method_name = $paymenMethod ? $paymenMethod->name : '---';
                    $withdrawal->trx = $reference;
                    $withdrawal->account_info = json_encode($account_info);
                    $withdrawal->number = $user->gateway_address;
                    $withdrawal->amount = $request->amount;
                    $withdrawal->currency = 'PHP';
                    $withdrawal->charge = $charge;
                    $withdrawal->oid = 'W-'.rand(000000,999999).rand(000000,999999).rand(000000,999999);
                    $withdrawal->final_amount = $finalAmount;
                    $withdrawal->status = $status_id;

                    //User Ledger
                    if ($withdrawal->save()) {
                        $ledger = new UserLedger();
                        $ledger->user_id = $user->id;
                        $ledger->reason = 'withdraw_request';
                        $ledger->perticulation = 'Your withdraw request status is pending please wait for admin approval or communication with us.';
                        $ledger->amount = $request->amount;
                        $ledger->debit = $request->amount - $charge;
                        $ledger->status = 'pending';
                        $ledger->date = date('d-m-Y H:i');
                        $ledger->save();
                    }
                    return back()->with('success', 'Withdraw send successfully.');
                } else {
                    return back()->with('error', 'Maximum Withdraw ' . price(setting('maximum_withdraw')));
                }
            } else {
                return back()->with('error', 'Minimum Withdraw ' . price(setting('minimum_withdraw')));
            }
        } else {
            return back()->with('error', 'Your sufficient balance is low.');
        }
    }

    public function withdrawConfirmSubmitUSDT(Request $request)
    {
        $validate = Validator::make($request->all(), [
            'amount' => 'required|numeric'
        ]);
        if ($validate->fails()) {
            return back()->with('error', $validate->errors());
        }

        if (!Auth::user()->usdt_password || !Auth::user()->usdt_number || !Auth::user()->usdt_name) {
            return back()->with('success', 'Please setup your bank');
        }

        if (Auth::user()->usdt_password != $request->password) {
            return back()->with('success', 'This password not match');
        }

        $user = Auth::user();

        // --- ONCE A DAY LIMIT CHECK ---
        if ($this->hasAlreadyWithdrawnToday($user->id)) {
            return redirect()->back()->with('error', 'You can only withdraw once a day. Daily limit resets at 12:00 AM Manila time.');
        }

        if ($request->amount <= $user->balance) {
            if (($request->amount / setting('rate')) >= setting('minimum_withdraw_usdt')) {
                if (($request->amount / setting('rate')) <= setting('maximum_withdraw_usdt')) {
                    $charge = 0;
                    if (setting('withdraw_charge') > 0) {
                        $charge = setting('withdraw_charge_usdt');
                    }

                    //Update User Balance
                    $balance = $user->balance - $request->amount;
                    User::where('id', $user->id)->update([
                        'balance' => $balance
                    ]);

                    //Withdraw
                    $withdrawal = new Withdrawal();
                    $withdrawal->payment_method_id = Auth::user()->gateway_method;
                    $withdrawal->user_id = $user->id;
                    $withdrawal->number = Auth::user()->usdt_number;
                    $withdrawal->amount = $request->amount;
                    $withdrawal->usdt = ($request->amount / setting('rate')) - $charge;
                    $withdrawal->currency = 'Bangladesh';
                    $withdrawal->charge = $charge;
                    $withdrawal->final_amount = 0;
                    $withdrawal->status = 'pending';

                    //User Ledger
                    if ($withdrawal->save()) {
                        $ledger = new UserLedger();
                        $ledger->user_id = $user->id;
                        $ledger->reason = 'withdraw_request';
                        $ledger->perticulation = 'Your withdraw request status is pending please wait for admin approval or communication with us.';
                        $ledger->amount = $request->amount;
                        $ledger->is_usdt = 'yes';
                        $ledger->debit = $request->amount - $charge;
                        $ledger->status = 'pending';
                        $ledger->date = date('d-m-Y H:i');
                        $ledger->save();
                    }
                    return back()->with('success', 'Withdraw request send successfully. Please wait for admin approval.');
                } else {
                    return back()->with('error', 'Withdraw amount must be less then ' . setting('maximum_withdraw_usdt'));
                }
            } else {
                return back()->with('error', 'Withdraw amount must be greater then ' . setting('minimum_withdraw_usdt'));
            }
        } else {
            return back()->with('error', 'Your sufficient balance is low.');
        }
    }

    public function withdrawPreview()
    {
        $withdraws = Withdrawal::with('payment_method')->where('user_id', Auth::id())->orderByDesc('id')->get();
        return view('app.main.withdraw.withdraw-preview', compact('withdraws'));
    }
}
