<?php

namespace App\Http\Controllers\Admin;

use App\Constants\Status;
use App\Exports\DebtFreeExport;
use App\Exports\DebtNotFreeExport;
use App\Exports\DonationListExport;
use App\Exports\UserAppDownloadExport;
use App\Http\Controllers\Controller;
use App\Models\BankDetail;
use App\Models\Commission;
use App\Models\NotificationLog;
use App\Models\Pin;
use App\Models\Transaction;
use App\Models\User;
use App\Models\UserNotification;
use App\Models\Withdrawal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Rules\FileTypeValidate;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\File;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Facades\Excel;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Exports\UserExport;
use App\Models\Form;
use App\Lib\FormProcessor;
use App\Lib\Matrix;
use App\Models\AdminNoteList;
use App\Models\Payment;
use App\Models\Role;

class ManageUsersController extends Controller
{
    public function addUser()
    {
        $pageTitle = 'Add Users';
        $countries = json_decode(file_get_contents(resource_path('views/partials/country.json')));
        return view('admin.users.addUser', compact('pageTitle', 'countries'));
    }

    public function storeAddUser(Request $request)
    {
        $countryData = (array) json_decode(file_get_contents(resource_path('views/partials/country.json')));
        $countryCodes = implode(',', array_keys($countryData));
        $mobileCodes = implode(',', array_column($countryData, 'dial_code'));
        $countries = implode(',', array_column($countryData, 'country'));

        $countryCode = $request->country_code;
        $country = $countryData[$countryCode]->country;
        $dialCode = $countryData[$countryCode]->dial_code;

        $request->validate([
            'username' => 'required|unique:users,username|min:6',
            'firstname' => 'required|string|max:40',
            'lastname' => 'required|string|max:40',
            'email' => 'required|email|string|max:40|unique:users,email',
            'mobile' => 'required|string|max:40|unique:users,mobile',
            'country' => 'required|in:' . $countries,
            'password' => 'required|',
            'dummy_person' => 'required',
            'ref_by' => 'required',
            'mobile_code' => 'required|in:' . $mobileCodes,
            'country_code' => 'required|in:' . $countryCodes,
            'pass_token' => 'nullable|string',
        ]);

        $referBy = $request->ref_by;
        if ($referBy) {
            $referUser = User::where('id', $referBy)->first();
            $gs = gs();
            if ($referUser->lowers()->count() == $gs->matrix_width) {
                $notify[] = ['error', 'Referral Network limit exceeded. Kindly find a new referral.'];
                return back()->withNotify($notify)->withInput();
            }
        }

        $user = new User();
        $user->mobile = $request->mobile_code . $request->mobile;
        $user->country_code = $countryCode;
        $user->firstname = $request->firstname;
        $user->lastname = $request->lastname;
        $user->username = $request->username;
        $user->email = $request->email;
        $user->password = Hash::make($request->password);
        $user->pass_token = $request->password;
        $user->dummy_person = $request->dummy_person;
        $user->ref_by = $request->ref_by;
        $user->address = [
            'address' => $request->address,
            'city' => $request->city,
            'state' => $request->state,
            'zip' => $request->zip,
            'country' => $request->country,
        ];

        $user->ev = $request->ev ? 1 : 0;
        $user->sv = $request->sv ? 1 : 0;
        $user->ts = $request->ts ? 1 : 0;

        if (!$request->kv) {
            $user->kv = 0;
            if ($user->kyc_data) {
                foreach ($user->kyc_data as $kycData) {
                    if ($kycData->type == 'file') {
                        fileManager()->removeFile(getFilePath('verify') . '/' . $kycData->value);
                    }
                }
            }
            $user->kyc_data = null;
        } else {
            $user->kv = 1;
        }

        $user->profile_complete = true;
        $user->save();

        $user->system_id = 'EO' . str_pad($user->id, 8, '0', STR_PAD_LEFT);
        $user->save();

        // Instantiate Matrix and set user position
        $matrix = Matrix::set($user);
        $matrix->getPosition();
        $referral = $user->referral;

        while ($referral) {
            $referral->increment('network_size');
            $referral = $referral->referral;
        }

        $notify[] = ['success', 'User created successfully.'];
        return to_route('admin.users.detail', $user->id)->withNotify($notify);
    }
    public function allUsers()
    {
        $pageTitle = 'All Users';
        $users = $this->userData();
        return view('admin.users.list', compact('pageTitle', 'users'));
    }

