<?php
// header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");

// session_start();
if (session_status() === PHP_SESSION_NONE) session_start();
include '../../helper_functions/data_request.php';

function sendJsonResponseForDoor($statusCode, $data): never
{
    http_response_code($statusCode);
    echo json_encode($data);
    exit;
}

function openDoorWithUrl($requestUrl,$userName,$password)
{
    $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $requestUrl,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPAUTH => CURLAUTH_BASIC | CURLAUTH_DIGEST,
            CURLOPT_HTTPHEADER => array(
                'Authorization: Basic ' . base64_encode( 
                    ($userName ?? '') . ':' . ($password ?? '')
                )
            ),
        ));

        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $response = curl_exec($curl);
        $curlError = curl_error($curl);
        curl_close($curl);
        if(!empty($curlError)){
            return false;
        }
        return true;
}

function openDoorWithSms($dataById, $requestUrl){
    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL => $requestUrl,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($dataById),
        CURLOPT_HTTPHEADER => array(
            'Content-Type: application/json'
        ),
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false
    ));
    $response = curl_exec($curl);
    $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    $error = curl_error($curl);
    curl_close($curl);
    
    if($error) {
        return ['response' => $error, 'httpCode' => 500];
    }
    
    return ['response' => $response, 'httpCode' => $httpCode];
}

