<?php

namespace App\Controllers;

use Rakit\Validation\Validator;
use App\Models\RunJobnetModel;
use App\Models\BoottimeModel;
use App\Models\JobargModuleModel;
use App\Controllers\Api\LoginApi;
use App\Utils\Constants;
use App\Utils\Core;
use App\Utils\Util;
use App\Models\IndexModel;
use App\Utils\Response;
use DateTime;
use PDOException;

class JobargModule
{
    protected $runJobnetModel;
    protected $boottimeModel;
    protected $indexModel;
    protected $response;
    protected $validator;
    protected $jobargModuleModel;
    protected $util;
    protected $logger;
    protected $timeout = 5;

    public function __construct()
    {
        $this->runJobnetModel = new RunJobnetModel();
        $this->boottimeModel = new BoottimeModel();
        $this->jobargModuleModel = new JobargModuleModel();
        $this->util = new Util();
        $this->indexModel = new IndexModel();
        $this->response = new Response();
        $this->validator = new Validator();
        $this->logger = Core::logger();
    }

    public function handleRequest()
    {
        header('Content-Type: application/json');
        $input = json_decode(file_get_contents('php://input'), true);
        $zabbixResult = $method = null;

        if ($input["Zabbix"]["method"] == "user.login") {
            $result = LoginApi::AuthPathAPI($input["Zabbix"]["params"]);
            if ($result == false) {
                echo $this->errorResponse("Couldn't connect with zabbix api", Constants::API_RESPONSE_TYPE_500);
                $this->logger->error("Couldn't connect with zabbix api", ['controller' => __METHOD__]);
                return;
            }
            if ($result == LoginApi::JSON_FAILED_FLAG) {
                echo $this->errorResponse("Zabbix api response format error.", Constants::API_RESPONSE_TYPE_500);
                $this->logger->error("Zabbix api response format error.", ['controller' => __METHOD__]);
                return;
            }
            $final = json_decode($result);
            if (isset($final->result->sessionid)) {
                $zabbixResult = (array) $final->result;
                echo $this->buildResponse($zabbixResult, true, $input["Zabbix"]["method"], null);
            } else {
                echo $this->errorResponse($final->error->data, Constants::API_RESPONSE_TYPE_INCOMPLETE);
                $this->logger->info($final->error->data, ['controller' => __METHOD__]);
            }
        }
        if ($input["Zabbix"]["method"] == "execution") {
            $this->logger->debug('Json Input' . json_encode($input));
            $this->logger->debug('Method' . $input['JobArranger']['method']);

            $resCheckAuth = LoginApi::checkAuthentication($input["Zabbix"]["auth"]);
            if ($resCheckAuth == false) {
                echo $this->errorResponse("Couldn't connect with zabbix api in execution", Constants::API_RESPONSE_TYPE_500);
                $this->logger->error("Couldn't connect with zabbix api", ['controller' => __METHOD__]);
                return;
            }
            if ($resCheckAuth == LoginApi::JSON_FAILED_FLAG) {
                echo $this->errorResponse("Zabbix api response format error.", Constants::API_RESPONSE_TYPE_500);
                $this->logger->error("Zabbix api response format error.", ['controller' => __METHOD__]);
                return;
            }
            $result = json_decode($resCheckAuth, true);
            $method = $input['JobArranger']['method'];
            $zabbixResult = [
                'sessionid' => $input["Zabbix"]["auth"],
                'userid' => $input["Zabbix"]["id"]
            ];
            if (!empty($result['result']['sessionid'])) {

                switch ($input['JobArranger']['method']) {
                    case 'jobnetrun':
                        $this->handleJobnetRun($input['JobArranger']['data'], $zabbixResult, $method);
                        break;
                    case 'jobnetstatusrq':
                        $this->handleJobnetGet($input['JobArranger']['data'], $zabbixResult, $method);
                        break;
                    case 'jobarg_joblogput':
                        $this->handleJobLog($input['JobArranger']['data'], $zabbixResult, $method);
                        break;
                    case 'jobarg_jobrelease':
                        $this->handleJobRelease($input['JobArranger']['data'], $zabbixResult, $method);
                        break;
                    default:
                        http_response_code(400);
                        echo $this->errorResponse("Unkown Method", Constants::API_RESPONSE_TYPE_BAD_REQUEST);
                        exit;
                }
            } else {
                $this->logger->error("Check auth fail");
                $this->errorResponse("Auth check fail", Constants::API_RESPONSE_TYPE_INCOMPLETE);
            }
        }
        if ($input["Zabbix"]["method"] == "user.logout") {
            $result = LoginApi::logoutAPI($input["Zabbix"]["auth"]);
            $final = json_decode($result);
            if (isset($final->error)) {
                echo $this->errorResponse($final->error->data, Constants::API_RESPONSE_TYPE_INCOMPLETE);
                $this->logger->info($final->error->data, ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
            } else {
                if ($final->result) {
                    echo Util::response(Constants::API_RESPONSE_TYPE_OK, [Constants::API_RESPONSE_MESSAGE => "User is successfully logout"]);
                    $this->logger->info("User logout process is successfully finished.", ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
                }
            }
        }
    }

    protected function jobExecAuth(string $jobnetId, string $userId1)
    {

        $jobnetControlRes = $this->jobargModuleModel->getJobExecAuth($jobnetId);
        if($jobnetControlRes != null){

            $this->logger->debug("JobnetControl res ". json_encode($jobnetControlRes));
            $username = $jobnetControlRes[0]->user_name;
            $publicFlag = $jobnetControlRes[0]->public_flag;
            $this->logger->info("Username and Public flag". $username. $publicFlag);

            $userId = $this->jobargModuleModel->getUserId($username);
            $this->logger->info('User ID . ' . $userId);

            $user_type = $this->jobargModuleModel->getUserType($userId);
            $this->logger->info("User Type ." . $user_type);

            if ($userId == 0) {
                $this->logger->error("Authentication failed. User Name. " . $username);
                echo $this->errorResponse("User is not found $username", Constants::API_RESPONSE_NOT_FOUND);
            }
            $user_status = $this->jobargModuleModel->checkUserStatus($userId);
            $this->logger->info('User Status. ' . $user_status);

            if ($user_status != 0) {
                    $this->logger->error("Invalid User. User Name. " . $username);
            }

            $user_cmp = 0;
            $checkUserGroup = $this->jobargModuleModel->checkCountUserGroup($userId, $userId);
            $this->logger->info("Check user group". json_encode($checkUserGroup));
            if($checkUserGroup > 0){
                $user_cmp = 1;
            }

            if ($user_type == Constants::USER_TYPE_SUPER || $publicFlag == 1
            || $user_cmp == 1)
            {
                return true;
            }else {
                return false;
            }

        }else {
            echo $this->errorResponse("Jobnet control record not found $jobnetId", Constants::API_RESPONSE_NOT_FOUND);
        }

    }

    protected function handleJobnetRun(array $data, array $zabbixResult, string $method)
    {
        header('Content-Type: application/json');
        $validation = $this->validator->validate($data, [
            'jobnetid' => 'required',
            'username' => 'required',
            'password' => 'required',
        ]);
        if ($validation->fails()) {
            $errors = $validation->errors();
            echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
            $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
        } else {
            try {

                $jobnetId   = $data['jobnetid'];
                $user       = $data['username'];
                $pass       = $data['password'];
                $startTime  = $data['start_time'] ?? null;
                $deterrence = $data['deterrence'] ?? "0";
                $env        = $data['env'] ?? [];
                $env1       = $data['env1'] ?? [];

                $this->logger->debug('Jobnet id . ' . $jobnetId);
                $this->logger->debug('Start Time. ' . $startTime);
                $checkExecAuth = $this->jobExecAuth($jobnetId, $user);
                $this->logger->debug("Check exec auth". $checkExecAuth);
                $this->logger->debug("Deterrence ". $deterrence);
                if($checkExecAuth){

                    if($startTime !== null && $deterrence == 1){

                        if (strlen($startTime) === 12) { // "YYYYMMDDHHMM"
                            $converStartTime = DateTime::createFromFormat('YmdHi', $startTime)->getTimestamp();
                        }
                        $this->logger->debug("Cover Start time". $converStartTime);
                        $checkScheduleJobnetCount = $this->jobargModuleModel->getCountJaRunJobnetTable($converStartTime, $jobnetId);
                        $this->logger->debug("Schedule jobnet count". json_encode($checkScheduleJobnetCount));

                        if($checkScheduleJobnetCount > 0){
                            echo $this->errorResponse("Received message error: Double registration detection of time starting jobnet.",Constants::DETAIL_BAD_REQUEST);
                            return;
                        }

                    }

                    $jobnetControlRes = $this->jobargModuleModel->getJobnetControl($jobnetId);
                    if (count($jobnetControlRes) === 0) {
                        echo $this->errorResponse("Jobnet control result not found ", Constants::API_RESPONSE_MESSAGE_OPERATION_FAIL);
                        exit;
                    }
                    $this->logger->debug("Jobnet control res ". json_encode($jobnetControlRes));

                    // Prepare data for run jobnet insert
                    $result = (object) $this->indexModel->getNextID(Constants::COUNT_INNER_JOBNET_ID);
                    $innerJobnetId = $result->nextid;

                    if ($startTime !== null && $startTime !== '') {
                        $runtype        = Constants::JA_JOBNET_RUN_TYPE_SCHEDULED;
                        $scheduledTime  = $this->util->convertUnixTime($startTime);;
                    } else {
                        $runtype        = Constants::JA_JOBNET_RUN_TYPE_IMMEDIATE;
                        $scheduledTime  = 0;
                    }

                    $runJobnetData = [
                        "update_date"       => $jobnetControlRes[0]->update_date,
                        "public_flag"       => $jobnetControlRes[0]->public_flag,
                        "multiple_start_up" => $jobnetControlRes[0]->multiple_start_up,
                        "jobnet_id"         => $jobnetControlRes[0]->jobnet_id,
                        "user_name"         => $jobnetControlRes[0]->user_name,
                        "jobnet_name"       => $jobnetControlRes[0]->jobnet_name,
                        "memo"              => $jobnetControlRes[0]->memo,
                        "scheduled_time"    => $scheduledTime,
                        "initial_scheduled_time" => $scheduledTime
                    ];

                    $this->logger->info("Run Jobnet Data" . json_encode($runJobnetData));

                    // Insert run jobnet
                    $insertResult = $this->runJobnetModel->insertExternalRunJobnet(
                        $runJobnetData,
                        $runtype,
                        $user,
                        $innerJobnetId
                    );

                    if ($insertResult) {
                        $this->logger->info("after insert jobnet");
                        $this->indexModel->increateNextID(Constants::JOB_EXEC_MANAGEMENT_COUNT_ID);

                        // Ensure $env and $env1 are arrays (avoid null issues)
                        $env = is_array($env) ? $env : [];
                        $env1 = is_array($env1) ? $env1 : [];

                        if (!empty($env1)) {
                            $this->logger->info("Env1 " . json_encode($env1));

                            $newEnv = array_map(function ($value) {
                                if (preg_match('/getHost\((.+)\)/', $value, $matches)) {
                                    $hostRes = $this->jobargModuleModel->getHost($matches[1]);
                                    $this->logger->info("Host res" . json_encode($hostRes));
                                    return $hostRes[0]->ip ?? $value; // fallback to original if no IP
                                }
                                return $value;
                            }, $env1);

                            $this->logger->info("Match array " . json_encode($newEnv));
                        } else {
                            $newEnv = [];
                        }

                        // Combine arrays (if both empty, result is empty array)
                        $combinedEnv = array_merge($env, $newEnv);

                        // JSON encode combined array
                        // $combinedJson = json_encode($combinedEnv);

                        // $this->logger->info("Combined Env JSON: " . $combinedJson);

                        // $this->jobargModuleModel->insertIntoJaRunJobnetVariable($innerJobnetId, $combinedJson);

                        if (!empty($env) || !empty($env1)) {
                            $combinedJson = json_encode($combinedEnv);
                            $this->logger->info("Combined Env JSON: " . $combinedJson);
                            $this->jobargModuleModel->insertIntoJaRunJobnetVariable($innerJobnetId, $combinedJson);
                        } else {
                            $this->logger->info("Both env and env1 are empty; skipping insert.");
                        }

                        $payload = [
                            "registry_number" => $innerJobnetId
                        ];
                        echo $this->buildResponse($zabbixResult, true, $method, $payload);
                    } else {
                        echo $this->errorResponse(Constants::SERVICE_INVALID, Constants::API_RESPONSE_MESSAGE_OPERATION_FAIL);
                        $this->logger->info("Run jobnet is not valid.", ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
                    }

                }else {
                    echo $this->errorResponse("Check exec auth fail", Constants::API_RESPONSE_TYPE_500);
                }
                
            } catch (PDOException $e) {
                echo $this->errorResponse(Constants::SERVICE_INTERNAL_SERVER_ERROR, Constants::API_RESPONSE_TYPE_500);
                $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
            }
            $this->logger->info('Jobnet execution process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
    }

    protected function handleJobnetGet(array $data, array $zabbixResult, string $method)
    {
        $this->logger->debug("Jobnet get start" . json_encode($data));
        $validator = $this->validator;
        $validation = $this->validator->validate($data, [
            'jobnetid' => 'required',
            'username' => 'required',
            'password' => 'required',
        ]);
        if ($validation->fails()) {
            $this->logger->error("Validate fail");
            $errors = $validation->errors();
            echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
            $this->logger->error(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
        } else {
            try {

                $res = $this->getJobnetInfo($data['jobnetid']);
                $this->logger->info("res for get jobnet info " . json_encode($res));
                echo $this->buildResponse($zabbixResult, true, $method, $res, null);
                return;
            } catch (\Exception $e) {
                $this->logger->error("Jobnet get error: " . $e->getMessage(), ['exception' => $e]);
                echo $this->errorResponse("Jobnet get error: " . $e->getMessage(), Constants::API_RESPONSE_TYPE_500);
                exit;
            }
        }
    }

    protected function getJobnetInfo(string|int $registryNumber)
    {
        // $this->logger->info("Registry number .". $registryNumber);
        $jobnetSummary = (array) $this->jobargModuleModel->getJaRunJobnetSummary($registryNumber);
        // $this->logger->info("Jobnet Summary info .". json_encode($jobnetSummary));
        $runType = $status = $jobStatus = $scheduledTime = $startTime = $endTime = $jobnetName = $jobnetId = $innerJobId = $stdOut = $stdErr = $jobExitCd = null;

        if ($jobnetSummary == false) {
            echo $this->errorResponse("registry number not found.", Constants::API_RESPONSE_TYPE_500);
        } else {

            if (is_array($jobnetSummary)) {
                foreach ($jobnetSummary as $index => $jobnet) {
                    $runType        = $jobnet->run_type        ?? '';
                    $status         = $jobnet->status          ?? '';
                    $jobStatus      = $jobnet->job_status      ?? '';
                    $scheduledTime  = $jobnet->scheduled_time  ?? 0;
                    $startTime      = $jobnet->start_time      ?? 0;
                    $endTime        = $jobnet->end_time        ?? 0;
                    $jobnetName     = $jobnet->jobnet_name     ?? '';
                    $jobnetId       = $jobnet->jobnet_id       ?? '';
                    $this->logger->info("Jobnet summary get ". json_encode($jobnet));
                    // $this->logger->info("Result [$index]: run_type=$runType, status=$status, job_status=$jobStatus, scheduled_time=$scheduledTime, start_time=$startTime, end_time=$endTime, jobnet_name=$jobnetName");
                }
            } else {
                $this->logger->error("Jobnet summary is not an array");
            }

            $this->logger->debug("Result : run_type=$runType, status=$status, job_status=$jobStatus, scheduled_time=$scheduledTime, start_time=$startTime, end_time=$endTime, jobnet_name=$jobnetName");
        }

        $jobres = (array) $this->jobargModuleModel->getJaRunJob($registryNumber);
        //$this->logger->info("Job res .". json_encode($jobres));
        if (!empty($jobres)) {
            foreach ($jobres as $job) {
                // Looping through each result in $jobres to get the inner_job_id
                $innerJobId = $job->inner_job_id ?? ''; // Safe check for inner_job_id
                $this->logger->info("Processing Inner job id: " . $innerJobId);

                // Initialize variables to store the last values
                $lastStdOut = '';
                $lastStdErr = '';
                $lastJobExitCd = '';

                // Fetch after variable data for each inner_job_id
                $afterVariableres = (array) $this->jobargModuleModel->getAfterVariable($innerJobId);
                $this->logger->info("after variable res: " . json_encode($afterVariableres));

                // Process the after_variable data if available
                if (!empty($afterVariableres)) {
                    foreach ($afterVariableres as $afterVariable) {
                        // Assuming 'after_variable' is present in the object
                        $afterVariableJson = $afterVariable->after_variable ?? '';
                        $afterVariableArray = json_decode($afterVariableJson, true);

                        // Safely extract values from the decoded array
                        $lastStdOut    = $afterVariableArray['STD_OUT']    ?? '';
                        $lastStdErr    = $afterVariableArray['STD_ERR']    ?? '';
                        $lastJobExitCd = $afterVariableArray['JOB_EXIT_CD'] ?? '';

                        // Update the last seen values
                        $stdOut = $lastStdOut;
                        $stdErr = $lastStdErr;
                        $jobExitCd = $lastJobExitCd;

                        // Optionally log extracted variables for each iteration (if needed)
                        $this->logger->info("Extracted: STD_OUT=$stdOut, STD_ERR=$stdErr, JOB_EXIT_CD=$jobExitCd");
                    }

                    // After the loop, log or return the last values
                    $this->logger->info("Last STD_OUT: $lastStdOut, Last STD_ERR: $lastStdErr, Last JOB_EXIT_CD: $lastJobExitCd");
                } else {
                    $this->logger->info("No before_variable data found for Inner Job ID: $innerJobId");
                }

            }
        } else {
            $this->logger->info("No job result found for status end and job type end");
        }

        $Data = [
            'run_type'       => $runType,
            'status'         => $status,
            'job_status'     => $jobStatus,
            'scheduled_time' => $scheduledTime,
            'start_time'     => $startTime,
            'end_time'       => $endTime,
            'jobnet_name'    => $jobnetName,
            'jobnet_id'      => $jobnetId,
            'inner_job_id'   => $innerJobId,
            'std_out'        => $stdOut,
            'std_err'        => $stdErr,
            'job_exit_cd'    => $jobExitCd,
        ];

        // Option 1: Log as JSON string
        // $this->logger->info('Job info: ' . json_encode($Data));
        return $Data;
    }

    protected function handleJobLog(array $data, array $zabbixResult, string $method)
    {
        // header('Content-Type: application/json');
        header('Content-Type: application/x-ndjson');
        $validation = $this->validator->validate($data, [
            'username' => 'required',
            'password' => 'required',
        ]);
        if ($validation->fails()) {
            $errors = $validation->errors();
            echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
            $this->logger->info(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
        } else {
            try {
                $username   = $data['username'];
                $from_time  = $data['from_time'];
                $to_time    = $data['to_time'];
                $this->logger->info("From time : ". $from_time);
                $this->logger->info("To time : ". $to_time);
                $this->logger->info("Target user : ". $data["target_user"]);
                $registry_number = $data['registry_number'];

                $this->logger->debug('Method . ' . $method);

                $userId = $this->jobargModuleModel->getUserId($username);
                $this->logger->info('User ID . ' . $userId);

                if ($userId == 0) {
                    $this->logger->error("Authentication failed. User Name. " . $username);
                }
                $user_status = $this->jobargModuleModel->checkUserStatus($userId);
                $this->logger->info('User Status. ' . $user_status);

                if ($user_status != 0) {
                    $this->logger->error("Invalid User. User Name. " . $username);
                }

                if ($registry_number === null) {
                    if ($from_time === null || $to_time === null) {
                        $this->logger->error("Can not get from_time and to_time from the input Json.");
                    }
                }

                $user_type = $this->jobargModuleModel->getUserType($userId);
                $this->logger->info("User Type ." . $user_type);

                $user_lang = $this->jobargModuleModel->getUserLang($userId);
                $this->logger->info("User Lang ." . $user_lang);

                // $this->jobargModuleModel->streamJobLogs($data, $user_lang, $user_type, $userId, $zabbixResult);
                try {
                    $this->jobargModuleModel->streamJobLogs($data, $user_lang, $user_type, $userId, $zabbixResult);
                } catch (\Throwable $e) {
                    // Stream the error as NDJSON
                    header('Content-Type: application/x-ndjson');
                    while (ob_get_level() > 0) ob_end_flush();
                    ob_implicit_flush(true);

                    echo json_encode([
                        'JobArranger' => [
                            'result' => false,
                            'error'  => 'Exception: ' . $e->getMessage()
                        ]
                    ], JSON_UNESCAPED_UNICODE) . "\n";
                    flush();
                }

            } catch (PDOException $e) {
                echo $this->errorResponse(Constants::SERVICE_INTERNAL_SERVER_ERROR, Constants::API_RESPONSE_TYPE_500);
                $this->logger->error($e->getMessage(), ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
            }
            $this->logger->info('Job Log Retrieve process is finished.', ['controller' => __METHOD__, 'user' => $_SESSION['userInfo']['userName']]);
        }
    }

    protected function handleJobRelease(array $data, array $zabbixResult, string $method)
    {
        $this->logger->debug("Job release start" . json_encode($data));
        $validator = $this->validator;
        $validation = $this->validator->validate($data, [
            'jobid' => 'required',
            'username' => 'required',
            'password' => 'required',
        ]);
        if ($validation->fails()) {
            $this->logger->error("Validate fail");
            $errors = $validation->errors();
            echo Util::response(Constants::API_RESPONSE_TYPE_BAD_REQUEST, [Constants::API_RESPONSE_MESSAGE => $errors->firstOfAll()]);
            $this->logger->error(Constants::SERVICE_MESSAGE_VALIDATION_FAIL . implode(", ", $errors->firstOfAll()), ['controller' => __METHOD__]);
        } else {
            try {

                $res = $this->jobRelease($data);
                $this->logger->info("Response release : ". json_encode($res));
                echo $this->buildResponse($zabbixResult, true, $method, $res);
                return;
            } catch (\Exception $e) {
                $this->logger->error("Jobnet get error: " . $e->getMessage(), ['exception' => $e]);
                echo $this->errorResponse("Jobnet get error: " . $e->getMessage(), Constants::API_RESPONSE_TYPE_500);
                exit;
            }
        }
    }

        protected function jobRelease(array $data)
    {
        $this->logger->info("Job release data" . json_encode($data));
        $userId = $this->jobargModuleModel->getUserId($data["username"]);
        $this->logger->info('User ID . ' . $userId);
        if ($userId == 0) {
            $this->logger->error("Authentication failed. User Name. " . $data["username"]);
        }

        $user_status = $this->jobargModuleModel->checkUserStatus($userId);
        $this->logger->debug('User Status. ' . $user_status);

        if ($user_status != 0) {
            $this->logger->error("Invalid User. User Name. " . $data["username"]);
        }
        $matchedInnerJobnets = [];
        if ($data["registry_number"] !== "") {
            $checkjobnet = $this->checkAuthJobnet($userId, $data["registry_number"]);
            if ($checkjobnet == 0) {
                $this->logger->error("Check jobnet auth fail");
                return $this->errorResponse("Check jobnet auth fail", Constants::API_RESPONSE_TYPE_500);
            }
            $this->logger->info("Check auth result ". $checkjobnet);
            $matchedInnerJobnets = [];
            $resultSummary = $this->jobargModuleModel->getJobnetSummaryTable($data["registry_number"], $data["jobnetid"]);
            $this->logger->info("Result summary ". json_encode($resultSummary));
            if (!empty($resultSummary)) {
                $this->logger->debug("Registry number". $data["registry_number"]);
                $this->logger->debug("JOB id". $data["jobid"]);
                $innerJobnetId = $data["registry_number"];
                $innerJobidAndStatusAndJobType = $this->jobargModuleModel->getJobnetGetJobId($innerJobnetId, $data["jobnetid"], $data["jobid"]);
                $this->logger->debug("Inner job id and status" . json_encode($innerJobidAndStatusAndJobType));
                $innerJobid = $innerJobidAndStatusAndJobType[0]->inner_job_id;
                $status = $innerJobidAndStatusAndJobType[0]->status;
                $jobType = (int)$innerJobidAndStatusAndJobType[0]->job_type;
                $this->logger->debug("Inner JOb id ". $innerJobid);
                $this->logger->info("Status ". $status);
                $this->logger->info("Job type ". gettype($jobType));
                $this->logger->info("Job type ". $jobType);
                if(empty($innerJobidAndStatusAndJobType)) {
                    $this->errorResponse("can not find the job id and status .", Constants::API_RESPONSE_TYPE_500);
                }else {

                    if($jobType == Constants::JA_JOB_TYPE_JOBNET) {

                        if($status == 0){
                            $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdUpdate($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                            $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                            if($jobReleaseResult){
                                $responseData = [];
                                array_push($responseData, $innerJobnetId);
                                return $responseData;
                            }
                        }
                        if($status == 1) {
                            $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdInsert($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                            $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                            if($jobReleaseResult){
                                $responseData = [];
                                array_push($responseData, $innerJobnetId);
                                return $responseData;
                            }
                        }

                    }else {
                        if($status == 0){
                            $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdUpdate($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                            $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                            if($jobReleaseResult){
                                $responseData = [];
                                array_push($responseData, $innerJobnetId);
                                return $responseData;
                            }
                        }
                        if($status == 1) {
                            $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdInsert($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                            $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                            if($jobReleaseResult){
                                $responseData = [];
                                array_push($responseData, $innerJobnetId);
                                return $responseData;
                            }
                        }

                    }
                }
            }else {

            }
        }else {

                $startTime = $data['start_time'];
                $this->logger->info("Start time ". $startTime);
                // Fetch jobnet summary
                $resultSummary = $this->jobargModuleModel->getInnerJobnetIdAndStartTimeFromJobnetSummary($data['jobnetid']);
                $this->logger->info("Result summary: " . json_encode($resultSummary));

                if (is_string($resultSummary)) {
                    $resultSummary = json_decode($resultSummary, true);
                    if ($resultSummary === null) {
                        $this->logger->error("Failed to decode JSON from result summary");
                        echo $this->errorResponse("Invalid result summary format", Constants::API_RESPONSE_TYPE_500);
                        return;
                    }
                }

                if (!is_array($resultSummary) || empty($resultSummary)) {
                    $this->logger->info("Result summary is not an array or empty");
                    echo $this->errorResponse("There is no running jobnet with jobnet id: " . $data["jobnetid"], Constants::API_RESPONSE_TYPE_500);
                    return;
                }

                if(is_array($resultSummary)){
                    $this->logger->info("Array". gettype($resultSummary));
                }

                // Convert db timestamp to Ymd
                foreach ($resultSummary as $row)
                {

                    $timestamp = (int)$row["start_time"];
                    $innerJobnetId = $row["inner_jobnet_id"];
                    $len = strlen($startTime);
                    if ($len === 8) {
                        $dbDate = date('Ymd', $timestamp);
                    } elseif ($len === 12) {
                        $dbDate = date('YmdHi', $timestamp);
                    } else {
                        $this->logger->warning("Unsupported startTime format: $startTime");
                        echo $this->errorResponse("Unsupported startTime format", Constants::API_RESPONSE_TYPE_500);
                        return;
                    }

                    $this->logger->info("Comparing: DB Date = $dbDate, Input Start Time = $startTime");

                    if ($dbDate === $startTime) {
                        $this->logger->info("Match found for inner_jobnet_id: " . $innerJobnetId);
                        $innerJobidAndStatusAndJobType = $this->jobargModuleModel->getJobnetGetJobId($innerJobnetId, $data["jobnetid"], $data["jobid"]);
                        $this->logger->info("Get job table . ". json_encode($innerJobidAndStatusAndJobType));
                        // Do something if needed
                        $checkjobnet = $this->checkAuthJobnet($userId, $innerJobnetId);
                        if ($checkjobnet == 0) {
                            $this->logger->error("Check jobnet auth fail");
                            return $this->errorResponse("Check jobnet auth fail", Constants::API_RESPONSE_TYPE_500);
                        }
                        $this->logger->info("Check auth result ". $checkjobnet);

                        $innerJobid = $innerJobidAndStatusAndJobType[0]->inner_job_id;
                        $status = $innerJobidAndStatusAndJobType[0]->status;
                        $jobType = (int)$innerJobidAndStatusAndJobType[0]->job_type;
                        $this->logger->debug("Inner JOb id ". $innerJobid);
                        $this->logger->debug("Status ". $status);
                        $this->logger->debug("Job type ". gettype($jobType));
                        $this->logger->debug("Job type ". $jobType);
                        if(empty($innerJobidAndStatusAndJobType)) {
                            $this->errorResponse("can not find the job id and status .", Constants::API_RESPONSE_TYPE_500);
                        }else {

                            if($jobType == Constants::JA_JOB_TYPE_JOBNET) {

                                if($status == 0){
                                    $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdUpdate($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                                    $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                                    if($jobReleaseResult){
                                        $matchedInnerJobnets[] = $innerJobnetId;
                                    }
                                }
                                if($status == 1) {
                                    $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdInsert($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                                    $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                                    if($jobReleaseResult){
                                        $matchedInnerJobnets[] = $innerJobnetId;
                                    }
                                }

                            }else {
                                $this->logger->debug("Zero corret");
                                if($status == 0){
                                    $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdUpdate($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                                    $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                                    if($jobReleaseResult){
                                        $matchedInnerJobnets[] = $innerJobnetId;
                                    }
                                }
                                if($status == 1) {
                                    $jobReleaseResult = $this->jobargModuleModel->jobReleaseJobIdInsert($innerJobid, $innerJobnetId, Constants::RUN_ACTION_ICON_UNHOLD);
                                    $this->logger->debug("Job releasse result ". json_encode($jobReleaseResult));
                                    if($jobReleaseResult){
                                        $matchedInnerJobnets[] = $innerJobnetId;
                                    }
                                }

                            }
                        }
                    }
                }
                if (empty($matchedInnerJobnets)) {
                    return $this->errorResponse("No matching jobnet found", Constants::API_RESPONSE_TYPE_500);
                }

                // Optionally return all matches
                return $matchedInnerJobnets;
                $this->logger->info("Filtered inner jobnet id");


        }
    }

    protected function checkAuthJobnet(int $userid, string $innerJobnetId)
    {
        $this->logger->debug("In checkAuthJobnet()");
    
        if ($userid === 0) {
            return 0;
        }
        $userType = $this->jobargModuleModel->getUserType($userid);
    
        $ret = 1;
        $publicFlag = 0;
        $userCmp = 0;
    
    
        $res = $this->jobargModuleModel->getUsernameAndPublicFlag($innerJobnetId);
        $this->logger->info("Response from ja_2_run_jobnet_table : " . json_encode($res));
    
        if ($res === false || empty($res)) {
            $this->logger->error("Jobnet not found in ja_2_run_jobnet_table. Inner jobnet id: " . $innerJobnetId);
            $ret = 0;
        } else {
            $username = $res['user_name'] ?? null;
            $publicFlag = (int) ($res['public_flag'] ?? 0);
    
            if ($username !== null) {
                $rowUserId = $this->jobargModuleModel->getUserId($username);
    
                if ($this->jobargModuleModel->checkCountUserGroup($rowUserId, $userid) > 0) {
                    $userCmp = 1;
                }
            }
        }
    
    
        if ($ret === 0) {
            return 0;
        }
    
        if ($userType == Constants::USER_TYPE_SUPER || $publicFlag == 1 || $userCmp == 1) {
            return 1;
        }
    
        return 0;
    }

    protected function buildResponse(array $zabbixResult, bool $JazBool, string $method, array $JazResult = null): string
    {
        $this->logger->info("Zabbix result . " . json_encode($zabbixResult));
        // $this->logger->info("Method . ". $method);
        $this->logger->info("Jaz result . " . json_encode($JazResult));
        if ("user.login" == $method) {

            $data = [
                "Zabbix" => [
                    "jsonrpc" => "2.0",
                    "result"  => $zabbixResult['sessionid'],
                    "id"      => $zabbixResult['userid']
                ],
                "JobArranger" => [
                    "result" => $JazBool,
                ]
            ];
        }
        if ("jobnetrun" == $method) {
            $data = [
                "Zabbix" => [
                    "jsonrpc" => "2.0",
                    "result"  => $zabbixResult['sessionid'],
                    "id"      => $zabbixResult['userid']
                ],
                "JobArranger" => [
                    "result" => $JazBool,
                    "registry_number" => $JazResult["registry_number"]
                ],
            ];
        }

        if ("jobnetstatusrq" == $method) {
            $data = [
                "Zabbix" => [
                    "jsonrpc" => "2.0",
                    "result"  => $zabbixResult['sessionid'],
                    "id"      => $zabbixResult['userid']
                ],
                "JobArranger" => [
                    "result" => $JazBool,
                    "runType" => (int)$JazResult["run_type"],
                    "status" => (string)$JazResult["status"],
                    "jobStatus" => (int)$JazResult["jobStatus"],
                    "scheduledTime" => (int)$JazResult["scheduled_time"],
                    "startTime" => (int)$JazResult["start_time"],
                    "endTime" => (int)$JazResult["end_time"],
                    "jobnetName" => (string)$JazResult["jobnet_name"],
                    "jobnetId" => (string)$JazResult["jobnet_id"],
                    "innerJobId" => (string)$JazResult["inner_job_id"],
                    "stdOut" => (string)$JazResult["std_out"],
                    "stdErr" => (string)$JazResult["std_err"],
                    "jobExitCd" => (string)$JazResult["job_exit_cd"],
                ],
            ];
        }

        if ("jobarg_jobrelease" == $method) {
            $data = [
                "Zabbix" => [
                    "jsonrpc" => "2.0",
                    "result"  => $zabbixResult['sessionid'],
                    "id"      => $zabbixResult['userid']
                ],
                "JobArranger" => [
                    "result" => $JazBool,
                    "jobReleaseInnerJobnetId" => $JazResult
                ],
            ];
        }

        $this->logger->info("Data before send go ." . json_encode($data));

        return json_encode($data);
    }

    protected function errorResponse(string $message, string $type)
    {
        $data = [
            "Error" => [
                "type" => $type,
                "message" => $message,
            ]
        ];

        return json_encode($data);
    }
}
