<?php 

/**
 * (c) 2023 iCrewTracker. All rights reserved.
 * 
 * This file is part of the iCrewTracker software suite.
 * Unauthorized copying, modification, distribution, or use of this file, 
 * via any medium, is strictly prohibited. This file is proprietary and confidential.
 * For license information, please see the LICENSE.md file.
 *
 * @author ICREWSYSTEMS SOFTWARE ENGINEERING LLP
 * @contact legal(at)icrewsystems.com 
 * @license UID cbb8060f-5d4c-45aa-8850-f4b8a87d0bcc
 * @package-bundle-hash:fe8Hghmq7t7GsZsW7KzHuTe/38L9upjcIflUqo8C5qr9iv/PeQNS
 */


namespace iCrewTracker\Controllers;

use Exception;
use iCrewTracker\Base\Config;
use iCrewTracker\Models\Acars;
use iCrewTracker\Models\Pilots;
use iCrewTracker\Base\AppContainer;
use iCrewTracker\Base\BaseController;
use iCrewTracker\Models\PositionReports;
use iCrewTracker\Controllers\PilotController;
use iCrewTracker\Models\Schedule;

class ACARSController extends BaseController {
       
        
    /**
     * check_if_pilot_has_linked_network_id_to_va
     *
     * @param  mixed $flight
     * @return void
     */
    private function check_if_pilot_has_linked_network_id_to_va($flight) {
        return AppContainer::make(PilotController::class)->_get_pilot_id_using_network_id($flight['pilot_network_id'], $flight['online']);                                               
    }
    
    /**
     * check_if_schedule_exists_in_va
     *
     * @param  mixed $flight
     * @return void
     */
    private function check_if_schedule_exists_in_va($flight) {

        $schedules = Schedule::where([
        	'code' => mb_substr($flight['flightnum'], 0, 3),
            'flightnum' => mb_substr($flight['flightnum'], 3),
            'depicao' => $flight['depicao'],
            'arricao' => $flight['arricao'],
        ])->first();

        return $schedules;
    }
    
    /**
     * update_acars_data
     *
     * @param  mixed $pilot
     * @param  mixed $flight
     * @return Object
     */
    private function update_acars_data($pilot, $flight) {
       try {
            $update = Acars::updateOrCreate([
                'pilotid' => $pilot['data']['pilotid'],                            
                'flightnum' => $flight['flightnum'],
                'depicao' => $flight['depicao'],
                'arricao' => $flight['arricao'],       
                'online' => 'IVAO',    
                'client' => $flight['client'],
            ], 
            [
                'pilotid' => $pilot['data']['pilotid'],
                'flightnum' => $flight['flightnum'],
                'pilotname' => $pilot['data']['firstname'].' '.$pilot['data']['lastname'],
                'aircraft' => $flight['aircraft'],
                'lat' => $flight['lat'],
                'lng' => $flight['lng'],
                'heading' => $flight['heading'],
                'alt' => $flight['alt'],
                'gs' => $flight['gs'],
                'depicao' => $flight['depicao'],
                'depapt' => $flight['depapt'],
                'arricao' => $flight['arricao'],
                'arrapt' => $flight['arrapt'],
                'deptime' => $flight['deptime'],
                'elapsed_time' => $flight['elapsed_time'],
                'timeremaining' => $flight['timeremaining'],
                'arrtime' => $flight['arrtime'],
                'route' => $flight['route'],
                'route_details' => $flight['route_details'],
                'distremain' => $flight['distremain'],
                'phasedetail' => $flight['phasedetail'],
                'online' => $flight['online'],
                'messagelog' => $flight['messagelog'],
                'lastupdate' => date('Y-m-d H:i:s'),
                'client' => $flight['client'],
            ]);     


            $position_report = PositionReports::create([
                'acarsid' => $update->id,
                'pilotid' => $pilot['data']['pilotid'],
                'flightnum' => $flight['flightnum'],
                'airline' => mb_substr($flight['flightnum'], 0, 3),
                'positiontime' => date('Y-m-d H:i:s'),
                'latitude' => $flight['lat'],
                'longitude' => $flight['lng'],
                'altitude' => $flight['alt'],
                'groundspeed' => $flight['gs'],
                'heading' => $flight['heading'],
                'phase' => $flight['phasedetail'],
            ]);

            return $update;    
       } catch (Exception $e) {
            throw new Exception("Unable to update Acars model. " . $e->getMessage());
       }           
    }