try {
    if (isset($_REQUEST['door_id'])) {
        $doorResponse = fetchData('gate_doors', ['id' => $_REQUEST['door_id']]);
        if (empty($doorResponse)) {
            sendJsonResponseForDoor(200, [
                "success" => false,
                "data" =>  "Door not found against this id"
            ]);
        }
        $call_id = $_REQUEST['call_id'];
        $hardwareResponse = fetchData('hardwares_settings', ['assigned_door' => $doorResponse[0]['id']]);
        if (empty($hardwareResponse)) {
            sendJsonResponseForDoor(200, [
                "success" => false,
                "data" =>  "No hardware is assigned to that door"
            ]);
        }
        $open_type = " by using invisble key";
        if(isset($_REQUEST['open_type']) && $_REQUEST['open_type'] == "1"){
            $open_type = " by phone call";
        }
        if(!empty($hardwareResponse[0]) && !empty($hardwareResponse[0]['device_id'])){
            $dataById = fetchDataWithId('hardware_devices', $hardwareResponse[0]['device_id']);
            if($dataById['device_type'] == "SMSIO"){
                $requestUrl = getNodejsUrl();
                if (empty($requestUrl)) {
                    sendJsonResponseForDoor(200, [
                        "success" => false,
                        "data" => "Nodejs Url not found. Please add the url in super admin settings",
                        "message" => $requestUrl
                    ]);
                    exit;
                }
                
                if (empty($_REQUEST['signalwire_id'])) {
                    sendJsonResponseForDoor(200, [
                        "success" => false,
                        "data" => "Signalwire id not found"
                    ]);
                    exit;
                }

                $signalwire_settings = fetchDataWithId('signalwire_settings', $_REQUEST['signalwire_id']);
                if (empty($signalwire_settings)) {
                    sendJsonResponseForDoor(200, [
                        "success" => false,
                        "data" =>  "signalwire settings not found"
                    ]);
                    exit;
                }

                if($dataById['model'] == "UC300"){
                    $message_body = $dataById['password'] . ';' . $hardwareResponse[0]['output'] . ',1,' . $hardwareResponse[0]['sms_duration'];
                }elseif($dataById['model'] == "UC1414"){
                    $message_body = $hardwareResponse[0]['output'] . ' momentary, Reply-STOP-to-opt-out';
                }
                $request_payload = makeSMSRequestPayload($dataById, $message_body, $signalwire_settings);
                $requestResponse = openDoorWithSms($request_payload, $requestUrl);
                if ($requestResponse['httpCode'] !== 200) {
                    sendJsonResponseForDoor(200, [
                        "success" => false,
                        "data" => "Server Error. Command SMS could not be sent. Please try again",
                        "message" => $requestUrl,
                        "signalwire_settings" => $signalwire_settings,
                        "payload" => $request_payload
                    ]);
                    exit;
                } else {
                    $utcTime = new DateTime('now', new DateTimeZone('UTC'));
                    $timestamp = $utcTime->format('Y-m-d H:i:s');
                    $save_snap = storeSnapshotImage($doorResponse[0]['id'], $doorResponse[0]['property_id']);
        
                    $file_name = "";
                    $snap_image = "";
                    if(isset($save_snap['filename']) && !empty($save_snap['filename'])){
                        $file_name = $save_snap['filename'];
                    }
                    if(isset($save_snap['failSnap']) && !empty($save_snap['failSnap'])){
                        $snap_image = $save_snap['failSnap'];
                    }

                    $response = insertData('hardwares_settings_events',  ['eventName' => 'Open', 'eventType' => $dataById['device_type'], 'eventOf' => $hardwareResponse[0]['id'], 'property_id' => $doorResponse[0]['property_id'], 'eventDetail' => 'Door open using ' . $hardwareResponse[0]['output'] . $open_type, 'created_by'  => 2, 'timestamp' => $timestamp, 'file_name' => $file_name, 'camera_snap' => $snap_image, 'call_id' => $call_id]);
                    $last_event_id = getLastInsertId();
                    $last_event_data = fetchDataSingle('hardwares_settings_events', ['id' => $last_event_id]);
        
                    createAuditLog(
                        '2',
                        'SMS Open',
                        'hardwares_settings_events',
                        $last_event_id,
                        null,
                        $doorResponse[0]['property_id'] ?? null,
                        null,
                        json_encode($last_event_data),
                        'Open',
                        'medium',
                        $hardwareResponse[0]['output'] . ' has open' . $open_type,
                    );
                    sendJsonResponseForDoor(200, [
                        "success" => true,
                        "data" => "Command sent successfully. Please wait for the door to open"
                    ]);
                    exit;
                }
            }
        }else {
            sendJsonResponseForDoor(200, [
                "success" => false,
                "data" =>  "Could not find the device"
            ]);
            exit;
        }
        $Url = $hardwareResponse[0]['completeUrl'] . "?" . $hardwareResponse[0]['output'] . "=2";
        $requestResponse = openDoorWithUrl($Url, $dataById['user_name'], $dataById['password']);
        if (!$requestResponse) {
            sendJsonResponseForDoor(200, [
                "success" => false,
                "data" =>  "System error Not able to open the door"
            ]);
            exit;
        } else {
            $utcTime = new DateTime('now', new DateTimeZone('UTC'));
            $timestamp = $utcTime->format('Y-m-d H:i:s');
            $save_snap = storeSnapshotImage($doorResponse[0]['id'], $doorResponse[0]['property_id']);
        
            $file_name = "";
            $snap_image = "";
            if(isset($save_snap['filename']) && !empty($save_snap['filename'])){
                $file_name = $save_snap['filename'];
            }
            if(isset($save_snap['failSnap']) && !empty($save_snap['failSnap'])){
                $snap_image = $save_snap['failSnap'];
            }

            $response = insertData('hardwares_settings_events',  ['eventName' => 'Open', 'eventType' => 'Relay', 'eventOf' => $hardwareResponse[0]['id'], 'property_id' => $doorResponse[0]['property_id'], 'eventDetail' => $hardwareResponse[0]['output'] . ' has open' . $open_type, 'created_by'  => 2, 'timestamp' => $timestamp, 'file_name' => $file_name, 'camera_snap' => $snap_image, 'call_id' => $call_id]);
            $last_event_id = getLastInsertId();
            $last_event_data = fetchDataSingle('hardwares_settings_events', ['id' => $last_event_id]);

            createAuditLog(
                '2',
                'Relay',
                'hardwares_settings_events',
                $last_event_id,
                null,
                $doorResponse[0]['property_id'] ?? null,
                null,
                json_encode($last_event_data),
                $hardwareResponse[0]['output'] . ' has open' . $open_type,
                'medium',
                'Commands'
            );

            sendJsonResponseForDoor(200, [
                "success" => true,
                "data" =>  "You can visit the door now"
            ]);
        }
    } else {
        sendJsonResponseForDoor( 500, ["error" => "door id not found"]);
    }
} catch (\Throwable $th) {
    sendJsonResponseForDoor(500, ["error" => "Server error occurred in open_door.php file: " . $th->getMessage()]);
}

function getNodejsUrl(){
    $response = fetchDataSingle("stream_url");
    $baseUrl = str_replace('\/', '/', $response['stream_url']);
    if(empty($baseUrl)) return false;
    return $baseUrl . '/api/send_sms_to_open_door';
}

function makeSMSRequestPayload($attach_device, $message_body, $signal_wire_setting){
    return [
        "from_number" => $attach_device['invisible_intercom_control_number'],
        "to_number" => $attach_device['sms_io_number'],
        "message_body" => $message_body,
        "project_id" => $signal_wire_setting['project_id'],
        "api_token" => $signal_wire_setting['api_token'],
        "space_url" => $signal_wire_setting['space_url']
    ];
}