<?php

namespace App\Http\Controllers;

use App\Classes\MikrotikService\Mikrotik;
use Carbon\Carbon;
use App\Models\Pop;
use App\Models\User;
use App\Models\Token;
use App\Services\Sms;
use App\Models\Client;
use App\Jobs\SendSmsJob;
use App\Models\Employee;
use App\Models\Reseller;
use App\Models\TokenCat;
use App\Models\User_log;
use App\Models\TokenCode;
use Illuminate\Support\Str;
use App\Classes\tokenSerial;
use Illuminate\Http\Request;
use App\Classes\Notification;
use App\Classes\SMS\TokenSms;
use App\Classes\TokenClass;
use App\Exports\SearchTokenExport;
use App\Models\Clientsinfo;
use App\Models\TokenSource;
use Illuminate\Support\Facades\DB;
use Brian2694\Toastr\Facades\Toastr;
use Exception;
use Maatwebsite\Excel\Facades\Excel;
use App\Facades\RadPostAuthFacade;


class SupportController extends Controller
{

    public function __construct() {}

    public function index()
    {

        $token = Token::list()->where('status', '=', 'Active');

        $id = auth()->id();
        if (auth()->user()->hasRole('Admin')) {

            $list = $token;
        } elseif (auth()->user()->hasRole(['Reseller Admin', 'Reseller', 'Reseller Technician'])) {
            $pop = Pop::poplist();
            $list = $token->whereHas('clients', function ($query) use ($pop) {
                $query->whereIn('pop_id', $pop->pluck('id'));
            });
        } elseif (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {
            $pop = Pop::poplist();
            $list = $token->whereHas('clients', function ($query) use ($pop) {
                $query->whereIn('pop_id', $pop->pluck('id'));
            });
        } else {
            $list = $token;
        }

        return view('token.index', [
            'token' => $list->paginate(1000),
            'reseller' => Reseller::resellerList()->get(),
        ]);
    }

    public function assignIndex()
    {
        // $token = DB::table('tokens')
        //     ->join('token_cats', 'tokens.tokenCategory', '=', 'token_cats.id')
        //     ->join('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
        //     ->join('clients', 'tokens.clientId', '=', 'clients.id')
        //     ->leftjoin('users', 'tokens.createdBy', '=', 'users.id')
        //     ->select('tokens.*', 'token_cats.tokenCategory', 'token_codes.tokenCode', 'clients.userid', 'users.name') //, 'employees.name')
        //     ->where('assignToken', '=', null)
        //     ->get();

        // $token = Token::with('category', 'Code', 'clients', 'creator')
        $token = Token::list()->where('assignToken', '=', null);
        // dd($token);

        $employees = Employee::orderBy('id', 'ASC')->get();


        return view('token.assignIndex', [
            'employees' => $employees,
            'token' => $token->paginate(1000),
            'reseller' => Reseller::resellerList()->get(),
        ]);
    }

    public function closeIndex()
    {
        // $token = DB::table('tokens')
        //     ->join('token_cats', 'tokens.tokenCategory', '=', 'token_cats.id')
        //     ->join('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
        //     ->join('employees', 'tokens.assignToken', '=', 'employees.id')
        //     ->join('clients', 'tokens.clientId', '=', 'clients.id')
        //     ->leftjoin('users', 'tokens.createdBy', '=', 'users.id')
        //     ->select('tokens.*', 'token_cats.tokenCategory', 'token_codes.tokenCode', 'clients.userid', 'employees.name', 'users.name as username')
        //     ->where('tokens.status', '=', 'Active')
        //     ->get();

        // $token = Token::with('category', 'Code', 'clients', 'creator', 'employees')
        $token = Token::list()->where('assignToken', '!=', null)->where('status', '=', 'Active');
        // dd($token->get());

        return view('token.closeIndex', [
            'token' => $token->paginate(1000),
            'reseller' => Reseller::resellerList()->get(),
        ]);
    }


    // public function create()
    // {
    //     // dd($request->all());
    //     // $client = Client::find($id);
    //     $tokenCategory = TokenCat::all();
    //     $tokenCode = TokenCode::all();
    //     $employees = Employee::latest()->get();
    //     return view('token.create', [
    //         // 'client' => $client,
    //         'tokenCategory' => $tokenCategory,
    //         'tokenCode' => $tokenCode,
    //         'employees' => $employees
    //     ]);
    // }

    // public function store(Request $request)
    // {
    //     //  dd($request->all());
    //     $this->validate($request, [
    //         'tokenCategory' => 'required',
    //         'tokenCode' => 'required',
    //         'description' => 'required',
    //         'reportedBy' => 'required',
    //         'reporterContact' => 'required'
    //     ]);
    //     $token = new Token();
    //     //  $token = Client::find($request->$id);
    //     $token->fill($request->all());
    //     $token->save();
    //     return redirect()->route('token.index');
    // }
    public function show($id)
    {
        // dd("comes");
        $token = Token::with('notes', 'clients.clientsinfo', 'Code', 'category', 'employees', 'creator', 'closer')->find($id);

        $data = [
            'token' => $token
        ];

        // dd($data);

        return view('token.show', $data);
    }
    public function edit($id)
    {
        $tokenCategory = TokenCat::latest()->get();
        $tokenCode = TokenCode::latest()->get();
        $employees = Employee::latest()->get();
        $token = Token::find($id);
        return view('token.edit', [
            'tokenCategory' => $tokenCategory,
            'tokenCode' => $tokenCode,
            'employees' => $employees,
            'token' => $token,
        ]);
    }

    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'tokenCategory' => 'required',
            'tokenCode' => 'required'
        ]);
        $token = Token::find($id);
        $token->fill($request->all());
        $token->update();
        return redirect()->route('token.index');
    }

    public function destroy($id)
    {
        $token = Token::find($id);
        $token->delete();
        return redirect()->route('token.index');
    }

    public function assignToken($id)
    {
        $employees = Employee::orderBy('id', 'ASC')->get();
        $token = Token::find($id);
        return view('token.assign', [
            'employees' => $employees,
            'token' => $token,
        ]);
    }

    public function assignStore(Request $request, $id)
    {

        $this->validate($request, [
            'assignToken' => 'required'
        ]);
        $token = Token::with('Code')->find($id);

        $token->assignToken = $request->assignToken;
        $token->assignUserId = $request->assignUserId;
        $token->assign_time = now();
        $token->update();
        $client_username = Client::find($token->clientId);
        $token_sms = new TokenSms();

        if (checkSettings('token-create-sms') == 'enable') {

            $token_sms->assignTokenSms($token->id);
        }

        (new Notification)->supportNotify(
            "..::[Token Assign]::..
        \nToken ID: " . $token->token .
                "\nAssign BY: " . auth()->user()->name .
                "\nAssigned To: " . employee_name($token->assignToken) .
                "\nClient ID: " . $token->clientId .
                "\nClient Username: " . $client_username->userid .
                "\nCustomer Name : " . $token->reportedBy .
                "\nCustomer Contact: " . $token->reporterContact .
                "\nProblem: " . $token->description
        );


        return redirect()->route('assignTokenList');
    }

    public function closeToken($id)
    {
        $token = Token::find($id);
        return view('token.close', [
            'token' => $token,

        ]);
    }
    public function closeTokenStore(Request $request, $id)
    {
        if (checkSettings('all_information_with_token_close') == 'enable') {

            $clientInfo = ClientsInfo::where('client_id', $request->closeUserId)->first();

            if (
                $clientInfo->division == "" || $clientInfo->division == "."
                || $clientInfo->district == "" || $clientInfo->district == "."
                || $clientInfo->upazila == "" || $clientInfo->upazila == "."
                || $clientInfo->area == "" || $clientInfo->area == "."
                || $clientInfo->block_sector == null || $clientInfo->block_sector == "."
                || $clientInfo->road_name == null || $clientInfo->road_name == "."
                || $clientInfo->road_no == null || $clientInfo->road_no == "."
                || $clientInfo->building_name == null || $clientInfo->building_name == "."
                || $clientInfo->building_no == null || $clientInfo->building_no == "."
                || $clientInfo->flat_no == null || $clientInfo->flat_no == "."
                || $clientInfo->box == null || $clientInfo->box == "."
                || $clientInfo->client_latitude == null || $clientInfo->client_latitude == "."
                || $clientInfo->client_longitude == null || $clientInfo->client_longitude == "."
            ) {
                return redirect()->back()->with('error', 'Please Update Client Address Information');
            }
        }
        // dd($request->all());
        if (checkSettings('close_token_after_customer_online') == 'enable' && checkAPI() == true) {

            $list = Token::with('clients.pops.nas')->find($id);

            $mkIp = $list->clients->pops->nas->nasname;
            $mkUser = $list->clients->pops->nas->mikrotick_user;
            $mkPass = $list->clients->pops->nas->mikrotick_user_password;
            $mkPort = $list->clients->pops->nas->mikrotick_port;
            $mk = new Mikrotik($mkIp, $mkUser, $mkPass, $mkPort ? (int)$mkPort : 8728);

            $last_online = [];
            try {
                $userStatus = $mk->getActiveConnection($list->clients->userid);
                $last_online['framedipaddress'] = $userStatus["address"];
            } catch (Exception $err) {
                $last_online = null;
            }

            if ($last_online == null) {
                Toastr::error('Customer is not online', 'Error');
                return redirect()->back();
            }
        }

        if ($request->remarks) {
            $token = Token::with('clients.clientsinfo', 'category', 'employees', 'Code')->find($id);

            $token->status = $request->status;
            $token->remarks = $request->remarks;
            $token->closeUserId = $request->closeUserId;
            $token->close_time = now();
            $token->update();
            $client_username = Client::withTrashed()->find($token->clientId);
            if (checkSettings('token-close-sms') == 'enable') {

                (new TokenSms)->closeTokenSms($token);
            }

            (new Notification)->supportNotify(
                "..::[Token Close]::..
            \nToken ID: " . $token->token .
                    "\nClosed BY: " . auth()->user()->name .
                    "\nClient ID: " . $token->clientId .
                    "\nClient Username: " . $client_username->userid .
                    "\nCustomer Name : " . $token->reportedBy .
                    "\nCustomer Contact: " . $token->reporterContact .
                    "\nClose Reason: " . $token->remarks
            );

            Toastr::success('Token Closed Successfully');
        } else {

            Toastr::error('Remarks is required', 'Error');
        }

        return redirect()->route('closeTokenList');
    }

    public function indexPrint()
    {
        $token =  DB::table('tokens')
            ->join('token_cats', 'tokens.tokenCategory', '=', 'token_cats.id')
            ->join('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
            ->leftjoin('employees', 'tokens.assignToken', '=', 'employees.id')
            ->leftJoin('clients', 'tokens.clientId', '=', 'clients.id')
            ->leftJoin('users as creator', 'tokens.createdBy', '=', 'creator.id')
            ->select('tokens.*', 'token_cats.tokenCategory', 'token_codes.tokenCode', 'employees.name', 'clients.userid', 'creator.name as createBy',)
            ->where('tokens.status', '=', 'Active')
            ->get();
        return view('token.indexPrint', [
            'token' => $token
        ]);
    }

    public function indexListPrint()
    {
        $token = DB::table('tokens')
            ->join('token_cats', 'tokens.tokenCategory', '=', 'token_cats.id')
            ->join('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
            ->leftjoin('users', 'tokens.createdBy', '=', 'users.id')
            ->leftJoin('clients', 'tokens.clientId', '=', 'clients.id')
            ->leftJoin('clientsinfo', 'tokens.clientId', '=', 'clientsinfo.client_id')
            ->leftjoin('employees', 'tokens.assignToken', '=', 'employees.id')
            ->select('tokens.*', 'token_cats.tokenCategory', 'token_codes.tokenCode', 'employees.name', 'clients.userid', 'users.name as username', 'clientsinfo.*')
            ->where('tokens.status', '=', 'Active')
            ->get();

        // dd($token);

        return view('token.indexListPrint', [
            'token' => $token
        ]);
    }

    public function tokenCreate($id)
    {
        $client = Client::withTrashed()->find($id);
        $tokenCategory = TokenCat::all();
        $tokenCode = TokenCode::all();
        return view('token.create', [
            'client' => $client,
            'tokenCategory' => $tokenCategory,
            'tokenCode' => $tokenCode,
            'employees' => Employee::get(),
            'tokenSource' => TokenSource::get(),
        ]);
    }
    public function tokenStore(Request $request)
    {
        $this->validate($request, [
            'clientId' => 'required',
            'tokenCategory' => 'required',
            'tokenCode' => 'required',
            'description' => 'required',
            'reportedBy' => 'required',
            'reporterContact' => 'required|min:11|max:14',
            'token_type' => 'required',
        ]);

        // Normalize phone number: remove +88 prefix if present, store only 11 digits
        if (strpos($request->reporterContact, '+88') === 0) {
            $request->merge(['reporterContact' => substr($request->reporterContact, 3)]);
        }

        $token_class = new TokenClass();
        $token = $token_class->saveToken($request);
        $token_sms = new TokenSms();
        $client_username = Client::withTrashed()->find($token->clientId);

        if (checkSettings('token-create-sms') == 'enable') {
            $token_sms->createSms($token->id);
        }

        if (globalPermission('notification')) {
            (new Notification)->supportNotify(
                "..::[New Token]::..
                \nToken ID: " . $token->token .
                    "\nCreated BY: " . auth()->user()->name .
                    "\nClient ID: " . $request->clientId .
                    "\nClient Username: " . $client_username->userid .
                    "\nCustomer Name : " . $request->reportedBy .
                    "\nCustomer Contact: " . $request->reporterContact .
                    "\nProblem: " . $request->description
            );
        }



        if (isset($request->employee)) {
            if ($request->employee != null) {

                if (checkSettings('token-create-sms') == 'enable') {

                    $token_sms->assignTokenSms($token->id);
                }

                if (globalPermission('notification')) {

                    (new Notification)->supportNotify(
                        "..::[Token Assign]::..
                            \nToken ID: " . $token->token .
                            "\nAssign BY: " . auth()->user()->name .
                            "\nAssigned To: " . employee_name($token->assignToken) .
                            "\nClient ID: " . $token->clientId .
                            "\nClient Username: " . $client_username->userid .
                            "\nCustomer Name : " . $token->reportedBy .
                            "\nCustomer Contact: " . $token->reporterContact .
                            "\nProblem: " . $token->description
                    );
                }
            }
        }


        return redirect()->route('support-home');

    }

    public function searchToken()
    {
        $start = Carbon::now()->startOfMonth();
        $end = today();

        $reseller = Reseller::orderBy('name')->get();
        $tokenCategory = TokenCat::get();
        $tokenCode = TokenCode::orderBy('tokenCode')->get();
        $created = User::orderBy('name')->get();
        $closed = User::orderBy('name')->get();
        $employee = Employee::where('status', 'active')->orderBy('name')->get();

        $token = Token::list()->where('status', '=', 'Active')->orderByRaw('ISNULL(assign_time), assign_time ASC');
        // dd($token->get());

        $id = auth()->id();
        if (auth()->user()->hasRole('Admin')) {

            $list = $token;
        } elseif (auth()->user()->hasRole(['Reseller Admin', 'Reseller', 'Reseller Technician'])) {
            $pop = Pop::poplist();
            $list = $token->whereHas('clients', function ($query) use ($pop) {
                $query->whereIn('pop_id', $pop->pluck('id'));
            });
        } elseif (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {
            $pop = Pop::poplist();
            $list = $token->whereHas('clients', function ($query) use ($pop) {
                $query->whereIn('pop_id', $pop->pluck('id'));
            });
        } else {
            $list = $token;
        }

        $online = null;
        if (checkAPI()) {
            $online = mikrotikOnlineAndOfflineUsers();
        }

        return view('token.search', [
            'page_title' => 'Token Search Panel',
            'reseller' => Reseller::resellerList()->get(),  // $reseller,
            'pop'  => Pop::conditionalList(),
            'tokenCategory' =>  $tokenCategory,
            'tokenCode' =>  $tokenCode,
            'created' =>  $created,
            'closed' =>  $closed,
            'employee' =>  $employee,
            'start' => $start,
            'end' => $end,
            'token' => $list->get(),
            'mikrotik_online_users' => $online,
            'tokenSource' => TokenSource::get(),
        ]);
    }
    // public function searchTokenResult(Request $request)
    // {
    //     //  dd($request->all());
    //     if ($request->ajax()) {

    //         $from = $request->from_date == '' ? today() : Carbon::parse($request->from_date);
    //         $to = $request->to_date == '' ? today() : Carbon::parse($request->to_date)->addDay();
    //         // $list = Token::with([
    //         //     'clients', 'clients.pops', 'clients.pops.resellers', 'Code', 'employees', 'creator', 'closer'
    //         // ]);

    //         $list = DB::table('tokens')
    //             ->leftJoin('clients', 'tokens.clientId', '=', 'clients.id')
    //             ->leftJoin('pops', 'clients.pop_id', '=', 'pops.id')
    //             ->leftJoin('resellers', 'pops.reseller_id', '=', 'resellers.id')
    //             ->leftJoin('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
    //             ->leftJoin('employees', 'tokens.assignToken', '=', 'employees.id')
    //             ->leftJoin('users as creator', 'tokens.createdBy', '=', 'creator.id')
    //             ->leftJoin('users as closer', 'tokens.closeUserId', '=', 'closer.id')
    //             ->leftJoin('packages', 'clients.package_id', '=', 'packages.id')
    //             ->select(
    //                 'tokens.*',
    //                 'clients.userid',
    //                 'packages.package_name',
    //                 'resellers.name as reseller',
    //                 'pops.popname',
    //                 'token_codes.tokenCode as code',
    //                 'employees.name as employee',
    //                 'creator.name as createBy',
    //                 'closer.name as closedBy'
    //             );

    //         // $list = Token::with('category', 'Code', 'clients', 'creator', 'employees', 'clients.clientsinfo', 'clients.pops', 'clients.pops.reseller')
    //         //         ->where('tokens.status', '=', 'Active');

    //         if (
    //             empty($request->from_date) && empty($request->to_date) && empty($request->name) && empty($request->pop) && empty($request->tokenCode) &&
    //             empty($request->createdBy) && empty($request->closeUserId) && empty($request->status) && empty($request->clientId) &&
    //             empty($request->token) && empty($request->assignToken) && empty($request->userName)
    //         ) {

    //             return '<p class="text-center bg-gray-50 p-2" style="color: red; font-size: 22px;"><b>No Token Found</b></p>';
    //         }

    //         if (!empty($request->name)) {
    //             $list->where('resellers.id',  $request->name);
    //         }
    //         if (!empty($request->pop)) {

    //             if ($request->pop != 'all') {
    //                 $list->where('pops.id',  $request->pop);
    //             } else {
    //                 $list->where('resellers.id',  $request->name);
    //             }
    //         }
    //         if (!empty($request->tokenCode)) {
    //             $list->where('tokens.tokenCode',  $request->tokenCode);
    //         }
    //         if (!empty($request->createdBy)) {
    //             $list->where('tokens.createdBy',  $request->createdBy);
    //         }
    //         if (!empty($request->closeUserId)) {
    //             $list->where('tokens.closeUserId',  $request->closeUserId);
    //         }
    //         if (!empty($request->status)) {
    //             $list->where('tokens.status',  $request->status);
    //         }
    //         if (!empty($request->clientId)) {
    //             $list->where('tokens.clientId',  $request->clientId);
    //         }
    //         if (!empty($request->assignToken)) {
    //             $list->where('tokens.assignToken',  $request->assignToken);
    //         }
    //         if (!empty($request->userName)) {
    //             $list->where('clients.userid',  $request->userName);
    //         }


    //         if (!empty($request->from_date) && !empty($request->to_date)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to]);
    //             // where('tokens.created_at', '>=', $from)
    //             // ->where('tokens.created_at', '<=', $to->addDay());
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->name)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 // where('tokens.created_at', '>=', $from)
    //                 //     ->where('tokens.created_at', '<=', $to->addDay())
    //                 ->where('resellers.id',  $request->name);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->name) && !empty($request->pop)) {

    //             if ($request->pop != 'all') {
    //                 $list->whereBetween('tokens.created_at', [$from, $to])
    //                     ->where('pops.id',  $request->pop);
    //             } else {
    //                 $list->whereBetween('tokens.created_at', [$from, $to])
    //                     ->where('resellers.id',  $request->name);
    //             }
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->name) && !empty($request->status)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('resellers.id',  $request->name)
    //                 ->where('tokens.status',  $request->status);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->tokenCode)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.tokenCode',  $request->tokenCode);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->createdBy)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.createdBy',  $request->createdBy);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->name) && !empty($request->createdBy)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('resellers.id',  $request->name)
    //                 ->where('tokens.createdBy',  $request->createdBy);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->closeUserId)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.closeUserId',  $request->closeUserId);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->status)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.status',  $request->status);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->clientId)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.clientId',  $request->clientId);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->userName)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('clients.userid',  $request->userName);
    //         }
    //         if (!empty($request->token)) {

    //             $list->where('tokens.token', $request->token);
    //         }
    //         if (!empty($request->from_date) && !empty($request->to_date) && !empty($request->assignToken)) {

    //             $list->whereBetween('tokens.created_at', [$from, $to])
    //                 ->where('tokens.assignToken',  $request->assignToken);
    //         }
    //         session()->put('token_search_result', $list->get());

    //         return view('token.result', [
    //             'r'           =>  $list->get(),
    //         ]);
    //     }
    // }


    public function searchTokenResult(Request $request)
    {
        if (!$request->ajax()) {
            abort(403);
        }

        // Prevent empty search
        $filters = [
            'from_date',
            'to_date',
            'name',
            'pop',
            'tokenCode',
            'createdBy',
            'closeUserId',
            'status',
            'clientId',
            'token',
            'assignToken',
            'userName',
            'token_type'
        ];

        $hasFilter = collect($filters)->contains(fn($field) => !empty($request->$field));

        if (!$hasFilter) {
            return '<p class="text-center bg-gray-50 p-2" style="color: red; font-size: 22px;"><b>No Token Found</b></p>';
        }

        // Set default dates
        $from = $request->filled('from_date') ? Carbon::parse($request->from_date) : today();
        $to   = $request->filled('to_date') ? Carbon::parse($request->to_date)->addDay() : today()->addDay();

        $list = DB::table('tokens')
            ->leftJoin('clients', 'tokens.clientId', '=', 'clients.id')
            ->leftJoin('pops', 'clients.pop_id', '=', 'pops.id')
            ->leftJoin('resellers', 'pops.reseller_id', '=', 'resellers.id')
            ->leftJoin('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
            ->leftJoin('employees', 'tokens.assignToken', '=', 'employees.id')
            ->leftJoin('users as creator', 'tokens.createdBy', '=', 'creator.id')
            ->leftJoin('users as closer', 'tokens.closeUserId', '=', 'closer.id')
            ->leftJoin('packages', 'clients.package_id', '=', 'packages.id')
            ->select(
                'tokens.*',
                'clients.userid',
                'packages.package_name',
                'resellers.name as reseller',
                'pops.popname',
                'token_codes.tokenCode as code',
                'employees.name as employee',
                'creator.name as createBy',
                'closer.name as closedBy'
            );

        // Apply filters
        $list->when($request->filled('name'), fn($q) => $q->where('resellers.id', $request->name));

        $list->when($request->filled('pop') && $request->pop !== 'all', fn($q) => $q->where('pops.id', $request->pop));
        $list->when($request->pop === 'all' && $request->filled('name'), fn($q) => $q->where('resellers.id', $request->name));

        $list->when($request->filled('tokenCode'), fn($q) => $q->where('tokens.tokenCode', $request->tokenCode));
        $list->when($request->filled('createdBy'), fn($q) => $q->where('tokens.createdBy', $request->createdBy));
        $list->when($request->filled('closeUserId'), fn($q) => $q->where('tokens.closeUserId', $request->closeUserId));
        $list->when($request->filled('status'), fn($q) => $q->where('tokens.status', $request->status));
        $list->when($request->filled('clientId'), fn($q) => $q->where('tokens.clientId', $request->clientId));
        $list->when($request->filled('assignToken'), fn($q) => $q->where('tokens.assignToken', $request->assignToken));
        $list->when($request->filled('userName'), fn($q) => $q->where('clients.userid', $request->userName));
        $list->when($request->filled('token'), fn($q) => $q->where('tokens.token', $request->token));
        $list->when($request->filled('token_type'), fn($q) => $q->where('tokens.token_type', $request->token_type));
        // Apply date filter
        if ($request->filled('from_date') && $request->filled('to_date')) {
            // When filtering by closer, use close_time range instead of created_at
            if ($request->filled('closeUserId')) {
                $list->whereBetween('tokens.close_time', [$from, $to]);
            } else {
                $list->whereBetween('tokens.created_at', [$from, $to]);
            }
        }

        $results = $list->get();
        session()->put('token_search_result', $results);

        return view('token.result', ['r' => $results]);
    }

    public function tokenExport(Request $request)
    {
        $result = $request->session()->get('token_search_result');
        $data[] = '';
        $data = $result;
        // dd($data);
        return Excel::download(new SearchTokenExport($data), 'tokens.csv');
    }

    public function getTokenById(Request $request)
    {
        if ($request->ajax()) {

            if (!empty($request->type) && !empty($request->value)) {

                $list = Client::with('clientsinfo', 'pop', 'packages', 'user')
                    ->where($request->type, $request->value)
                    ->first();
                $con_history = User_log::with('client', 'user')
                    ->where('client_id', $list->id)
                    ->orderBy('id', 'DESC')
                    ->get();


                $login_attempts = RadPostAuthFacade::getAccessLogByUsername($list->userid);
                $log_activities = DB::table('reselle_balance_log_reports')->where('client_id', $list->id)->orderBy('id', 'DESC')->get();
                $html = '';
                foreach ($login_attempts as $row) {
                    $html .= '<tr><td>' . Carbon::parse($row->authdate)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $row->username . '</td>' .
                        '<td>' . $row->pass . '</td>' .
                        '<td>' . '' . '</td>' .
                        '<td>' . $row->reply . '</td>' .
                        '<td>' . '' . '</td>' .
                        '</tr>';
                }
                $output = '';
                foreach ($log_activities as $row) {
                    $output .= '<tr><td>' . Carbon::parse($row->created_at)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $row->action . '</td>' .
                        '<td>' . $row->remarks . '</td>' .
                        '</tr>';
                }
                $con_output = '';
                foreach ($con_history as $row) {
                    $con_output .= '<tr><td>' . Carbon::parse($row->created_at)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $row->details . '</td>' .
                        '<td>' . $row->log_type . '</td>' .
                        '<td>' . $row->user->name . '</td>' .
                        '</tr>';
                }

                if ($list == null) {
                    return '<p class="text-center bg-gray-50 p-2">No User Found</p>';
                }
            }

            return $data = [
                'r'                        =>  $list,
                'login_attempts'           =>  $html,
                'log_activities'           =>  $output,
                'connection_history'       =>  $con_output,
            ];
        }
    }


    public function getTokenCodeList(Request $request)
    {

        if (request()->ajax()) {

            $tokenCode = TokenCode::where('tokenCategory', $request->id)->get();

            // dd($tokenCode);

            $option = '<option value="">Select One Code</option>';

            foreach ($tokenCode as $code) {

                $option .= "<option value='" . $code->id . "'>" . $code->tokenCode . "</option>";
            }


            echo $option;
        }
    }

    public function assignSearch(Request $request)
    {
        if ($request->ajax()) {

            $token = Token::list()->where('assignToken', '=', null);
            $employees = Employee::orderBy('id', 'ASC')->get();

            if (!empty($request->reseller) && !empty($request->pop)) {

                if ($request->pop != 'all') {

                    $token->whereHas('clients.pops', function ($query) use ($request) {
                        $query->where('id', $request->pop);
                    });
                } else {

                    $token->whereHas('clients.pops.reseller', function ($query) use ($request) {
                        $query->where('id', $request->reseller);
                    });
                }
            } else {

                return '<p class="text-center bg-gray-50 p-2" style="color: red; font-size: 22px;"><b>No Token Found</b></p>';
            }

            return view('token.assignSearch', [
                'list' => $token->paginate(1000),
                'employees' => $employees,
            ]);
        }
    }

    public function closeTokenSearch(Request $request)
    {
        if ($request->ajax()) {

            $token = Token::list()->where('assignToken', '!=', null)->where('status', '=', 'Active');

            if (!empty($request->reseller) && !empty($request->pop)) {

                if ($request->pop != 'all') {

                    $token->whereHas('clients.pops', function ($query) use ($request) {
                        $query->where('id', $request->pop);
                    });
                } else {

                    $token->whereHas('clients.pops.reseller', function ($query) use ($request) {
                        $query->where('id', $request->reseller);
                    });
                }
            } else {

                return '<p class="text-center bg-gray-50 p-2" style="color: red; font-size: 22px;"><b>No Token Found</b></p>';
            }

            return view('token.closeSearch', [
                'list' => $token->paginate(1000)
            ]);
        }
    }

    public function printTokenSearch(Request $request)
    {
        if ($request->ajax()) {

            $token = Token::list()->where('status', '=', 'Active');

            if (!empty($request->reseller) && !empty($request->pop)) {

                if ($request->pop != 'all') {

                    $token->whereHas('clients.pops', function ($query) use ($request) {
                        $query->where('id', $request->pop);
                    });
                } else {

                    $token->whereHas('clients.pops.reseller', function ($query) use ($request) {
                        $query->where('id', $request->reseller);
                    });
                }
            } else {

                return '<p class="text-center bg-gray-50 p-2" style="color: red; font-size: 22px;"><b>No Token Found</b></p>';
            }

            return view('token.printSearch', [
                'list' => $token->paginate(1000)
            ]);
        }
    }

    public function indexSearchPrint(Request $request)
    {
        $reseller = $request->query('reseller');
        $pop = $request->query('pop');
        // dd($reseller, $pop);

        $list = DB::table('tokens')
            ->join('token_cats', 'tokens.tokenCategory', '=', 'token_cats.id')
            ->join('token_codes', 'tokens.tokenCode', '=', 'token_codes.id')
            ->join('clients', 'tokens.clientId', '=', 'clients.id')
            ->leftjoin('users', 'tokens.createdBy', '=', 'users.id')
            ->leftjoin('employees', 'tokens.assignToken', '=', 'employees.id')
            ->leftjoin('clientsinfo', 'tokens.clientId', '=', 'clientsinfo.client_id')
            ->leftJoin('pops', 'clients.pop_id', '=', 'pops.id')
            ->leftJoin('resellers', 'pops.reseller_id', '=', 'resellers.id')
            ->select(
                'tokens.*',
                'token_cats.tokenCategory',
                'token_codes.tokenCode',
                'employees.name',
                'clientsinfo.clients_name',
                'resellers.id as reseller_id',
                'resellers.name as reseller',
                'pops.id as pop_id',
                'pops.popname',
            )
            ->where('tokens.status', '=', 'Active');

        if (!empty($request->reseller) && !empty($request->pop)) {

            if ($request->pop != 'all') {
                $list->where('pops.id',  $pop);
            } else {
                $list->where('resellers.id',  $reseller);
            }

            return view('token.indexPrint', [
                'token' => $list->get()
            ]);
        }
    }
}