    /**
     * posrep
     * 
     * - Who is flying 
     * - 
     *
     * @return void
     */
    public function posrep() {      
        
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {            
            $data = json_decode(file_get_contents('php://input'));
            // return var_dump($_POST);
            $response = [];

            $response['total_flights_received'] = count($data->form_params->data);
            $response['stats']['success'] = 0;
            $response['stats']['error'] = 0;


            foreach ($data->form_params->data as $flight) {    
                                
                $flight = (array) $flight;      
                $pilot = $this->check_if_pilot_has_linked_network_id_to_va($flight);                                
                // If the pilot ID is linked, the funciton will return an object. Else we can know that the pilot is not linked his account.
                // print_r(gettype($pilot['data']) . "\n");

                if(is_object($pilot['data'])) {        
                    
                    // Check if the schedule is valid
					// Check if the schedule has been bidded
                    // PRO: Create schedule on the fly, like charters? 

                    //TODO IF the names of the airports have special / latin characters, it fails. So sanitize them. 
                                        
                    //CHECK: If the schedule exists in the databse.
                    $check_if_schedule_exists_in_va = $this->check_if_schedule_exists_in_va($flight);
                    if(is_object($check_if_schedule_exists_in_va)) {
                    	// The schedule exists in the VA database.                

                            // CHECK: If the schedule is actually bidded by the pilot.         
                            if($check_if_schedule_exists_in_va->bid != 0) {
                                // Bid exists.

                            } else {
                                // Bid does not exist. 

                            }
                            
                            try {                                            
                                $update = $this->update_acars_data($pilot, $flight);
                                                            
                                if($update->wasRecentlyCreated) {
                                    // If it's a new record on the phpvms_acars table, say "Starting to track" else "Updating"
                                    $response['log'][] = "Success: Starting ACARS tracker for {$flight['flightnum']} on {$flight['online']}, **flown by {$flight['pilot_network_id']}, {$pilot['data']['firstname']} {$pilot['data']['lastname']}**";                    
                                } else {
                                    $response['log'][] = "Success: Position report for {$flight['flightnum']} on {$flight['online']}, **flown by {$flight['pilot_network_id']}, {$pilot['data']['firstname']} {$pilot['data']['lastname']}**";                    
                                }

                                $response['stats']['success']++;
                            } catch (Exception $e) {

                                $response['log'][] = "Exception: {$flight['flightnum']}. {$flight['online']} - {$flight['pilot_network_id']}. {$e->getMessage()}";    
                                $response['stats']['error']++;
                            }                                  
                    } else {
                    	// No schedule was found in the VA database.
	                    $response['log'][] = "Error: {$flight['flightnum']} ({$flight['online']}) could not be processed, pilot network ID match ({$flight['pilot_network_id']} - {$pilot['data']['firstname']} {$pilot['data']['lastname']}) but **schedule was not found in VA database**";                                        	
                    
                    }
                } else {                    
                    $response['log'][] = "Error: {$flight['flightnum']} ({$flight['online']}) could not be processed, **pilot's network ID ({$flight['pilot_network_id']}) was not found in VA database**";                    
                    $response['stats']['error']++;
                }
                                            
            }            


            $response['version'] = Config::get('app')->version;


            return $this->json($response);
        } else {
            throw new Exception("Whoops! Only POST method allowed for this route");
        }
                
    }
    
    
	public function save_to_json($data) {
	    // Check if 'flightnum' exists in the data
	    if (!isset($data['flightnum'])) {
	        throw new Exception('Error while saving PIREP to prefile format: The flightnum key is missing in the data provided to save_to_json() function.');
	    }
	
	    $filename = BASE_PATH . "/prefile/" . $data['pilotid']. '_' .$data['flightnum'] . '.pirep';
	
	    // If the file already exists, return false
	    if (file_exists($filename)) {
	        return false;
	    }
	
	    // Check for write permissions
	    if (!is_writable(dirname($filename))) {
	        throw new Exception('Error while saving PIREP to prefile format: Insufficient permissions to create a file in the directory.');
	    }
	
	    // Since the file doesn't exist, we initialize an empty array for currentData
	    $currentData = [];
	
	    // Append the new data to the current data
	    $currentData[] = $data;
	
	    // Save the data back to the new file
	    // file_put_contents($filename, base64_encode(json_encode($currentData)));
	    file_put_contents($filename, json_encode($currentData, JSON_PRETTY_PRINT));
	
	    // Return true since a new file was created
	    return true;
	}

    
    /**
     * file_pirep
     *
     * @return void
     */
    public function file_pirep() {
    	
    	 if ($_SERVER['REQUEST_METHOD'] === 'POST') {            
            $data = json_decode(file_get_contents('php://input'));
            // return var_dump($_POST);
            $response = [];

		
            $response['total_flights_received'] = count($data->form_params->data);
            $response['stats']['success'] = 0;
            $response['stats']['error'] = 0;
			$response['log'] = [];
			$response['pireps'] = [];
			
	
            foreach ($data->form_params->data as $flight) {    
                $flight = (array) $flight;                     
                
                $network = $flight['network'];
				$network_id = $flight['network_id'];
				$flightnum = $flight['flightnum'];
                
                $pilot = AppContainer::make(PilotController::class)->_get_pilot_id_using_network_id($network_id, $network);
                
                if(is_object($pilot['data'])) {                       
                    try {
                        
						$acars_data = Acars::where([
						        'pilotid' => $pilot['data']['pilotid'],
						        // 'flightnum' => $flightnum, # Disabled during development, enable to during testing. 
								'online' => $network, 
						])->first();
						
						$data =  [
							   'pilotid' => $acars_data->pilotid,
					            'code' => mb_substr($acars_data->flightnum, 0, 3),
					            'flightnum' => $acars_data->flightnum,
					            'depicao' => $acars_data->depicao,
					            'arricao' => $acars_data->arricao,
					            'route' => $acars_data->route,
					            'aircraft' => 7702,
					            'load' => rand(100, 150),
					            'flighttime' => '01:30',
					            'landingrate' => '-100',
					            'submitdate' => date('Y-m-d H:i:s'),
					            'comment' => [],
					            'fuelused' => 5000,
					            'source' => $acars_data->client,
					            'log' => '*iCrewTracker*PIREP LOG*WILL COME HERE',
						    ];
						
						$prefile = $this->save_to_json($data);
						
						if($prefile != false) {
							// $response['pireps'][$flightnum]['pilot'] = $pilot;
							// $response['pireps'][$flightnum]['acars_data'] = $acars_data;
							$response['log'][] = "Success: PIREP prefiled for {$flight['flightnum']} ({$flight['network']}), flown by {$pilot['data']['firstname']} {$pilot['data']['lastname']} ({$network_id})";
	                        $response['stats']['success']++;	
						} else {
							// $response['pireps'][$flightnum]['pilot'] = $pilot;
							// $response['pireps'][$flightnum]['acars_data'] = $acars_data;
							$response['log'][] = "Whoops! prefiled PIREP already available for {$flight['flightnum']} ({$flight['network']}), flown by {$pilot['data']['firstname']} {$pilot['data']['lastname']} ({$network_id})";
	                        $response['stats']['success']++;
						}
						
                    } catch (Exception $e) {
                        $response['log'][] = "Exception: {$flight['flightnum']}. {$flight['network']} - {$flight['pilot_network_id']}. {$e->getMessage()}";    
                        $response['stats']['error']++;
                    }                    
                } else {                    
                    // $response['log'][] = "Error: {$flight['flightnum']} ({$network}) could not be processed, pilot's network ID ({$network_id}) was not found in VA database";                    
                    $response['stats']['error']++;
                }
            }            


            $response['version'] = Config::get('app')->version;
            $response['original_request'] = $data;

			

            return $this->json($response);
        } else {
            throw new Exception("Whoops! Only POST method allowed for this route");
        }
        
        
    }
}
