<?php

namespace App\Http\Controllers;

use Exception;
use Carbon\Carbon;
use App\Models\Pop;
use App\Models\Token;
use App\Models\Client;
use App\Models\Packages;
use App\Models\User_log;
use Illuminate\Http\Request;
use App\Services\ClientServices;
use App\Facades\RadPostAuthFacade;
use Illuminate\Support\Facades\DB;
use App\Classes\Accounting\Accounting;
use App\Classes\MikrotikService\Mikrotik;


class SupportHomeController extends Controller
{

    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            if ($request->user()->can('support_home_hide')) {
                abort(403);
            }
            return $next($request);
        })->only(['supportHome']);
    }

    public function supportHome(Request $request)
    {
        return view('support_home.create', [
            'page_title' => 'Customer Support Panel',


        ]);
    }
    public function getClientDetails(Request $request)
    {
        if ($request->ajax()) {

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

                if ($request->type == 'id') {
                    $lists = Client::listWithPendingAndClose()->where($request->type, 'like', "%$request->value%")->get();
                    $list = [];
                    if(checkSettings('active_inactive_pop') == 'enable'){
                        foreach($lists as $item){
                            $pop = Pop::find($item->pop_id);
                            if($pop && $pop->active_inactive == 'active'){
                                $list[] = $item;
                            }
                        }
                    }else{
                        foreach($lists as $item){
                            $list[] = $item;
                        }
                    }
                } else {
                    $lists = Client::listWithPendingAndClose()->whereHas('clientsinfo', function ($q) use ($request) {
                        $q->where($request->type, 'like', "%$request->value%");
                    })->get();
                    $list = [];
                    if(checkSettings('active_inactive_pop') == 'enable'){
                        foreach($lists as $item){
                            $pop = Pop::find($item->pop_id);
                            if($pop && $pop->active_inactive == 'active'){
                                $list[] = $item;
                            }
                        }
                    }else{
                        foreach($lists as $item){
                            $list[] = $item;
                        }
                    }

                }
                $list = collect($list);

                if ($list->count() <= 0) {
                    return '<p class="text-center bg-gray-50 p-2">No User Found</p>';
                } else {
                    return view('support_home.result', [
                        'list'           =>  $list,
                    ]);
                }
            } else {
                return '<p class="text-center bg-gray-50 p-2">Please input user name or user id or contact number</p>';
            }
        }
    }
    public function getClientById(Request $request)
    {
        if ($request->ajax()) {

            if (!empty($request->id)) {

                $logForAPISecrets = "";
                $logType = '';

                $list = Client::withTrashed()->with('clientsinfo:email,contact_no,national_id,passport_no,mother_name,father_name,area,client_id,clients_name',
                'pop:id,popname,nas_id', 'packages:id,package_name,pool_name', 'customerAccount:id,client_id,dueAmount','radusergroup:username,groupname')
                    ->find($request->id, ['id', 'userid', 'password', 'ip_address', 'mac', 'created_at', 'clients_status', 'pop_id', 'package_id', 'expire_date', 'created_by']);

                $list->created_by_name = user_name($list->created_by);

                $con_history = User_log::where('client_id', $list->id)
                    ->orderBy('id', 'DESC')
                    ->limit(10)
                    ->get();

                $last_online = null;
                if (checkAPI()) {
                    try {
                        $nas = $list->pop->load('nas');
                        $mkIp = $list->pop->nas->nasname;
                        $mkUser = $list->pop->nas->mikrotick_user;
                        $mkPass = $list->pop->nas->mikrotick_user_password;
                        $mkPort = $list->pop->nas->mikrotick_port;
                        $mk = new Mikrotik($mkIp, $mkUser, $mkPass, $mkPort ? (int)$mkPort : 8728);

                        $last_online = [];
                        try {
                            $userStatus = $mk->getActiveConnection($list->userid);
                            $last_online['framedipaddress'] = $userStatus["address"];
                        } catch (Exception $err) {
                            $last_online = null;
                        }
                        try {
                            if ($last_online) {
                                $clientInfo = $mk->getSecret($list->userid);
                                $last_online['acctstoptime'] = $clientInfo['last-logged-out'];
                            }
                        } catch (Exception $err) {
                            $last_online = null;
                        }

                        try {
                            $all_logs = array_reverse($mk->getSecretLogs());
                            foreach ($all_logs as $log) {
                                $time = $log["time"];
                                $message = str_replace(">", "", str_replace("<", "", $log["message"]));
                                if (str_contains($message,  $list->userid)) {
                                    $logForAPISecrets .= "<tr>
                                    <td> $time </td>
                                    <td>$message</td>
                                    </tr>";
                                }
                            }
                        } catch (Exception $err) {
                        }
                    } catch (Exception $err) {
                    }
                } else {

                    $new_accounting = new Accounting();
                    $last_online = $new_accounting->lastOnlineOfSingleUser($list->userid);
                }

                $login_attempts = RadPostAuthFacade::getAccessLogByUsername($list->userid);
                if (auth()->user()->hasRole(['Sub Reseller'])) {
                    $log_activities = DB::table('sub_reseller_balance_log_report')->where('client_id', $list->id)->orderBy('id', 'DESC')->limit(10)->get();
                } else {
                    $log_activities = DB::table('reselle_balance_log_reports')->where('client_id', $list->id)->orderBy('id', 'DESC')->limit(10)->get();
                }
                $tokens = Token::with('category', 'Code')->where('clientId', $list->id);

                // Clone or reinitialize the query for each different set of conditions
                $previous_token = (clone $tokens)->where('status', 'Inactive')->orderBy('id', 'DESC')->limit(10)->get();
                $pending_token = (clone $tokens)->where('status', 'Active')->orderBy('id', 'DESC')->limit(10)->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>' . (isset($row->mac) ? $row->mac : '') . '</td>' .
                        '<td>' . $row->reply . '</td>' .
                        '<td>' . (isset($row->mikrotik) ? $row->mikrotik : '') . '</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>';
                }

                $token_output = '';
                foreach ($pending_token as $row) {
                    $token_output .= '<tr><td>' . Carbon::parse($row->created_at)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $row->token . '</td>' .
                        '<td>' . ($row->category->tokenCategory ?? '') . '</td>' .
                        '<td>' . ($row->Code->tokenCode ?? '') . '</td>' .
                        '<td>' . $row->reportedBy . '</td>' .
                        '<td>' . $row->reporterContact . '</td>' .
                        '<td>' . $row->description . '</td>' .
                        '<td>' . $row->status . '</td>' .
                        '</tr>';
                }

                $previous_token_output = '';
                foreach ($previous_token as $row) {
                    $previous_token_output .= '<tr><td>' . Carbon::parse($row->created_at)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $row->token . '</td>' .
                        '<td>' . ($row->category->tokenCategory ?? '') . '</td>' .
                        '<td>' . ($row->Code->tokenCode ?? '') . '</td>' .
                        '<td>' . $row->reportedBy . '</td>' .
                        '<td>' . $row->reporterContact . '</td>' .
                        '<td>' . $row->description . '</td>' .
                        '<td>' . $row->status . '</td>' .
                        '</tr>';
                }

                $con_output = '';
                foreach ($con_history as $row) {
                    if ($row->log_type == 'id_enable') {
                        $logType = '<span class="bg bg-green btn-block text-center">Enable</span>';
                    } elseif ($row->log_type == 'id_disable') {
                        $logType = '<span class="bg bg-warning btn-block text-center">Disable</span>';
                    } elseif ($row->log_type == 'id_deactive') {
                        $logType = '<span class="bg bg-danger btn-block text-center">Deactive</span>';
                    } elseif ($row->log_type == 'id_approved') {
                        $logType = '<span class="bg bg-success btn-block text-center">Approved</span>';
                    } elseif ($row->log_type == 'id_close') {
                        $logType = '<span class="bg bg-danger btn-block text-center">Close</span>';
                    } elseif ($row->log_type == 'id_restore') {
                        $logType = '<span class="bg bg-danger btn-block text-center">Restore</span>';
                    }

                    $con_output .= '<tr><td>' . Carbon::parse($row->created_at)->isoFormat('LLLL') . '</td>' .
                        '<td>' . $logType . '</td>' .
                        '<td>' . $row->details . '</td>' .
                        '<td>' . user_name($row->user_id) . "<br>" . user_email($row->user_id)  . '</td>' .
                        '</tr>';
                }

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

                $edit_log = '';


                $edit_log .= "<tr><td colspan=3><a class='btn btn-secondary btn-block' href='get-all-edit-log-history/" . $request->id . "'>view All Edit History</a></td></tr>";
            }

            $auth_user_id = auth()->user()->id;
            $pool_name_show_permission = auth()->user()->hasPermissionTo('pool_name_in_support_home') ? true : false;


            return $data = [
                'r'                        =>  $list,
                'login_attempts'           =>  checkAPI() ? $logForAPISecrets : $html,
                'log_activities'           =>  $output,
                'connection_history'       =>  $con_output,
                'last_online'              =>  $last_online,
                'edit_log'                 =>  $edit_log,
                'token_output'             =>  $token_output,
                'previous_token_output'    =>  $previous_token_output,
                'auth_user_id'            =>  $auth_user_id,
                'pool_name_show_permission' =>  $pool_name_show_permission,
                // 'created_by_name'          =>  user_name($list->created_by),
            ];
        }
    }


    public function getAllEditLogHistory($id)
    {
        $client = Client::with('clientsinfo', 'pop', 'packages', 'user', 'customerAccount', "pop.nas", 'clientEditLog.user')->find($id);

        $data = [
            'client' => $client,
        ];
        return view('support_home.clienEditLog', $data);
    }

    public function showLastLogLines()
    {
        $filePath = '/var/log/freeradius/radius.log';
        $linesToShow = 500;

        if (!file_exists($filePath)) {
            return response()->json(['error' => 'Log file does not exist'], 404);
        }

        $lines = $this->tailFile($filePath, $linesToShow);

        return view('support_home.freeradiusLogsPage', [
            'logs' =>  $lines,
        ]);
    }

    private function tailFile($filePath, $linesToShow)
    {
        $file = new \SplFileObject($filePath, 'r');
        $file->seek(PHP_INT_MAX);
        $totalLines = $file->key();

        $lines = [];
        $startLine = max(0, $totalLines - $linesToShow);

        $macPattern = '/cli ([0-9A-Fa-f:]{17})/';
        $usernamePattern = '/\[(.*?)\]/';
        $nasNamePattern = '/client (.*?) port/';
        $timePattern = '/^(\w+ \w+ \d+ \d+:\d+:\d+ \d+)/';

        for ($i = $startLine; $i <= $totalLines; $i++) {
            $file->seek($i);
            $currentLine = $file->current();

            preg_match($macPattern, $currentLine, $macMatches);
            preg_match($usernamePattern, $currentLine, $userMatches);
            preg_match($nasNamePattern, $currentLine, $nasMatches);
            preg_match($timePattern, $currentLine, $timeMatches);


            $parsedLine = [
                'original_line' => trim($currentLine),
                'timestamp' => $timeMatches[1] ?? null,
                'mac_address' => $macMatches[1] ?? null,
                'username' => $userMatches[1] ?? null,
                'nas_name' => $nasMatches[1] ?? null,
            ];

            $lines[] = $parsedLine;
        }

        return $lines;
    }
}
