<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/*
TODO
	- Update Edit
	- Store Radio Information
	- Upload to clublog (request api key)
*/

class QSO extends CI_Controller {

	function __construct()
	{
		parent::__construct();
		$this->lang->load('qso');

		$this->load->model('user_model');
		if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }
	}

	public function index()
	{
		$this->load->model('cat');
		$this->load->model('stations');
		$this->load->model('logbook_model');
		$this->load->model('user_model');
		$this->load->model('modes');
        $this->load->model('bands');
        if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }

		$data['active_station_profile'] = $this->stations->find_active();
        
		$data['notice'] = false;
		$data['stations'] = $this->stations->all_of_user();
		$data['radios'] = $this->cat->radios();
		$data['query'] = $this->logbook_model->last_custom_paginated(5, 0);
		$data['total_rows'] = $this->logbook_model->last_custom_count();
		$data['total_pages'] = ceil($data['total_rows'] / 5);
		$data['current_page'] = 0;
		$data['limit'] = 5;
		$data['dxcc'] = $this->logbook_model->fetchDxcc();
		$data['iota'] = $this->logbook_model->fetchIota();
		$data['modes'] = $this->modes->active();
		$data['bands'] = $this->bands->get_user_bands_for_qso_entry();
		$data['user_default_band'] = $this->session->userdata('user_default_band');
		$data['sat_active'] = array_search("SAT", $this->bands->get_user_bands(), true);

        $remote_operation_option = $this->user_options_model->get_options(
            'remote_operation',
            array('option_name' => 'enabled', 'option_key' => 'value'),
            $this->session->userdata('user_id')
        )->row();
        $data['isRemoteOperationEnabled'] = isset($remote_operation_option->option_value)
            ? ((string)$remote_operation_option->option_value === 'true' || (string)$remote_operation_option->option_value === '1')
            : (bool)$this->session->userdata('isRemoteOperationEnabled');
		
		// Set user's preferred date format
		if($this->session->userdata('user_date_format')) {
			$data['user_date_format'] = $this->session->userdata('user_date_format');
		} else {
			$data['user_date_format'] = $this->config->item('qso_date_format');
		}

		// Measurement base for frontend bearing/distance calculations
		$data['measurement_base'] = $this->session->userdata('user_measurement_base') ?: $this->config->item('measurement_base');

		$this->load->library('form_validation');

		$this->form_validation->set_rules('start_date', 'Date', 'required');
		$this->form_validation->set_rules('start_time', 'Time', 'required');
		$this->form_validation->set_rules('callsign', 'Callsign', 'required');
		$this->form_validation->set_rules('band', 'Band', 'required');
		$this->form_validation->set_rules('mode', 'Mode', 'required');
		$this->form_validation->set_rules('locator', 'Locator', 'callback_check_locator');

        // [eQSL default msg] GET user options (option_type='eqsl_default_qslmsg'; option_name='key_station_id'; option_key=station_id) //
		$this->load->model('user_options_model');
		$options_object = $this->user_options_model->get_options('eqsl_default_qslmsg',array('option_name'=>'key_station_id','option_key'=>$data['active_station_profile']))->result();
		$data['qslmsg'] = (isset($options_object[0]->option_value))?$options_object[0]->option_value:'';

		// Load QSO form field visibility preferences
		$qso_fields_defaults = [
			'rst' => true, 'name' => true, 'qth' => true, 'locator' => true, 'comment' => true,
			'station_tab' => true, 'freq_tx' => true, 'freq_rx' => true, 'band_rx' => true,
			'transmit_power' => true, 'operator_callsign' => true,
			'general_tab' => true, 'iota' => true, 'sota' => true, 'wwff' => true, 'pota' => true,
			'sig' => true, 'dok' => true, 'usa_state' => true,
			'satellite_tab' => true, 'notes_tab' => true, 'qsl_tab' => true,
			'dxcluster_tab' => true,
		];
		$qso_form_options = $this->user_options_model->get_options('qso_form')->result();
		foreach ($qso_form_options as $qfo_item) {
			if ($qfo_item->option_key == 'visible' && array_key_exists($qfo_item->option_name, $qso_fields_defaults)) {
				$qso_fields_defaults[$qfo_item->option_name] = ($qfo_item->option_value == 'true');
			}
		}
		$data['qso_fields'] = $qso_fields_defaults;

		if ($this->form_validation->run() == FALSE)
		{
			$data['page_title'] = "Add QSO";

			$this->load->view('interface_assets/header', $data);
			$this->load->view('qso/index');
			$this->load->view('interface_assets/footer');
		}
		else
		{
			// Store Basic QSO Info for reuse
			// Put data in an array first, then call set_userdata once.
			// This solves the problem of CI dumping out the session
			// cookie each time set_userdata is called.
			// For more info, see http://bizhole.com/codeigniter-nginx-error-502-bad-gateway/
			// $qso_data = [
			// 18-Jan-2016 - make php v5.3 friendly!
			$qso_data = array(
                'start_date' => $this->input->post('start_date'),
                'start_time' => $this->input->post('start_time'),
                'end_time' => $this->input->post('end_time'),
				'time_stamp' => time(),
				'band' => $this->input->post('band'),
				'band_rx' => $this->input->post('band_rx'),
				'freq' => $this->input->post('freq_display'),
				'freq_rx' => $this->input->post('freq_display_rx'),
				'mode' => $this->input->post('mode'),
				'sat_name' => $this->input->post('sat_name'),
				'sat_mode' => $this->input->post('sat_mode'),
				'prop_mode' => $this->input->post('prop_mode'),
				'radio' => $this->input->post('radio'),
				'station_profile_id' => $this->input->post('station_profile'),
				'operator_callsign' => $this->input->post('operator_callsign'),
				'transmit_power' => $this->input->post('transmit_power')
			);

            $propMode = strtoupper(trim((string)($qso_data['prop_mode'] ?? '')));
            if ($propMode !== 'SAT') {
                $qso_data['sat_name'] = '';
                $qso_data['sat_mode'] = '';
            }
			// ];

			setcookie("radio", $qso_data['radio'], time()+3600*24*99);
			setcookie("station_profile_id", $qso_data['station_profile_id'], time()+3600*24*99);

			$this->session->set_userdata($qso_data);

			// If SAT name is set make it session set to sat
			if($this->input->post('sat_name')) {
        		$this->session->set_userdata('prop_mode', 'SAT');
    		}

			// Add QSO
			// $this->logbook_model->add();
			//change to create_qso function as add and create_qso duplicate functionality
			$this->logbook_model->create_qso();

			// Get last 5 qsos
			$data['query'] = $this->logbook_model->last_custom('5');

			// Set Any Notice Messages
			$data['notice'] = "QSO Added";

			// Load view to create another contact
			$data['page_title'] = "Add QSO";

			$this->load->view('interface_assets/header', $data);
			$this->load->view('qso/index');
			$this->load->view('interface_assets/footer');
		}
	}

	/*
	 * This is used for contest-logging and the ajax-call
	 */
	public function saveqso() {
        $this->load->model('logbook_model');
        $this->logbook_model->create_qso();
    }

    /*
     * AJAX endpoint for QSO entry form to avoid full page reload on save.
     */
    public function ajax_saveqso() {
        $this->load->library('form_validation');
        $this->load->model('logbook_model');

        $this->form_validation->set_rules('start_date', 'Date', 'required');
        $this->form_validation->set_rules('start_time', 'Time', 'required');
        $this->form_validation->set_rules('callsign', 'Callsign', 'required');
        $this->form_validation->set_rules('band', 'Band', 'required');
        $this->form_validation->set_rules('mode', 'Mode', 'required');
        $this->form_validation->set_rules('locator', 'Locator', 'callback_check_locator');

        if ($this->form_validation->run() == FALSE) {
            $validation_errors = array();
            $fields = array('start_date', 'start_time', 'callsign', 'band', 'mode', 'locator');
            foreach ($fields as $field) {
                $field_error = form_error($field, '', '');
                if (!empty($field_error)) {
                    $validation_errors[$field] = strip_tags($field_error);
                }
            }

            return $this->output
                ->set_content_type('application/json')
                ->set_output(json_encode(array(
                    'status' => 'error',
                    'message' => 'Please correct the form errors and try again.',
                    'validation_errors' => $validation_errors,
                )));
        }

        $qso_data = array(
            'start_date' => $this->input->post('start_date'),
            'start_time' => $this->input->post('start_time'),
            'end_time' => $this->input->post('end_time'),
            'time_stamp' => time(),
            'band' => $this->input->post('band'),
            'band_rx' => $this->input->post('band_rx'),
            'freq' => $this->input->post('freq_display'),
            'freq_rx' => $this->input->post('freq_display_rx'),
            'mode' => $this->input->post('mode'),
            'sat_name' => $this->input->post('sat_name'),
            'sat_mode' => $this->input->post('sat_mode'),
            'prop_mode' => $this->input->post('prop_mode'),
            'radio' => $this->input->post('radio'),
            'station_profile_id' => $this->input->post('station_profile'),
            'operator_callsign' => $this->input->post('operator_callsign'),
            'transmit_power' => $this->input->post('transmit_power')
        );

        $propMode = strtoupper(trim((string)($qso_data['prop_mode'] ?? '')));
        if ($propMode !== 'SAT') {
            $qso_data['sat_name'] = '';
            $qso_data['sat_mode'] = '';
        }

        setcookie("radio", $qso_data['radio'], time() + 3600 * 24 * 99);
        setcookie("station_profile_id", $qso_data['station_profile_id'], time() + 3600 * 24 * 99);

        $this->session->set_userdata($qso_data);

        if ($this->input->post('sat_name')) {
            $this->session->set_userdata('prop_mode', 'SAT');
        }

        $this->logbook_model->create_qso();

        return $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode(array(
                'status' => 'ok',
                'message' => 'QSO Added',
            )));
    }

	function edit() {

		$this->load->model('logbook_model');
		$this->load->model('user_model');
		$this->load->model('modes');
		if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }
		
		$qso_id = $this->uri->segment(3);
		
		// Check if user has write permission to this QSO
		if (!$this->logbook_model->check_qso_is_writable($qso_id)) {
			$this->session->set_flashdata('notice', 'You do not have permission to edit this QSO');
			redirect('dashboard');
		}
		
		$query = $this->logbook_model->qso_info($qso_id);

		$this->load->library('form_validation');

		$this->form_validation->set_rules('time_on', 'Start Date', 'required');
		$this->form_validation->set_rules('time_off', 'End Date', 'required');
		$this->form_validation->set_rules('callsign', 'Callsign', 'required');

        $data['qso'] = $query->row();
        $data['dxcc'] = $this->logbook_model->fetchDxcc();
        $data['iota'] = $this->logbook_model->fetchIota();
		$data['modes'] = $this->modes->all();

		if ($this->form_validation->run() == FALSE)
		{
			$this->load->view('qso/edit', $data);
		}
		else
		{
			$this->logbook_model->edit();
			$this->session->set_flashdata('notice', 'Record Updated');
			$this->load->view('qso/edit_done');
		}
	}

    function winkeysettings() {

        // Load model Winkey
        $this->load->model('winkey');
        $this->load->model('stations');
        
        // Get active station profile
        $active_station_id = $this->stations->find_active();

        // call settings from model winkey
        $data['result'] = $this->winkey->settings($this->session->userdata('user_id'), $active_station_id);

        if ($data['result'] == false) {
            $this->load->view('qso/components/winkeysettings', $data);
        } else {
            $this->load->view('qso/components/winkeysettings_results', $data);
        }
    }

    function remoteoperationsettings() {
        $this->load->view('qso/components/remoteoperationsettings');
    }

    public function remoteoperationsecret_json() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $this->load->model('user_options_model');
            $this->load->library('encryption');

            $row = $this->user_options_model->get_options(
                'remote_operation',
                array('option_name' => 'secret', 'option_key' => 'link_password')
            )->row();

            $encrypted = isset($row->option_value) ? (string)$row->option_value : '';
            $plain = '';
            if ($encrypted !== '') {
                $decrypted = $this->encryption->decrypt($encrypted);
                $plain = ($decrypted !== false && $decrypted !== null) ? (string)$decrypted : '';
            }

            echo json_encode(array('status' => 'ok', 'link_password' => $plain));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function remoteoperationsecret_save() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $this->load->model('user_options_model');
            $this->load->library('encryption');

            $link_password = trim((string)$this->security->xss_clean($this->input->post('link_password', true)));

            if ($link_password !== '' && strlen($link_password) < 16) {
                echo json_encode(array('status' => 'error', 'message' => 'Link password must be at least 16 characters'));
                return;
            }

            if ($link_password === '') {
                $this->user_options_model->set_option('remote_operation', 'secret', array('link_password' => ''));
            } else {
                $encrypted = $this->encryption->encrypt($link_password);
                $this->user_options_model->set_option('remote_operation', 'secret', array('link_password' => $encrypted));
            }

            echo json_encode(array('status' => 'ok'));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function cwmacrosave(){
        try {
            // Get the data from the form with proper sanitization
            $function1_name = $this->input->post('function1_name', TRUE);
            $function1_macro = $this->input->post('function1_macro', TRUE);

            $function2_name = $this->input->post('function2_name', TRUE);
            $function2_macro = $this->input->post('function2_macro', TRUE);

            $function3_name = $this->input->post('function3_name', TRUE);
            $function3_macro = $this->input->post('function3_macro', TRUE);

            $function4_name = $this->input->post('function4_name', TRUE);
            $function4_macro = $this->input->post('function4_macro', TRUE);

            $function5_name = $this->input->post('function5_name', TRUE);
            $function5_macro = $this->input->post('function5_macro', TRUE);
            
            // Set empty strings for null values
            $function1_name = $function1_name ? $function1_name : '';
            $function1_macro = $function1_macro ? $function1_macro : '';
            $function2_name = $function2_name ? $function2_name : '';
            $function2_macro = $function2_macro ? $function2_macro : '';
            $function3_name = $function3_name ? $function3_name : '';
            $function3_macro = $function3_macro ? $function3_macro : '';
            $function4_name = $function4_name ? $function4_name : '';
            $function4_macro = $function4_macro ? $function4_macro : '';
            $function5_name = $function5_name ? $function5_name : '';
            $function5_macro = $function5_macro ? $function5_macro : '';
            
            // Basic validation
            if (!$this->session->userdata('user_id')) {
                throw new Exception('User not logged in');
            }
            
            // Load stations model to get active station profile
            $this->load->model('stations');
            $active_station_id = $this->stations->find_active();
            
            if (!$active_station_id || $active_station_id === '0') {
                throw new Exception('No active station profile found. Please set an active station profile.');
            }

            $data = [
            'user_id' => $this->session->userdata('user_id'),
            'station_location_id' => $active_station_id,
			'function1_name'  => $function1_name,
            'function1_macro' => $function1_macro,
            'function2_name'  => $function2_name,
            'function2_macro' => $function2_macro,
            'function3_name'  => $function3_name,
            'function3_macro' => $function3_macro,
            'function4_name'  => $function4_name,
            'function4_macro' => $function4_macro,
            'function5_name'  => $function5_name,
            'function5_macro' => $function5_macro,
		];
		
		// Debug: Log the data being saved
		log_message('debug', 'CW Macros Save Data: ' . print_r($data, true));

            // Load model Winkey
            $this->load->model('winkey');

            // save the data
            $this->winkey->save($data);
            
            // Return a proper success message with proper HTML
            echo '<div class="alert alert-success alert-dismissible fade show" role="alert">
                    <i class="fas fa-check-circle"></i> <strong>Success!</strong> CW Macros saved successfully! The button labels will update when you close this dialog.
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                  </div>';
        } catch (Exception $e) {
            // Return error message if save fails
            echo '<div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <i class="fas fa-exclamation-triangle"></i> <strong>Error!</strong> Failed to save macros: ' . htmlspecialchars($e->getMessage()) . '
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                  </div>';
        } catch (Throwable $t) {
            // Catch any other errors
            log_message('error', 'CW Macros Save Error: ' . $t->getMessage() . ' - File: ' . $t->getFile() . ' - Line: ' . $t->getLine());
            echo '<div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <i class="fas fa-exclamation-triangle"></i> <strong>Error!</strong> An unexpected error occurred while saving macros.
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                  </div>';
        }
    }

    public function cwmacros_test() {
        try {
            $this->load->model('stations');
            $active_station_id = $this->stations->find_active();
            echo "Test successful - User ID: " . $this->session->userdata('user_id') . " Active Station ID: " . $active_station_id;
        } catch (Exception $e) {
            echo "Error: " . $e->getMessage();
        }
    }

    public function cwmacros_json() {
        try {
            // Load model Winkey
            $this->load->model('winkey');

            header('Content-Type: application/json; charset=utf-8');

            $user_id = $this->session->userdata('user_id');
            
            if (!$user_id) {
                echo json_encode(['status' => 'error', 'message' => 'User not logged in']);
                return;
            }
            
            // Load stations model to get active station profile
            $this->load->model('stations');
            $station_id = $this->stations->find_active();
            
            if (!$station_id || $station_id === '0') {
                echo json_encode(['status' => 'error', 'message' => 'No active station profile']);
                return;
            }

            // Call settings_json from model winkey
            echo $this->winkey->settings_json($user_id, $station_id);
        } catch (Exception $e) {
            header('Content-Type: application/json; charset=utf-8');
            echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
        }
    }

    public function winkeyrelaytoken_json() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $this->load->model('user_options_model');
            $result = $this->user_options_model->get_options('winkey_websocket_relay', array('option_name' => 'relay', 'option_key' => 'token'))->result();
            $token = isset($result[0]->option_value) ? (string)$result[0]->option_value : '';

            echo json_encode(array('status' => 'ok', 'token' => $token));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function winkeyrelaytoken_save() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $token = trim((string)$this->security->xss_clean($this->input->post('token', true)));

            if ($token !== '' && strlen($token) < 8) {
                echo json_encode(array('status' => 'error', 'message' => 'Relay token must be at least 8 characters'));
                return;
            }

            $this->load->model('user_options_model');
            $this->user_options_model->set_option('winkey_websocket_relay', 'relay', array('token' => $token));

            echo json_encode(array('status' => 'ok'));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function winkeyrelaysettings_json() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $this->load->model('user_options_model');
            $rows = $this->user_options_model->get_options('winkey_websocket_relay', array('option_name' => 'relay'))->result();

            $settings = array(
                'enabled' => false,
                'url' => 'wss://relay.cloudlog.org/',
                'room' => 'cw_room',
                'token' => '',
            );

            foreach ($rows as $row) {
                if ($row->option_key === 'enabled') {
                    $settings['enabled'] = ((string)$row->option_value === '1');
                } elseif ($row->option_key === 'url' && (string)$row->option_value !== '') {
                    $settings['url'] = (string)$row->option_value;
                } elseif ($row->option_key === 'room' && (string)$row->option_value !== '') {
                    $settings['room'] = (string)$row->option_value;
                } elseif ($row->option_key === 'token') {
                    $settings['token'] = (string)$row->option_value;
                }
            }

            echo json_encode(array('status' => 'ok', 'settings' => $settings));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function winkeyrelaysettings_save() {
        header('Content-Type: application/json; charset=utf-8');

        try {
            $enabled = $this->input->post('enabled', true) === '1';
            $url = trim((string)$this->security->xss_clean($this->input->post('url', true)));
            $room = trim((string)$this->security->xss_clean($this->input->post('room', true)));
            $token = trim((string)$this->security->xss_clean($this->input->post('token', true)));

            if ($url === '') {
                $url = 'wss://relay.cloudlog.org/';
            }

            if ($room === '') {
                $room = 'cw_room';
            }

            if ($enabled) {
                if (!preg_match('/^wss?:\/\//', $url)) {
                    echo json_encode(array('status' => 'error', 'message' => 'Relay URL must start with ws:// or wss://'));
                    return;
                }

                if (strlen($token) < 8) {
                    echo json_encode(array('status' => 'error', 'message' => 'Relay token must be at least 8 characters'));
                    return;
                }
            }

            $this->load->model('user_options_model');
            $this->user_options_model->set_option('winkey_websocket_relay', 'relay', array(
                'enabled' => $enabled ? '1' : '0',
                'url' => $url,
                'room' => $room,
                'token' => $token,
            ));

            echo json_encode(array('status' => 'ok'));
        } catch (Exception $e) {
            echo json_encode(array('status' => 'error', 'message' => $e->getMessage()));
        }
    }

    public function edit_ajax() {

        $this->load->model('logbook_model');
        $this->load->model('user_model');
        $this->load->model('modes');
        $this->load->model('bands');
		$this->load->model('contesting_model');

        $this->load->library('form_validation');

        if(!$this->user_model->authorize(2)) {
            $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard');
        }

        $id = str_replace('"', "", $this->input->post("id"));
        
        // Check if user has write permission to this QSO
        if (!$this->logbook_model->check_qso_is_writable($id)) {
            $this->session->set_flashdata('notice', 'You do not have permission to edit this QSO');
            header('Content-Type: application/json');
            echo json_encode(array('message' => 'not allowed'));
            return;
        }
        
        $query = $this->logbook_model->qso_info($id);

        $data['qso'] = $query->row();
        $data['dxcc'] = $this->logbook_model->fetchDxcc();
        $data['iota'] = $this->logbook_model->fetchIota();
        $data['modes'] = $this->modes->all();
        $data['bands'] = $this->bands->get_user_bands_for_qso_entry(true);
        $data['contest'] = $this->contesting_model->getActivecontests();

        $this->load->view('qso/edit_ajax', $data);
    }

    function qso_save_ajax() {
        $this->load->model('logbook_model');
        $this->load->model('user_model');
        if(!$this->user_model->authorize(2)) {
            $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard');
        }

        $qso_id = $this->input->post('id');
        
        // Check if user has write permission to this QSO
        if (!$this->logbook_model->check_qso_is_writable($qso_id)) {
            header('Content-Type: application/json');
            echo json_encode(array('message' => 'not allowed'));
            return;
        }

        $this->logbook_model->edit();
    }

	function qsl_rcvd($id, $method) {
		$this->load->model('logbook_model');
		$this->load->model('user_model');
		if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }

			// Update Logbook to Mark Paper Card Received

			$this->logbook_model->paperqsl_update($id, $method);

			$this->session->set_flashdata('notice', 'QSL Card: Marked as Received');

			redirect('logbook');
	}

    function qsl_rcvd_ajax() {
        $id = str_replace('"', "", $this->input->post("id"));
        $method = str_replace('"', "", $this->input->post("method"));

        $this->load->model('logbook_model');
        $this->load->model('user_model');

        header('Content-Type: application/json');

        if(!$this->user_model->authorize(2)) {
            echo json_encode(array('message' => 'Error'));

        }
        else {
            // Update Logbook to Mark Paper Card Received
            $this->logbook_model->paperqsl_update($id, $method);

            echo json_encode(array('message' => 'OK'));
        }
    }

    function qsl_sent_ajax() {
        $id = str_replace('"', "", $this->input->post("id"));
        $method = str_replace('"', "", $this->input->post("method"));
        
        $this->load->model('logbook_model');
        $this->load->model('user_model');
        
        header('Content-Type: application/json');
        
        if(!$this->user_model->authorize(2)) {
            echo json_encode(array('message' => 'Error'));
            
        }
        else {
            // Update Logbook to Mark Paper Card Sent
            $this->logbook_model->paperqsl_update_sent($id, $method);
            
            echo json_encode(array('message' => 'OK'));
        }
    }

    function qsl_requested_ajax() {
        $id = str_replace('"', "", $this->input->post("id"));
        $method = str_replace('"', "", $this->input->post("method"));

        $this->load->model('logbook_model');
        $this->load->model('user_model');

        header('Content-Type: application/json');

        if(!$this->user_model->authorize(2)) {
            echo json_encode(array('message' => 'Error'));

        }
        else {
            // Update Logbook to Mark Paper Card Received
            $this->logbook_model->paperqsl_requested($id, $method);

            echo json_encode(array('message' => 'OK'));
        }
    }

	public function qsl_ignore_ajax() {
        $id = str_replace('"', "", $this->input->post("id"));
        $method = str_replace('"', "", $this->input->post("method"));

        $this->load->model('logbook_model');
        $this->load->model('user_model');

        header('Content-Type: application/json');

        if(!$this->user_model->authorize(2)) {
            echo json_encode(array('message' => 'Error'));

        }
        else {
            // Update Logbook to Mark Paper Card Received
            $this->logbook_model->paperqsl_ignore($id, $method);

            echo json_encode(array('message' => 'OK'));
        }
    }

	/* Delete QSO */
	public function delete($id) {
		$this->load->model('logbook_model');

		if ($this->logbook_model->check_qso_is_writable($id)) {
			$this->logbook_model->delete($id);
			$this->session->set_flashdata('notice', 'QSO Deleted Successfully');
			$data['message_title'] = "Deleted";
			$data['message_contents'] = "QSO Deleted Successfully";
			$this->load->view('messages/message', $data);
		} else {
			$this->session->set_flashdata('notice', 'You do not have permission to delete this QSO');
			$data['message_title'] = "Permission Denied";
			$data['message_contents'] = "You do not have permission to delete this QSO";
			$this->load->view('messages/message', $data);
		}

		// If deletes from /logbook dropdown redirect
		if (strpos($_SERVER['HTTP_REFERER'], '/logbook') !== false) {
		    redirect($_SERVER['HTTP_REFERER']);
		}
	}

    /* Delete QSO */
    public function delete_ajax() {
        $id = str_replace('"', "", $this->input->post("id"));

        $this->load->model('logbook_model');
	if ($this->logbook_model->check_qso_is_writable($id)) {
        	$this->logbook_model->delete($id);
        	header('Content-Type: application/json');
        	echo json_encode(array('message' => 'OK'));
	} else {
        	header('Content-Type: application/json');
        	echo json_encode(array('message' => 'not allowed'));
	}
    }

	public function band_to_freq($band, $mode) {

		$this->load->library('frequency');

		echo $this->frequency->convert_band($band, $mode);
	}

	/*
	 * Function is used for autocompletion of SOTA in the QSO entry form
	 */
	public function get_sota() {
		$this->load->library('sota');
		$json = [];

		if (!empty($this->input->get("query"))) {
			$query = $_GET['query'] ?? FALSE;
			$json = $this->sota->get($query);
		}

		header('Content-Type: application/json');
		echo json_encode($json);
	}

	public function get_wwff() {
        $json = [];

        if(!empty($this->input->get("query"))) {
            $query = isset($_GET['query']) ? $_GET['query'] : FALSE;
            $wwff = strtoupper($query);

            $file = 'assets/json/wwff.txt';

            if (is_readable($file)) {
                $lines = file($file, FILE_IGNORE_NEW_LINES);
                $input = preg_quote($wwff, '~');
                $reg = '~^'. $input .'(.*)$~';
                $result = preg_grep($reg, $lines);
                $json = [];
                $i = 0;
                foreach ($result as &$value) {
                    // Limit to 100 as to not slowdown browser too much
                    if (count($json) <= 100) {
                        $json[] = ["name"=>$value];
                    }
                }
            }
        }

        header('Content-Type: application/json');
        echo json_encode($json);
    }

	public function get_pota() {
        $json = [];

        if(!empty($this->input->get("query"))) {
            $query = isset($_GET['query']) ? $_GET['query'] : FALSE;
            $pota = strtoupper($query);

            $file = 'assets/json/pota.txt';

            if (is_readable($file)) {
                $lines = file($file, FILE_IGNORE_NEW_LINES);
                $input = preg_quote($pota, '~');
                $reg = '~^'. $input .'(.*)$~';
                $result = preg_grep($reg, $lines);
                $json = [];
                $i = 0;
                foreach ($result as &$value) {
                    // Limit to 100 as to not slowdown browser too much
                    if (count($json) <= 100) {
                        $json[] = ["name"=>$value];
                    }
                }
            }
        }

        header('Content-Type: application/json');
        echo json_encode($json);
    }

    /*
	 * Function is used for autocompletion of DOK in the QSO entry form
	 */
    public function get_dok() {
        $json = [];

        if(!empty($this->input->get("query"))) {
            $query = isset($_GET['query']) ? $_GET['query'] : FALSE;
            $dok = strtoupper($query);

            $file = 'assets/json/dok.txt';

            if (is_readable($file)) {
                $lines = file($file, FILE_IGNORE_NEW_LINES);
                $input = preg_quote($dok, '~');
                $reg = '~^'. $input .'(.*)$~';
                $result = preg_grep($reg, $lines);
                $json = [];
                $i = 0;
                foreach ($result as &$value) {
                    // Limit to 100 as to not slowdown browser too much
                    if (count($json) <= 100) {
                        $json[] = ["name"=>$value];
                    }
                }
            }
        }

        header('Content-Type: application/json');
        echo json_encode($json);
    }

    /*
	 * Function is used for autocompletion of Counties in the station profile form
	 */
    public function get_county() {
        $json = [];

        if(!empty($this->input->get("query"))) {
            //$query = isset($_GET['query']) ? $_GET['query'] : FALSE;
            $county = $this->input->get("state");
            $cleanedcounty = explode('(', $county);
            $cleanedcounty = trim($cleanedcounty[0]);

            $file = 'assets/json/US_counties.csv';

            if (is_readable($file)) {
                $lines = file($file, FILE_IGNORE_NEW_LINES);
                $input = preg_quote($cleanedcounty, '~');
                $reg = '~^'. $input .'(.*)$~';
                $result = preg_grep($reg, $lines);
                $json = [];
                $i = 0;
                foreach ($result as &$value) {
                    $county = explode(',', $value);
                    // Limit to 100 as to not slowdown browser too much
                    if (count($json) <= 300) {
                        $json[] = ["name"=>$county[1]];
                    }
                }
            }
        }

        header('Content-Type: application/json');
        echo json_encode($json);
    }

   public function get_sota_info() {
      $this->load->library('sota');

      $sota = xss_clean($this->input->post('sota'));

      header('Content-Type: application/json');
      echo $this->sota->info($sota);
   }

   public function get_wwff_info() {
      $this->load->library('wwff');

      $wwff = xss_clean($this->input->post('wwff'));

      header('Content-Type: application/json');
      echo $this->wwff->info($wwff);
   }

   public function get_pota_info() {
      $this->load->library('pota');

      $pota = xss_clean($this->input->post('pota'));

      header('Content-Type: application/json');
      echo $this->pota->info($pota);
   }

   public function get_station_power() {
      $this->load->model('stations');
      $stationProfile = xss_clean($this->input->post('stationProfile'));
      $data = array('station_power' => $this->stations->get_station_power($stationProfile));

      header('Content-Type: application/json');
      echo json_encode($data);
   }

   // Return Previous QSOs Made in the active logbook
   public function component_past_contacts() {
    $this->load->model('logbook_model');
    if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }

    $limit = 5;
    $page = $this->input->get('page') ? (int)$this->input->get('page') : 0;
    $offset = $page * $limit;

    $data['query'] = $this->logbook_model->last_custom_paginated($limit, $offset);
    $data['total_rows'] = $this->logbook_model->last_custom_count();
    $data['total_pages'] = ceil($data['total_rows'] / $limit);
    $data['current_page'] = $page;
    $data['limit'] = $limit;

        // This endpoint is polled by HTMX and must not be cached.
        $this->output->set_header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
        $this->output->set_header('Cache-Control: post-check=0, pre-check=0', false);
        $this->output->set_header('Pragma: no-cache');
        $this->output->set_header('Expires: Sat, 01 Jan 2000 00:00:00 GMT');

    // Load view
    $this->load->view('qso/components/previous_contacts', $data);
   }

   function check_locator($grid) {
      $grid = $this->input->post('locator');
      // Allow empty locator
      if (preg_match('/^$/', $grid)) return true;
      // Allow 6-digit locator
      if (preg_match('/^[A-Ra-r]{2}[0-9]{2}[A-Xa-x]{2}$/', $grid)) return true;
      // Allow 4-digit locator
      else if (preg_match('/^[A-Ra-r]{2}[0-9]{2}$/', $grid)) return true;
      // Allow 4-digit grid line
      else if (preg_match('/^[A-Ra-r]{2}[0-9]{2},[A-Ra-r]{2}[0-9]{2}$/', $grid)) return true;
      // Allow 4-digit grid corner
      else if (preg_match('/^[A-Ra-r]{2}[0-9]{2},[A-Ra-r]{2}[0-9]{2},[A-Ra-r]{2}[0-9]{2},[A-Ra-r]{2}[0-9]{2}$/', $grid)) return true;
      // Allow 2-digit locator
      else if (preg_match('/^[A-Ra-r]{2}$/', $grid)) return true;
      // Allow 8-digit locator
      else if (preg_match('/^[A-Ra-r]{2}[0-9]{2}[A-Xa-x]{2}[0-9]{2}$/', $grid)) return true;
      // Allow 10-digit locator
      else if (preg_match('/^[A-Ra-r]{2}[0-9]{2}[A-Xa-x]{2}[0-9]{2}[A-Xa-x]{2}$/', $grid)) return true;
      else {
         $this->form_validation->set_message('check_locator', 'Please check value for grid locator ('.strtoupper($grid).').');
         return false;
      }
   }
}
