<?php

namespace App\Http\Controllers\Clients;

use App\Classes\Accounting\Accounting;
use App\Classes\MikrotikService\Mikrotik;
use App\Models\Pop;
use App\Models\Client;
use App\Models\Reseller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use App\Models\CustomerDelInfo;
use App\Models\Nas;
use App\Models\User;
use Brian2694\Toastr\Facades\Toastr;
use Exception;

class OflineCustomerController extends Controller
{
    public function oflineCustomer(Request $request)
    {

        if (auth()->user()->hasRole(['Sub Reseller', 'Sub Reseller Technician'])) {
            $poplist = userPops();




            return view('clients.onlineofline.oflineCustomer', [
                'page_title' => 'Offline Customer List',
                'poplist' => $poplist,
                'reseller' => null
            ]);
        } else {

            $reseller_list =  Reseller::resellerList()->get();


            return view('clients.onlineofline.oflineCustomer', [
                'page_title' => 'Offline Customer List',
                'reseller' => $reseller_list,
                'poplist' => null
            ]);
        }
    }


    public function oflineCustomerResult(Request $request)
    {


        if (checkAPI()) {

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

                try {
                    $allUsersInMK = [];
                    $pop = userPops()->find($request->pop);

                    if($request->clients_status != null){
                        $users = Client::list()
                            ->where('clients_status', $request->clients_status)
                            ->where('pop_id', $request->pop)
                            ->pluck('userid')->toArray();
                    }else{

                        $users = Client::list()
                            ->where(function ($q) {
                                $q->where('clients_status', 'active')
                                    ->orWhere('clients_status', 'expired')
                                    ->orWhere('clients_status', 'disable');
                            })
                            ->where('pop_id', $request->pop)
                            ->pluck('userid')->toArray();
                    }


                    if (!globalPermission("clientManageThroughNodeJs")) {
                        $mkIp = $pop->nas->nasname;
                        $mkUsername = $pop->nas->mikrotick_user;
                        $mkPassword = $pop->nas->mikrotick_user_password;
                        $mkPort = $pop->nas->mikrotick_port;
                        $mk = new Mikrotik($mkIp, $mkUsername, $mkPassword, $mkPort ? (int)$mkPort : 8728);
                        $allActiveUsers = $mk->getActiveConnection();
                        $allUsers = $mk->getSecret();
                        foreach ($allUsers as $user) {
                            $allUsersInMK[$user["name"]] = $user;
                        }
                        $storedActiveUser = [];
                        foreach ($allActiveUsers as $user) {
                            $storedActiveUser[$user["name"]] = $user;
                        }
                    }

                    $result = [];

                    $allClients = Client::select('id', 'userid', 'password', 'deleted_at', 'clients_status', 'expire_date', 'payment_dadeline', 'pop_id', 'package_id', 'sub_package_id') // Columns from the Client model
                        ->with([
                            'clientsinfo:client_id,clients_name,contact_no,otc,otc_due,flat_no,building_name,road_no,block_sector,area,box', // client_id is necessary for the relationship
                            'customerAccount:id,client_id,dueAmount', // client_id needed for relation
                            'pop:id,bill_generate,subreseller,popname', // pop_id is selected in the client table, id selected here
                            'subpack:id,rate,name', // subpack_id in client, id here
                            'packages:id,package_rate,package_name' // package_id in client, id here
                        ])
                        ->whereIn('userid', $users)
                        ->get();


                    foreach ($users as $user) {
                        if (globalPermission("clientManageThroughNodeJs")) {
                            $allUsersInMK[$user] = secretFromRedis($user);
                            if (!activeFromRedis($user)) {
                                $offlineuser = $allClients->where('userid', $user)->first();
                                if ($offlineuser)
                                    array_push($result, $offlineuser);
                            }
                        } else
                        if (!array_key_exists($user, $storedActiveUser)) {
                            $offlineuser = $allClients->where('userid', $user)->first();
                            array_push($result, $offlineuser);
                        }
                    }

                    return view('clients.onlineofline.oflineResult', [
                        'list' => $result,
                        'all_customer' => $allUsersInMK,
                        'page_title' => 'ofline Customer List',
                    ]);
                } catch (Exception $e) {
                    return response()->json([
                        'status' => 'error',
                        'message' => $e->getMessage() . ' while processing POP: ' . $pop->popname,
                        'error_detail' => $e->getMessage(),
                    ], 500);
                }
            } else if ($request->pop && $request->reseller && $request->pop == 'all') {
                //offline customer for a selected reseller

                $popes = userPops()->where('reseller_id', $request->reseller);
                $storedActiveUser = [];
                $result = [];
                $allUsersInMK = [];
                $checkedMk = [];
                foreach ($popes as $pop) {
                    try {

                          if($request->clients_status != null){
                            $users = Client::list()
                                  ->where('clients_status', $request->clients_status)
                                  ->where('pop_id', $pop->id)
                                  ->pluck('userid')->toArray();
                          }else{

                              $users = Client::list()
                                  ->where(function ($q) {
                                      $q->where('clients_status', 'active')
                                          ->orWhere('clients_status', 'expired')
                                          ->orWhere('clients_status', 'disable');
                                  })
                                  ->where('pop_id', $pop->id)
                                  ->pluck('userid')->toArray();
                          }

                        if (!globalPermission("clientManageThroughNodeJs")) {
                            $mkIp = $pop->nas->nasname;
                            $mkUsername = $pop->nas->mikrotick_user;
                            $mkPassword = $pop->nas->mikrotick_user_password;
                            $mkPort = $pop->nas->mikrotick_port;

                            $ipPort = $pop->nas->nasname . ':' . $pop->nas->mikrotick_port;

                            if (!in_array($ipPort, $checkedMk)) {

                                $mk = new Mikrotik($mkIp, $mkUsername, $mkPassword, $mkPort ? (int)$mkPort : 8728);
                                $allActiveUsers = $mk->getActiveConnection();

                                $allUsers = $mk->getSecret();

                                foreach ($allUsers as $user) {
                                    $allUsersInMK[$user["name"]] = $user;
                                }
                                foreach ($allActiveUsers as $user) {
                                    $storedActiveUser[$user["name"]] = $user;
                                }
                                array_push($checkedMk, $ipPort);
                            }
                        }


                        $allClients = Client::select('id', 'userid', 'password', 'deleted_at', 'clients_status', 'expire_date', 'payment_dadeline', 'pop_id', 'package_id', 'sub_package_id') // Columns from the Client model
                            ->with([
                                'clientsinfo:client_id,clients_name,contact_no,otc,otc_due,flat_no,building_name,road_no,block_sector,area,box', // client_id is necessary for the relationship
                                'customerAccount:id,client_id,dueAmount', // client_id needed for relation
                                'pop:id,bill_generate,subreseller,popname', // pop_id is selected in the client table, id selected here
                                'subpack:id,rate,name', // subpack_id in client, id here
                                'packages:id,package_rate,package_name' // package_id in client, id here
                            ])
                            ->whereIn('userid', $users)
                            ->get();

                        foreach ($users as $user) {
                            if (globalPermission("clientManageThroughNodeJs")) {
                                $allUsersInMK[$user] = secretFromRedis($user);
                                if (!activeFromRedis($user)) {
                                    $offlineuser = $allClients->where('userid', $user)->first();
                                    if ($offlineuser)
                                        array_push($result, $offlineuser);
                                }
                            } else
                        if (!array_key_exists($user, $storedActiveUser)) {
                                $offlineuser = $allClients->where('userid', $user)->first();
                                array_push($result, $offlineuser);
                            }
                        }
                    } catch (Exception $e) {
                        return response()->json([
                            'status' => 'error',
                            'message' => $e->getMessage() . ' while processing POP: ' . $pop->popname,
                            'error_detail' => $e->getMessage(),
                        ], 500);
                    }
                }


                return view('clients.onlineofline.oflineResult', [
                    'list' => $result,
                    'all_customer' => $allUsersInMK,
                    'page_title' => 'ofline Customer List',
                ]);
            } else if ($request->pop  && $request->pop != 'all') {

                //offline customer for sub reseller of selected pop
                try {
                    $allUsersInMK = [];
                    $pop = userPops()->find($request->pop);

                     if($request->clients_status != null){
                              $users = Client::list()
                             ->where('clients_status', $request->clients_status)
                             ->where('pop_id', $request->pop)
                             ->pluck('userid')->toArray();
                     }else{

                         $users = Client::list()
                             ->where(function ($q) {
                                 $q->where('clients_status', 'active')
                                     ->orWhere('clients_status', 'expired')
                                     ->orWhere('clients_status', 'disable');
                             })
                             ->where('pop_id', $request->pop)
                             ->pluck('userid')->toArray();
                     }

                    if (!globalPermission("clientManageThroughNodeJs")) {
                        $mkIp = $pop->nas->nasname;
                        $mkUsername = $pop->nas->mikrotick_user;
                        $mkPassword = $pop->nas->mikrotick_user_password;
                        $mkPort = $pop->nas->mikrotick_port;
                        $mk = new Mikrotik($mkIp, $mkUsername, $mkPassword, $mkPort ? (int)$mkPort : 8728);
                        $allActiveUsers = $mk->getActiveConnection();
                        $allUsers = $mk->getSecret();
                        foreach ($allUsers as $user) {
                            $allUsersInMK[$user["name"]] = $user;
                        }
                        $storedActiveUser = [];
                        foreach ($allActiveUsers as $user) {
                            $storedActiveUser[$user["name"]] = $user;
                        }
                    }



                    $result = [];
                    $allClients = Client::select('id', 'userid', 'password', 'deleted_at', 'clients_status', 'expire_date', 'payment_dadeline', 'pop_id', 'package_id', 'sub_package_id') // Columns from the Client model
                        ->with([
                            'clientsinfo:client_id,clients_name,contact_no,otc,otc_due,flat_no,building_name,road_no,block_sector,area,box', // client_id is necessary for the relationship
                            'customerAccount:id,client_id,dueAmount', // client_id needed for relation
                            'pop:id,bill_generate,subreseller,popname', // pop_id is selected in the client table, id selected here
                            'subpack:id,rate,name', // subpack_id in client, id here
                            'packages:id,package_rate,package_name' // package_id in client, id here
                        ])
                        ->whereIn('userid', $users)
                        ->get();
                    foreach ($users as $user) {
                        if (globalPermission("clientManageThroughNodeJs")) {
                            $allUsersInMK[$user] = secretFromRedis($user);
                            if (!activeFromRedis($user)) {
                                $offlineuser = $allClients->where('userid', $user)->first();
                                if ($offlineuser)
                                    array_push($result, $offlineuser);
                            }
                        } else
                        if (!array_key_exists($user, $storedActiveUser)) {
                            $offlineuser = $allClients->where('userid', $user)->first();
                            array_push($result, $offlineuser);
                        }
                    }
                } catch (Exception $e) {
                    return response()->json([
                        'status' => 'error',
                        'message' => $e->getMessage() . ' while processing POP: ' . $pop->popname,
                        'error_detail' => $e->getMessage(),
                    ], 500);
                }



                return view('clients.onlineofline.oflineResult', [
                    'list' => $result,
                    'all_customer' => $allUsersInMK,
                    'page_title' => 'ofline Customer List',
                ]);
            } else {

                $popes = Pop::conditionalList();

                $storedActiveUser = [];
                $result = [];
                $allUsersInMK = [];
                $checkedMk = [];
                foreach ($popes as $pop) {
                    try {
                         if($request->clients_status != null){
                            $users = Client::list()
                                 ->where('clients_status', $request->clients_status)
                                 ->where('pop_id', $pop->id)
                                 ->pluck('userid')->toArray();
                         }else{

                             $users = Client::list()
                                 ->where(function ($q) {
                                     $q->where('clients_status', 'active')
                                         ->orWhere('clients_status', 'expired')
                                         ->orWhere('clients_status', 'disable');
                                 })
                                 ->where('pop_id', $pop->id)
                                 ->pluck('userid')->toArray();
                         }

                        $mkIp = $pop->nas->nasname;
                        $mkUsername = $pop->nas->mikrotick_user;
                        $mkPassword = $pop->nas->mikrotick_user_password;
                        $mkPort = $pop->nas->mikrotick_port;

                        $ipPort = $pop->nas->nasname . ':' . $pop->nas->mikrotick_port;

                        if (!in_array($ipPort, $checkedMk)) {

                            $mk = new Mikrotik($mkIp, $mkUsername, $mkPassword, $mkPort ? (int)$mkPort : 8728);
                            $allActiveUsers = $mk->getActiveConnection();

                            $allUsers = $mk->getSecret();

                            foreach ($allUsers as $user) {
                                $allUsersInMK[$user["name"]] = $user;
                            }
                            foreach ($allActiveUsers as $user) {
                                $storedActiveUser[$user["name"]] = $user;
                            }
                            array_push($checkedMk, $ipPort);
                        }


                        $allClients = Client::select('id', 'userid', 'password', 'deleted_at', 'clients_status', 'expire_date', 'payment_dadeline', 'pop_id', 'package_id', 'sub_package_id') // Columns from the Client model
                            ->with([
                                'clientsinfo:client_id,clients_name,contact_no,otc,otc_due,flat_no,building_name,road_no,block_sector,area,box', // client_id is necessary for the relationship
                                'customerAccount:id,client_id,dueAmount', // client_id needed for relation
                                'pop:id,bill_generate,subreseller,popname', // pop_id is selected in the client table, id selected here
                                'subpack:id,rate,name', // subpack_id in client, id here
                                'packages:id,package_rate,package_name' // package_id in client, id here
                            ])
                            ->whereIn('userid', $users)
                            ->get();

                        foreach ($users as $user) {
                            if (!array_key_exists($user, $storedActiveUser)) {
                                $offlineuser = $allClients->where('userid', $user)->first();
                                array_push($result, $offlineuser);
                            }
                        }
                    } catch (Exception $e) {
                        return response()->json([
                            'status' => 'error',
                            'message' => $e->getMessage() . ' while processing POP: ' . $pop->popname,
                            'error_detail' => $e->getMessage(),
                        ], 500);
                    }
                }



                return view('clients.onlineofline.oflineResult', [
                    'list' => $result,
                    'all_customer' => $allUsersInMK,
                    'page_title' => 'ofline Customer List',
                ]);
            }
        } else {
            if ($request->pop || $request->reseller) {

                $pop_ids = Pop::poplist();

                if ($request->reseller == null) {
                    $pop_ids = Pop::poplist()->pluck('id')->toArray();
                }

                if ($request->reseller != null && $request->pop == 'all') {
                    $pop_ids = Pop::poplist()->where('reseller_id', $request->reseller)->pluck('id')->toArray();
                }

                if ($request->pop != 'all' && $request->pop != null) {
                    $pop_ids = Pop::poplist()->where('id', $request->pop)->pluck('id')->toArray();
                }



                $clientList = Client::list()->where('clients_status', 'active')
                    ->whereIn('pop_id', $pop_ids)
                    ->select('userid')
                    ->pluck('userid');

                $accounting = new Accounting();


                $online = $accounting->OnlineUsers($clientList);

                // dd("comes");
                $list =  $clientList->diff($online)->toArray();



                $oflinelist = $accounting->latestRecords($list);
                // dd($latestRecords);



                return view('clients.onlineofline.oflineResult', [
                    'list' => $oflinelist,
                    'page_title' => 'ofline Customer List',
                ]);
            } else {
                echo '<p class="text-center text-danger">Please Select Reseller</p>';
            }
        }
    }



    public function deletedCustomer()
    {
        $list = CustomerDelInfo::all();

        return view('clients.onlineofline.deletedCustomer', [
            'page_title' => 'Deleted Customer List',
            'list' => $list,
        ]);
    }
}