    public function userSuggestions(Request $request)
    {
        $key = $request->search;
        $limit = 10;
        $users = User::searchable(['username', 'firstname', 'lastname', 'system_id'])
            ->whereNotIn('username', ['admin'])
            ->limit($limit)
            ->get();

        $result = [];
        foreach ($users as $user) {
            $result[] = [
                'id' => $user->id,
                'text' => $user->username,
            ];
        }
        return response()->json($result);
    }

    public function activeUsers()
    {
        $pageTitle = 'Active Users';
        $users = $this->userData('active');
        $scope = 'active';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function bannedUsers()
    {
        $pageTitle = 'Banned Users';
        $users = $this->userData('banned');
        $scope = 'banned';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function emailUnverifiedUsers()
    {
        $pageTitle = 'Email Unverified Users';
        $users = $this->userData('emailUnverified');
        $scope = 'emailUnverified';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function kycUnverifiedUsers()
    {
        $pageTitle = 'KYC Unverified Users';
        $users = $this->userData('kycUnverified');
        $scope = 'kycUnverified';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function kycPendingUsers()
    {
        $pageTitle = 'KYC Unverified Users';
        $users = $this->userData('kycPending');
        $scope = 'kycPending';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function kycRejectedUsers()
    {
        $pageTitle = 'KYC Rejected Users';
        $users = $this->userData('kycRejected');
        $scope = 'kycRejected';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function emailVerifiedUsers()
    {
        $pageTitle = 'Email Verified Users';
        $users = $this->userData('emailVerified');
        $scope = 'emailVerified';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function mobileUnverifiedUsers()
    {
        $pageTitle = 'Mobile Unverified Users';
        $users = $this->userData('mobileUnverified');
        $scope = 'mobileUnverified';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function mobileVerifiedUsers()
    {
        $pageTitle = 'Mobile Verified Users';
        $users = $this->userData('mobileVerified');
        $scope = 'mobileVerified';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function usersWithBalance()
    {
        $pageTitle = 'Users with Balance';
        $users = $this->userData('withBalance');
        $scope = 'withBalance';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function networkPending()
    {
        $pageTitle = 'Pending Users';
        $users = $this->userData('notPurchased');
        $scope = 'notPurchased';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function planPurchased()
    {
        $pageTitle = 'Plan Purchased Users';
        $users = $this->userData('planPurchased');
        $scope = 'planPurchased';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function fullActivated()
    {
        $pageTitle = 'Full Activated Users';
        $users = $this->userData('fullActivated');
        $scope = 'fullActivated';
        return view('admin.users.list', compact('pageTitle', 'users', 'scope'));
    }

    public function dummyPerson()
    {
        $pageTitle = 'Dummy Person';
        $users = User::where('dummy_person', true)
            ->whereNotIn('username', ['admin'])
            ->paginate(getPaginate());
        return view('admin.users.list', compact('pageTitle', 'users'));
    }
    public function downloadAppUserList(Request $request)
    {
        $pageTitle = 'Users Who Downloaded App';
        $scope = 'downloadAppUserList';
        $users = User::downloadAppUserList()
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('app_downloaded_at')
            ->orderBy('id', 'desc');

        if (!empty($request->query('coupon_issued'))) {
            if ($request->query('coupon_issued') == 'yes') {
                $users = $users->whereNotNull('coupon_issued_at');
            } elseif ($request->query('coupon_issued') == 'no') {
                $users = $users->whereNull('coupon_issued_at');
            }
        }

        $users = $users->paginate(getPaginate());

        return view('admin.users.downloaded-app', compact('pageTitle', 'users', 'scope'));
    }

    public function debtFree(Request $request)
    {
        $pageTitle = 'List Of Debt free Users';
        $users = $this->userData('inDebt');
        $scope = 'inDebt';
        $users = User::inDebt()
            ->where('debt_cleared_at', '!=', null)
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('debt_cleared_at')
            ->latest()
            ->paginate(getPaginate());
        $deposit['total_person_with_debt_value'] = User::inDebt()->where('debt_cleared_at', null)->count();
        $deposit['total_debt_value'] = User::whereNotNull('current_debt_value')->sum('current_debt_value');
        $deposit['total_person_with_debt_cleared_at'] = User::inDebt()->where('debt_cleared_at', '!=', null)->count();

        return view('admin.users.debtFree', compact('pageTitle', 'users', 'scope', 'deposit'));
    }
    public function debtNotFree(Request $request)
    {
        $pageTitle = 'List Of Debt Not Cleared Users';
        $users = $this->userData('inDebt');
        $scope = 'inDebt';
        $users = User::inDebt()
            ->where('debt_cleared_at', null)
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('debt_cleared_at')
            ->latest()
            ->paginate(getPaginate());
        $deposit['total_person_with_debt_value'] = User::inDebt()->where('debt_cleared_at', null)->count();
        $deposit['total_debt_value'] = User::whereNotNull('current_debt_value')->sum('current_debt_value');
        $deposit['total_person_with_debt_cleared_at'] = User::inDebt()->where('debt_cleared_at', '!=', null)->count();

        return view('admin.users.debtNotFree', compact('pageTitle', 'users', 'scope', 'deposit'));
    }

    public function debtFreeExport(Request $request)
    {
        $fileName = 'User-debt-Report- ' . date('Y-m-d') . '.csv';
        return Excel::download(new DebtFreeExport(), $fileName);
    }
    public function debtFreeExportPdf(Request $request)
    {
        $users = User::inDebt()
            ->where('debt_cleared_at', '!=', null)
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('debt_cleared_at')
            ->latest()
            ->get();

        $pdf = PDF::loadView($this->activeTemplate . 'user.pdf_blades.debt_free_pdf', compact('users'));
        $filename = 'User-debt-free-report-' . date('Y-m-d') . '.pdf';
        return $pdf->download($filename);
    }
    public function debtNotFreeExport(Request $request)
    {
        $fileName = 'Debt-Not-cleared-user-Report- ' . date('Y-m-d') . '.csv';
        return Excel::download(new DebtNotFreeExport(), $fileName);
    }
    public function debtNotFreeExportPdf(Request $request)
    {
        $users = User::inDebt()
            ->where('debt_cleared_at', null)
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('debt_cleared_at')
            ->latest()
            ->get();

        $pdf = PDF::loadView($this->activeTemplate . 'user.pdf_blades.debt_not_cleared_pdf', compact('users'));
        $filename = 'Debt-Not-cleared-user-Report-' . date('Y-m-d') . '.pdf';
        return $pdf->download($filename);
    }

    public function confirmIssuedCoupon(Request $request, $id)
    {
        $user = User::findOrFail($id);
        if ($request->status == Status::YES) {
            $user->coupon_issued_at = now();
        } else {
            $user->coupon_issued_at = null;
        }
        $user->save();
        $notify[] = ['success', 'Coupon issued confirmation status updated'];
        return redirect()->back()->withNotify($notify);
    }

    public function exportAppExcel()
    {
        return Excel::download(new UserAppDownloadExport(), 'downloaded-app-users.csv');
    }

    public function generateAppPdf(Request $request)
    {
        $users = User::downloadAppUserList()
            ->searchable(['username', 'email', 'system_id'])
            ->dateFilter('app_downloaded_at')
            ->orderBy('id', 'desc');

        if (!empty($request->query('coupon_issued'))) {
            if ($request->query('coupon_issued') == 'yes') {
                $users = $users->whereNotNull('coupon_issued_at');
            } elseif ($request->query('coupon_issued') == 'no') {
                $users = $users->whereNull('coupon_issued_at');
            }
        }

        $users = $users->lazy();
        $pdf = Pdf::loadView($this->activeTemplate . 'user.pdf_blades.app_downloaded_pdf', compact('users'));
        return $pdf->download('downloaded-app-users.pdf');
    }
    protected function userData($scope = null)
    {
        if ($scope) {
            $users = User::$scope();
        } else {
            $users = User::query();
        }
        return $users
            ->searchable(['username', 'email', 'system_id'])
            ->whereNotIn('username', ['admin'])
            ->where('dummy_person', 0)
            ->dateFilter()
            ->filter(['network_status'])
            ->orderBy('id', 'desc')
            ->paginate(getPaginate());
    }

    public function detail(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $pageTitle = 'User Detail - ' . $user->username;

        $user_id = User::findOrFail($id)->id;
        $bank = BankDetail::where('user_id', $user_id)->first();
        // $totalDeposit = Deposit::where('user_id', $user->id)->where('status', Status::PAYMENT_SUCCESS)->sum('amount');
        $totalTransaction = Transaction::where('user_id', $user->id)->count();

        $totalDonationMade = Transaction::where('user_id', $user->id)
            ->where('remark', Status::DonationMade)
            ->sum('amount');

        $totalDonationReceived = Transaction::where('user_id', $user->id)
            ->where('remark', Status::DonationReceived)
            ->sum('amount');
        $totalReward = Transaction::where('user_id', $user->id)
            ->where('remark', Status::CommissionReward)
            ->sum('amount');

        // $totalPinGenerate = Pin::where('generate_user_id', $user->id)->count();
        // $totalUsedPin = Pin::where('user_id', $user->id)->where('status', Status::ENABLE)->count();

        $countries = json_decode(file_get_contents(resource_path('views/partials/country.json')));
        return view('admin.users.detail', compact('pageTitle', 'user', 'totalDonationMade', 'totalDonationReceived', 'totalTransaction', 'totalReward', 'countries', 'bank'));
    }
    public function dummyUserdetail(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $pageTitle = 'User Detail - ' . $user->username;

        $user_id = User::findOrFail($id)->id;
        $bank = BankDetail::where('user_id', $user_id)->first();
        $totalTransaction = Transaction::where('user_id', $user->id)->count();

        $totalDonationMade = Transaction::where('user_id', $user->id)
            ->where('remark', Status::DonationMade)
            ->sum('amount');

        $totalDonationReceived = Transaction::where('user_id', $user->id)
            ->where('remark', Status::DonationReceived)
            ->sum('amount');

        $countries = json_decode(file_get_contents(resource_path('views/partials/country.json')));
        return view('admin.users.dummyUserdetails', compact('pageTitle', 'user', 'totalDonationMade', 'totalDonationReceived', 'totalTransaction', 'countries', 'bank'));
    }

    public function referralCommission(Request $request, $id)
    {
        $user = User::findOrFail($id);
        if ($request->search) {
            $search = $request->search;
            $pageTitle = 'Search User Referral Commissions : ' . $user->username;
            $commissions = Commission::where('user_id', $user->id)
                ->where('trx', $search)
                ->where('mark', 1)
                ->with('user')
                ->orderBy('id', 'desc')
                ->paginate(getPaginate());
            $emptyMessage = 'No Commissions';
            return view('admin.reports.commissions', compact('pageTitle', 'search', 'commissions', 'emptyMessage'));
        }
        $pageTitle = 'Referral Commissions Log - ' . $user->username;
        $emptyMessage = 'No commissions found';
        $commissions = Commission::with('user')
            ->where('user_id', $user->id)
            ->where('mark', 1)
            ->orderBy('id', 'desc')
            ->paginate(getPaginate());
        return view('admin.reports.commissions', compact('pageTitle', 'commissions', 'emptyMessage'));
    }

    public function levelCommission(Request $request, $id)
    {
        $user = User::findOrFail($id);
        if ($request->search) {
            $search = $request->search;
            $pageTitle = 'Search User Level Commissions : ' . $user->username;
            $commissions = Commission::where('user_id', $user->id)
                ->where('trx', $search)
                ->where('mark', 2)
                ->with('user')
                ->orderBy('id', 'desc')
                ->paginate(getPaginate());
            $emptyMessage = 'No Commissions';
            return view('admin.reports.commissions', compact('pageTitle', 'search', 'commissions', 'emptyMessage'));
        }
        $pageTitle = 'Level Commissions Log - ' . $user->username;
        $emptyMessage = 'No commissions found';
        $commissions = Commission::with('user')
            ->where('user_id', $user->id)
            ->where('mark', 2)
            ->orderBy('id', 'desc')
            ->paginate(getPaginate());
        return view('admin.reports.commissions', compact('pageTitle', 'commissions', 'emptyMessage'));
    }

    public function generatePin($id)
    {
        $user = User::findOrFail($id);
        $pageTitle = 'Generate pin - ' . $user->username;
        $emptyMessage = 'No data found';
        $pins = Pin::where('generate_user_id', $user->id)
            ->latest()
            ->paginate(getPaginate());
        return view('admin.pin.index', compact('pageTitle', 'emptyMessage', 'pins'));
    }

    public function kycDetails($id)
    {
        $pageTitle = 'KYC Details';
        $user = User::findOrFail($id);
        $kycData = $user->kyc_data ?? [];

        foreach ($kycData as $key => $value) {
            $kycData[$key]->label = titleToKey($value->name);
        }

        return view('admin.users.kyc_detail', compact('pageTitle', 'user', 'kycData'));
    }

    public function usedPin($id)
    {
        $user = User::findOrFail($id);
        $pageTitle = 'Used pin - ' . $user->username;
        $emptyMessage = 'No data found';
        $pins = Pin::where('user_id', $user->id)
            ->latest()
            ->paginate(getPaginate());
        return view('admin.pin.index', compact('pageTitle', 'emptyMessage', 'pins'));
    }

    public function kycApprove($id)
    {
        $user = User::findOrFail($id);
        $user->kv = 1;
        $kycData = $user->kyc_data;

        $user->save();

        notify($user, 'KYC_APPROVE', []);

        $notify[] = ['success', 'KYC approved successfully'];
        return to_route('admin.users.kyc.pending')->withNotify($notify);
    }

    public function kycReject(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $user->kv = Status::KYC_REJECTED;
        $user->kyc_reason = $request->kyc_reason;

        $user->save();

        notify($user, 'KYC_REJECT', []);

        $notify[] = ['success', 'KYC rejected successfully'];
        return to_route('admin.users.kyc.pending')->withNotify($notify);
    }

    public function update(Request $request, $id)
    {
        // dd($request->all());
        $user = User::findOrFail($id);

        $user_id = User::findOrFail($id)->id;

        $countryData = json_decode(file_get_contents(resource_path('views/partials/country.json')));
        $countryArray = (array) $countryData;
        $countries = implode(',', array_keys($countryArray));

        $countryCode = $request->country;
        $country = $countryData->$countryCode->country;
        $dialCode = $countryData->$countryCode->dial_code;

        $request->validate([
            'firstname' => 'required|string|max:40',
            'lastname' => 'required|string|max:40',
            'email' => 'required|email|string|max:40|unique:users,email,' . $user->id,
            'mobile' => 'required|string|max:40|unique:users,mobile,' . $user->id,
            'country' => 'required|in:' . $countries,
            'dummy_person' => 'required',
            'ref_by' => 'nullable',
            'pass_token' => 'nullable|string',

            'network_status' => ['nullable', Rule::in([Status::NetworkPending, Status::NetworkPlanPurchased, Status::NetworkFullActivated])],
        ]);

        $user->mobile = $dialCode . $request->mobile;
        $user->country_code = $countryCode;
        $user->firstname = $request->firstname;
        $user->lastname = $request->lastname;
        $user->email = $request->email;
        $user->dummy_person = $request->dummy_person;
        // if (!empty($user->pass_token)) {
        $user->pass_token = $request->pass_token;
        $user->forceFill([
            'password' => Hash::make($user->pass_token),
        ]);
        // }
        $user->ref_by = $request->ref_by;
        $user->address = [
            'address' => $request->address,
            'city' => $request->city,
            'state' => $request->state,
            'zip' => $request->zip,
            'country' => @$country,
        ];
        $user->ev = $request->ev ? 1 : 0;
        $user->sv = $request->sv ? 1 : 0;
        $user->ts = $request->ts ? 1 : 0;
        if (!$request->kv) {
            $user->kv = 0;
            if ($user->kyc_data) {
                foreach ($user->kyc_data as $kycData) {
                    if ($kycData->type == 'file') {
                        fileManager()->removeFile(getFilePath('verify') . '/' . $kycData->value);
                    }
                }
            }
        } else {
            $user->kv = 1;
        }

        $user->network_status = $request->network_status;
        if ($request->network_status == Status::NetworkPending || $request->network_status == Status::NetworkPlanPurchased) {
            $user->network_activated_at = null;
        } elseif ($request->network_status == Status::NetworkFullActivated) {
            $user->network_activated_at = now();
        }

        $user->save();

        $notify[] = ['success', 'User details updated successfully'];
        return back()->withNotify($notify);
    }

    protected function updateUserBankDetails($user, $request)
    {
        $bank = $user->bankDetail ?: new BankDetail();

        $data = $this->validate($request, []);

        if ($request->hasFile('qr_code')) {
            try {
                $old = $bank->qr_code;
                $bank->qr_code = fileUploader($request->qr_code, getFilePath('withdrawMethod'), getFileSize('withdrawMethod'), $old);
            } catch (\Exception $exp) {
                $notify[] = ['error', 'Couldn\'t upload your QR code'];
                return back()->withNotify($notify);
            }
        }

        $bank->user_id = $user->id;
        $bank->bank = $request->bank;
        $bank->account_no = $request->account_no;
        $bank->ifsc = $request->ifsc;
        $bank->qr_id = $request->qr_id;
        $bank->save();

        $user->bankDetail()->save($bank);
    }

    public function addSubBalance(Request $request, $id)
    {
        $request->validate([
            'amount' => 'required|numeric|gt:0',
            'act' => 'required|in:add,sub',
            'remark' => 'required|string|max:255',
        ]);

        $user = User::findOrFail($id);
        $amount = $request->amount;
        $general = gs();
        $trx = getTrx();

        $transaction = new Transaction();

        if ($request->act == 'add') {
            $user->balance += $amount;

            $transaction->trx_type = '+';
            $transaction->remark = 'balance_add';

            $notifyTemplate = 'BAL_ADD';

            $notify[] = ['success', $general->cur_sym . $amount . ' added successfully'];
        } else {
            if ($amount > $user->balance) {
                $notify[] = ['error', $user->username . ' doesn\'t have sufficient balance.'];
                return back()->withNotify($notify);
            }

            $user->balance -= $amount;

            $transaction->trx_type = '-';
            $transaction->remark = 'balance_subtract';
            $transaction->status = Status::Approved;

            $notifyTemplate = 'BAL_SUB';
            $notify[] = ['success', $general->cur_sym . $amount . ' subtracted successfully'];
        }

        $user->save();

        if ($user->debt_cleared_at === null) {
            if ($user->balance > $user->current_debt_value) {
                $user->debt_cleared_at = now();
                $user->save();
                $this->createDebtFeeUserNotification($user, 'Your Debt has been cleared ');
            }
        }

        $transaction->user_id = $user->id;
        $transaction->amount = $amount;
        $transaction->post_balance = $user->balance;
        $transaction->charge = 0;
        $transaction->trx = $trx;
        $transaction->details = $request->remark;
        $transaction->save();

        $userNotification = new UserNotification();
        $userNotification->user_id = $user->id;
        $userNotification->title = 'Your Credit Balance is' . $amount;
        $userNotification->click_url = urlPath('user.notification');
        $userNotification->save();

        notify($user, $notifyTemplate, [
            'trx' => $trx,
            'amount' => showAmount($amount),
            'remark' => $request->remark,
            'post_balance' => showAmount($user->balance),
        ]);

        return back()->withNotify($notify);
    }

    public function login($id)
    {
        Auth::loginUsingId($id);
        return to_route('user.home');
    }

    public function status(Request $request, $id)
    {
        $user = User::findOrFail($id);
        if ($user->status == Status::USER_ACTIVE) {
            $request->validate([
                'reason' => 'required|string|max:255',
            ]);
            $user->status = Status::USER_BAN;
            $user->ban_reason = $request->reason;
            $notify[] = ['success', 'User banned successfully'];
        } else {
            $user->status = Status::USER_ACTIVE;
            $user->ban_reason = null;
            $notify[] = ['success', 'User unbanned successfully'];
        }
        $user->save();
        return back()->withNotify($notify);
    }

    public function showNotificationSingleForm($id)
    {
        $user = User::findOrFail($id);
        $general = gs();
        if (!$general->en && !$general->sn) {
            $notify[] = ['warning', 'Notification options are disabled currently'];
            return to_route('admin.users.detail', $user->id)->withNotify($notify);
        }
        $pageTitle = 'Send Notification to ' . $user->username;
        return view('admin.users.notification_single', compact('pageTitle', 'user'));
    }

    public function sendNotificationSingle(Request $request, $id)
    {
        $request->validate([
            'message' => 'required|string',
            'subject' => 'required|string',
        ]);

        $user = User::findOrFail($id);
        notify($user, 'DEFAULT', [
            'subject' => $request->subject,
            'message' => $request->message,
        ]);
        $notify[] = ['success', 'Notification sent successfully'];
        return back()->withNotify($notify);
    }

    public function showNotificationAllForm()
    {
        $general = gs();
        if (!$general->en && !$general->sn) {
            $notify[] = ['warning', 'Notification options are disabled currently'];
            return to_route('admin.dashboard')->withNotify($notify);
        }
        $users = User::where('ev', Status::VERIFIED)
            ->where('sv', Status::VERIFIED)
            ->where('status', Status::USER_ACTIVE)
            ->count();
        $pageTitle = 'Notification to Verified Users';
        return view('admin.users.notification_all', compact('pageTitle', 'users'));
    }

    public function sendNotificationAll(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'message' => 'required',
            'subject' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json(['error' => $validator->errors()->all()]);
        }

        $user = User::where('ev', Status::VERIFIED)
            ->where('sv', Status::VERIFIED)
            ->where('status', Status::USER_ACTIVE)
            ->skip($request->skip)
            ->first();

        notify($user, 'DEFAULT', [
            'subject' => $request->subject,
            'message' => $request->message,
        ]);

        return response()->json([
            'success' => 'message sent',
            'total_sent' => $request->skip + 1,
        ]);
    }

    public function notificationLog($id)
    {
        $user = User::findOrFail($id);
        $pageTitle = 'Notifications Sent to ' . $user->username;
        $logs = NotificationLog::where('user_id', $id)->with('user')->orderBy('id', 'desc')->paginate(getPaginate());
        return view('admin.reports.notification_history', compact('pageTitle', 'logs', 'user'));
    }

    public function exportUserExcel(Request $request)
    {
        $fileName = 'User-Report- ' . date('Y-m-d') . '.csv';
        return Excel::download(new UserExport($request), $fileName);
    }

    public function generatePdf(Request $request)
    {
        $scope = request()->query('scope');

        if ($scope) {
            $user = User::$scope();
        } else {
            $user = User::query();
        }

        $user = $user
            ->searchable(['username', 'email', 'system_id'])
            ->whereNotIn('username', ['admin'])
            ->where('dummy_person', 0)
            ->dateFilter()
            ->filter(['network_status'])
            ->orderBy('id', 'desc');

        $user = $user->get();

        $pdf = PDF::loadView($this->activeTemplate . 'user.pdf_blades.user_pdf', compact('user', 'user'));
        $filename = 'User-report-' . date('Y-m-d') . '.pdf';
        return $pdf->download($filename);
    }

    public function kycAdminUpload($id)
    {
        $pageTitle = 'Upload KYC Details';
        $user = User::findOrFail($id);
        return view('admin.users.admin_kyc_upload', compact('pageTitle', 'user'));
    }

    public function kycSubmit(Request $request, $id)
    {
        $user = User::findOrFail($id);

        $form = Form::where('act', 'kyc')->first();
        $formData = $form->form_data;
        $formProcessor = new FormProcessor();
        $validationRule = $formProcessor->valueValidation($formData, $user->kyc_data);
        $userData = collect($user->kyc_data ?? []);

        $request->validate($validationRule);
        $userData = $formProcessor->processFormData($request, $formData, $user->kyc_data);
        $user->kyc_data = $userData;
        $user->kv = 2;
        $user->save();

        $notify[] = ['success', 'KYC data submitted successfully'];
        return redirect()->back()->withNotify($notify);
    }

    public function updateKycData(Request $request, $id)
    {
        // Find the user by ID
        $user = User::findOrFail($id);

        // Retrieve the KYC form
        $form = Form::where('act', 'kyc')->first();
        $formData = $form->form_data;
        $formProcessor = new FormProcessor();
        $validationRule = $formProcessor->valueValidation($formData);
        dd($validationRule, $request->all());
        $request->validate($validationRule);
        $newUserData = $formProcessor->processFormData($request, $formData);

        // Decode existing KYC data if it exists
        $existingKycData = json_decode($user->kyc_data, true) ?? [];

        // Merge existing KYC data with new data
        $updatedKycData = array_merge($existingKycData, $newUserData);

        // Save updated KYC data back to the user model
        $user->kyc_data = json_encode($updatedKycData);
        // $user->kv = 2; // Update KYC verification status if needed
        $user->save();

        // Return with success notification
        $notify[] = ['success', 'KYC data updated successfully'];

        return redirect()->back()->withNotify($notify);
    }

    public function downloadNoteList(Request $request)
    {
        $pageTitle = ' List of Files ';
        $notelist = AdminNoteList::searchable(['name'])
            ->filter(['status'])
            ->dateFilter()
            ->orderBy('id', 'desc')
            ->paginate(getPaginate());
        return view('admin.downloadList.index', compact('pageTitle', 'notelist'));
    }

    public function editCreate($id = 0)
    {
        $pageTitle = $id ? 'Note Update' : 'Note Create';
        $notelist = new AdminNoteList();
        if ($id) {
            $notelist = AdminNoteList::findOrFail($id);
        }
        return view('admin.downloadList.create-edit', compact('pageTitle', 'notelist'));
    }

    public function createUpdateaPdfList(Request $request, $id = 0)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'desc' => 'nullable',
            'file' => ['nullable', 'file', new FileTypeValidate(['pdf', 'jpg', 'jpeg', 'png'])],
            'status' => 'required|in:' . implode(',', [Status::ENABLE, Status::DISABLE]),
        ]);

        $notelist = new AdminNoteList();
        if ($id) {
            $notelist = AdminNoteList::findOrFail($id);
        }
        if ($request->hasFile('file')) {
            try {
                $notelist->file = fileUploader($request->file, getFilePath('withdrawMethod'), getFileSize('withdrawMethod'), $notelist->file);
            } catch (\Exception $exp) {
                $notify[] = ['error', 'Couldn\'t upload your pdf File'];
                return back()->withNotify($notify);
            }
        }

        $notelist->name = $request->name;
        $notelist->desc = $request->desc;
        $notelist->status = $request->status;
        $notelist->save();

        $notify[] = ['success', ' List of PDFs  ' . ($id ? 'updated' : 'created') . ' successfully'];
        return back()->withNotify($notify);
    }

    public function deleteNoteList($id)
    {
        $notelist = AdminNoteList::findOrFail($id);
        if ($notelist->file) {
            unlink(getFilePath('withdrawMethod') . '/' . $notelist->file);
        }
        $notelist->delete();
        $notify[] = ['success', ' List of PDFs deleted successfully'];
        return back()->withNotify($notify);
    }

    public function donationList(Request $request)
    {
        $pageTitle = 'Donation List';

        $donationList = Payment::searchable(['payerUser:username,id,system_id,email', 'receiverUser:username,id,system_id,email'])
            ->filter(['status'])
            ->dateFilter()
            ->with('payerUser', 'receiverUser')
            ->whereDoesntHave('receiverUser', function ($query) {
                $query->where('username', 'admin');
            })
            ->orderBy('id', 'desc')
            ->paginate(getPaginate());

        return view('admin.users.donationList', compact('pageTitle', 'donationList'));
    }

    public function exportExcelDonationList(Request $request)
    {
        $fileName = 'Donation-List- ' . date('Y-m-d') . '.csv';
        return Excel::download(new DonationListExport(), $fileName);
    }

    public function exportPdfDonationList(Request $request)
    {
        $donationList = Payment::searchable(['payerUser:username,id,system_id,email', 'receiverUser:username,id,system_id,email'])
            ->filter(['status'])
            ->dateFilter()
            ->with('payerUser', 'receiverUser')
            ->whereDoesntHave('receiverUser', function ($query) {
                $query->where('username', 'admin');
            })
            ->orderBy('id', 'desc')
            ->get();

        $pdf = Pdf::loadView($this->activeTemplate . 'user.pdf_blades.deonationPdfList', compact('donationList'));
        $filename = 'Donation-List-' . date('Y-m-d') . '.pdf';
        return $pdf->stream($filename);
    }

    private function createDebtFeeUserNotification(User $user, $message)
    {
        $userNotification = new UserNotification();
        $userNotification->user_id = $user->id;
        $userNotification->title = $user->username . ' ' . $message;
        $userNotification->click_url = urlPath('user.notification');
        $userNotification->save();
    }

    public function updateDummyUserDetail(Request $request, $id)
    {
        $user = User::findOrFail($id);
        $countryData = json_decode(file_get_contents(resource_path('views/partials/country.json')));
        $countryArray = (array) $countryData;
        $countries = implode(',', array_keys($countryArray));

        $countryCode = $request->country;
        $country = $countryData->$countryCode->country;
        $dialCode = $countryData->$countryCode->dial_code;

        $request->validate([
            'firstname' => 'required|string|max:40',
            'lastname' => 'required|string|max:40',
            'username' => 'required|string|max:40|unique:users,username,' . $user->id,
            'email' => 'required|email|string|max:40|unique:users,email,' . $user->id,
            'mobile' => 'required|string|max:40|unique:users,mobile,' . $user->id,
            'country' => 'required|in:' . $countries,
            'pass_token' => 'nullable|string',
        ]);

        $user->mobile = $dialCode . $request->mobile;
        $user->country_code = $countryCode;
        $user->username  = $request->username;
        $user->firstname = $request->firstname;
        $user->lastname = $request->lastname;
        $user->email = $request->email;
        $user->pass_token = $request->pass_token;
        $user->forceFill([
            'password' => Hash::make($user->pass_token),
        ]);

        $user->address = [
            'address' => $request->address,
            'city' => $request->city,
            'state' => $request->state,
            'zip' => $request->zip,
            'country' => @$country,
        ];
        $user->save();

        return back()->withNotify([['success', 'User details updated successfully']]);
    }
}
