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

class User extends CI_Controller
{

	function __construct()
	{
		parent::__construct();

		$this->lang->load(array(
			'account',
			'lotw',
			'eqsl',
			'admin',
		));
	}

	/**
	 * Index method for the User controller.
	 * This method loads the user model, authorizes the user, and displays the user accounts.
	 */
	public function index()
	{
		$this->load->model('user_model');

		// Check if the user is authorized
		if (!$this->user_model->authorize(99)) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}

		// Get the user accounts
		$data['results'] = $this->user_model->users();

		// Set the page title
		$data['page_title'] = $this->lang->line('admin_user_accounts');

		// Load the views
		$this->load->view('interface_assets/header', $data);
		$this->load->view('user/main');
		$this->load->view('interface_assets/footer');
	}

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

		$data['existing_languages'] = $this->find();

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

		$this->form_validation->set_rules('user_name', 'Username', 'required');
		$this->form_validation->set_rules('user_email', 'E-mail', 'required');
		$this->form_validation->set_rules('user_password', 'Password', 'required');
		$this->form_validation->set_rules('user_type', 'Type', 'required');
		$this->form_validation->set_rules('user_firstname', 'First name', 'required');
		$this->form_validation->set_rules('user_lastname', 'Last name', 'required');
		$this->form_validation->set_rules('user_callsign', 'Callsign', 'trim|required|callback_check_unique_callsign');
		$this->form_validation->set_rules('user_locator', 'Locator', 'required');
		$this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator');
		$this->form_validation->set_rules('user_timezone', 'Timezone', 'required');

		$data['user_add'] = true;
		$data['user_form_action'] = site_url('user/add');
		$data['bands'] = $this->bands->get_user_bands();

		// Get themes list
		$data['themes'] = $this->user_model->getThemes();

		// Get timezones
		$data['timezones'] = $this->user_model->timezones();
		$data['language'] = 'english';

		// Set defaults
		$data['dashboard_upcoming_dx_card'] = false;
		$data['dashboard_dxpedition_sat_worked'] = false;
		$data['dashboard_qslcard_card'] = false;
		$data['dashboard_eqslcard_card'] = false;
		$data['dashboard_lotw_card'] = false;
		$data['dashboard_vuccgrids_card'] = false;
		$data['dashboard_map_greyline'] = true;

		$dashboard_options = $this->user_options_model->get_options('dashboard')->result();

		foreach ($dashboard_options as $item) {
			$option_name = $item->option_name;
			$option_key = $item->option_key;
			$option_value = $item->option_value;

			if ($option_name == 'dashboard_upcoming_dx_card' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_upcoming_dx_card'] = true;
				} else {
					$data['dashboard_upcoming_dx_card'] = false;
				}
			}

			if ($option_name == 'dashboard_dxpedition_sat_worked' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_dxpedition_sat_worked'] = true;
				} else {
					$data['dashboard_dxpedition_sat_worked'] = false;
				}
			}

			if ($option_name == 'dashboard_qslcards_card' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_qslcard_card'] = true;
				} else {
					$data['dashboard_qslcard_card'] = false;
				}
			}

			if ($option_name == 'dashboard_eqslcards_card' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_eqslcard_card'] = true;
				} else {
					$data['dashboard_eqslcard_card'] = false;
				}
			}

			if ($option_name == 'dashboard_lotw_card' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_lotw_card'] = true;
				} else {
					$data['dashboard_lotw_card'] = false;
				}
			}

			if ($option_name == 'dashboard_vuccgrids_card' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_vuccgrids_card'] = true;
				} else {
					$data['dashboard_vuccgrids_card'] = false;
				}
			}

			if ($option_name == 'dashboard_map_greyline' && $option_key == 'enabled') {
				if ($item->option_value == 'true') {
					$data['dashboard_map_greyline'] = true;
				} else {
					$data['dashboard_map_greyline'] = false;
				}
			}
		}

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

			$this->load->view('interface_assets/header', $data);
			if ($this->input->post('user_name')) {
				$data['user_name'] = $this->input->post('user_name');
				$data['user_email'] = $this->input->post('user_email');
				$data['user_password'] = $this->input->post('user_password');
				$data['user_type'] = $this->input->post('user_type');
				$data['user_firstname'] = $this->input->post('user_firstname');
				$data['user_lastname'] = $this->input->post('user_lastname');
				$data['user_callsign'] = $this->input->post('user_callsign');
				$data['user_locator'] = $this->input->post('user_locator');
				$data['user_timezone'] = $this->input->post('user_timezone');
				$data['user_measurement_base'] = $this->input->post('user_measurement_base');
				$data['user_stylesheet'] = $this->input->post('user_stylesheet');
				$data['user_qth_lookup'] = $this->input->post('user_qth_lookup');
				$data['user_sota_lookup'] = $this->input->post('user_sota_lookup');
				$data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup');
				$data['user_pota_lookup'] = $this->input->post('user_pota_lookup');
				$data['user_show_notes'] = $this->input->post('user_show_notes');
				$data['user_column1'] = $this->input->post('user_column1');
				$data['user_column2'] = $this->input->post('user_column2');
				$data['user_column3'] = $this->input->post('user_column3');
				$data['user_column4'] = $this->input->post('user_column4');
				$data['user_column5'] = $this->input->post('user_column5');
				$data['user_show_profile_image'] = $this->input->post('user_show_profile_image');
				$data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type');
				$data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload');
				$data['user_mastodon_url'] = $this->input->post('user_mastodon_url');
				$data['user_default_band'] = $this->input->post('user_default_band');
				$data['user_default_confirmation'] = ($this->input->post('user_default_confirmation_qsl') !== null ? 'Q' : '') . ($this->input->post('user_default_confirmation_lotw') !== null ? 'L' : '') . ($this->input->post('user_default_confirmation_eqsl') !== null ? 'E' : '') . ($this->input->post('user_default_confirmation_qrz') !== null ? 'Z' : '');
				$data['user_qso_end_times'] = $this->input->post('user_qso_end_times');
				$data['user_quicklog'] = $this->input->post('user_quicklog');
				$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter');
				$data['user_hamsat_key'] = $this->input->post('user_hamsat_key');
				$data['user_hamsat_workable_only'] = $this->input->post('user_hamsat_workable_only');
				$data['user_winkey'] = $this->input->post('user_winkey');
				$data['user_winkey_websocket'] = $this->input->post('user_winkey_websocket');
				$data['user_remote_operation'] = $this->input->post('user_remote_operation');
				$data['language'] = $this->input->post('language');
				$this->load->view('user/edit', $data);
			} else {
				$this->load->view('user/edit', $data);
			}
			$this->load->view('interface_assets/footer');
		} else {
			switch ($this->user_model->add(
				$this->input->post('user_name'),
				$this->input->post('user_password'),
				$this->input->post('user_email'),
				$this->input->post('user_type'),
				$this->input->post('user_firstname'),
				$this->input->post('user_lastname'),
				$this->input->post('user_callsign'),
				$this->input->post('user_locator'),
				$this->input->post('user_timezone'),
				$this->input->post('user_measurement_base'),
				$this->input->post('user_date_format'),
				$this->input->post('user_stylesheet'),
				$this->input->post('user_qth_lookup'),
				$this->input->post('user_sota_lookup'),
				$this->input->post('user_wwff_lookup'),
				$this->input->post('user_pota_lookup'),
				$this->input->post('user_show_notes'),
				$this->input->post('user_column1'),
				$this->input->post('user_column2'),
				$this->input->post('user_column3'),
				$this->input->post('user_column4'),
				$this->input->post('user_column5'),
				$this->input->post('user_show_profile_image'),
				$this->input->post('user_previous_qsl_type'),
				$this->input->post('user_amsat_status_upload'),
				$this->input->post('user_mastodon_url'),
				$this->input->post('user_default_band'),
				($this->input->post('user_default_confirmation_qsl') !== null ? 'Q' : '') . ($this->input->post('user_default_confirmation_lotw') !== null ? 'L' : '') . ($this->input->post('user_default_confirmation_eqsl') !== null ? 'E' : '') . ($this->input->post('user_default_confirmation_qrz') !== null ? 'Z' : ''),
				$this->input->post('user_qso_end_times'),
				$this->input->post('user_quicklog'),
				$this->input->post('user_quicklog_enter'),
				$this->input->post('language'),
				$this->input->post('user_hamsat_key'),
				$this->input->post('user_hamsat_workable_only'),
				$this->input->post('user_callbook_type'),
				$this->input->post('user_callbook_username'),
				$this->input->post('user_callbook_password'),
				$this->input->post('user_winkey'),
				$this->input->post('user_winkey_websocket'),
				$this->input->post('user_remote_operation')
			)) {
				// Check for errors
				case EUSERNAMEEXISTS:
					$data['username_error'] = 'Username <b>' . $this->input->post('user_name') . '</b> already in use!';
					break;
				case EEMAILEXISTS:
					$data['email_error'] = 'E-mail address <b>' . $this->input->post('user_email') . '</b> already in use!';
					break;
				case ECALLSIGNEXISTS:
					$data['callsign_error'] = 'Callsign <b>' . strtoupper($this->input->post('user_callsign')) . '</b> already in use!';
					break;
				case EPASSWORDINVALID:
					$data['password_error'] = 'Invalid password!';
					break;
				// All okay, return to user screen
				case OK:
					// Send welcome email to new user if checkbox is checked
					if ($this->input->post('send_welcome_email') == '1') {
						$this->send_welcome_email(
							$this->input->post('user_email'),
							$this->input->post('user_name'),
							$this->input->post('user_password'),
							$this->input->post('user_firstname'),
							$this->input->post('user_lastname'),
							$this->input->post('user_callsign')
						);
					}
					
					$this->session->set_flashdata('notice', 'User ' . $this->input->post('user_name') . ' added');
					redirect('user');
					return;
			}


			$data['page_title'] = "Users";

			$this->load->view('interface_assets/header', $data);
			$data['user_name'] = $this->input->post('user_name');
			$data['user_email'] = $this->input->post('user_email');
			$data['user_password'] = $this->input->post('user_password');
			$data['user_type'] = $this->input->post('user_type');
			$data['user_firstname'] = $this->input->post('user_firstname');
			$data['user_lastname'] = $this->input->post('user_lastname');
			$data['user_callsign'] = $this->input->post('user_callsign');
			$data['user_locator'] = $this->input->post('user_locator');
			$data['user_measurement_base'] = $this->input->post('user_measurement_base');
			$data['user_stylesheet'] = $this->input->post('user_stylesheet');
			$data['user_qth_lookup'] = $this->input->post('user_qth_lookup');
			$data['user_sota_lookup'] = $this->input->post('user_sota_lookup');
			$data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup');
			$data['user_pota_lookup'] = $this->input->post('user_pota_lookup');
			$data['user_show_notes'] = $this->input->post('user_show_notes');
			$data['user_column1'] = $this->input->post('user_column1');
			$data['user_column2'] = $this->input->post('user_column2');
			$data['user_column3'] = $this->input->post('user_column3');
			$data['user_column4'] = $this->input->post('user_column4');
			$data['user_column5'] = $this->input->post('user_column5');
			$data['user_show_profile_image'] = $this->input->post('user_show_profile_image');
			$data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type');
			$data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload');
			$data['user_mastodon_url'] = $this->input->post('user_mastodon_url');
			$data['user_default_band'] = $this->input->post('user_default_band');
			$data['user_default_confirmation'] = ($this->input->post('user_default_confirmation_qsl') !== null ? 'Q' : '') . ($this->input->post('user_default_confirmation_lotw') !== null ? 'L' : '') . ($this->input->post('user_default_confirmation_eqsl') !== null ? 'E' : '') . ($this->input->post('user_default_confirmation_qrz') !== null ? 'Z' : '');
			$data['user_qso_end_times'] = $this->input->post('user_qso_end_times');
			$data['user_quicklog'] = $this->input->post('user_quicklog');
			$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter');
			$data['language'] = $this->input->post('language');
			$this->load->view('user/edit', $data);
			$this->load->view('interface_assets/footer');
		}
	}

	function find()
	{
		$existing_langs = array();
		$lang_path = APPPATH . 'language';

		$results = scandir($lang_path);

		foreach ($results as $result) {
			if ($result === '.' or $result === '..') continue;

			if (is_dir(APPPATH . 'language' . '/' . $result)) {
				$dirs[] = $result;
			}
		}
		return $dirs;
	}

	function edit()
	{
		$this->load->model('user_model');
		if (($this->session->userdata('user_id') == '') || ((!$this->user_model->authorize(99)) && ($this->session->userdata('user_id') != $this->uri->segment(3)))) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}
		$query = $this->user_model->get_by_id($this->uri->segment(3));

		$data['existing_languages'] = $this->find();

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

		$this->form_validation->set_rules('user_name', 'Username', 'required|xss_clean');
		$this->form_validation->set_rules('user_email', 'E-mail', 'required|xss_clean');
		if ($this->session->userdata('user_type') == 99) {
			$this->form_validation->set_rules('user_type', 'Type', 'required|xss_clean|callback_check_last_admin_role');
		}
		$this->form_validation->set_rules('user_firstname', 'First name', 'required|xss_clean');
		$this->form_validation->set_rules('user_lastname', 'Last name', 'required|xss_clean');
		$this->form_validation->set_rules('user_callsign', 'Callsign', 'trim|required|xss_clean|callback_check_unique_callsign');
		$this->form_validation->set_rules('user_clublog_name', 'Clublog Email', 'callback_check_clublog_email');
		$this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator');
		$this->form_validation->set_rules('user_timezone', 'Timezone', 'required');

		$data['user_form_action'] = site_url('user/edit') . "/" . $this->uri->segment(3);;
		$data['bands'] = $this->bands->get_user_bands();

		// Get themes list
		$data['themes'] = $this->user_model->getThemes();

		// Get timezones
		$data['timezones'] = $this->user_model->timezones();

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

			$q = $query->row();

			$data['id'] = $q->user_id;

			if ($this->input->post('user_name', true)) {
				$data['user_name'] = $this->input->post('user_name', true);
			} else {
				$data['user_name'] = $q->user_name;
			}

			if ($this->input->post('user_email', true)) {
				$data['user_email'] = $this->input->post('user_email', true);
			} else {
				$data['user_email'] = $q->user_email;
			}

			if ($this->input->post('user_password', true)) {
				$data['user_password'] = $this->input->post('user_password', true);
			} else {
				$data['user_password'] = $q->user_password;
			}

			if ($this->input->post('user_type', true)) {
				$data['user_type'] = $this->input->post('user_type', true);
			} else {
				$data['user_type'] = $q->user_type;
			}

			if ($this->input->post('user_callsign', true)) {
				$data['user_callsign'] = $this->input->post('user_callsign', true);
			} else {
				$data['user_callsign'] = $q->user_callsign;
			}

			if ($this->input->post('user_locator', true)) {
				$data['user_locator'] = $this->input->post('user_locator', true);
			} else {
				$data['user_locator'] = $q->user_locator;
			}

			if ($this->input->post('user_firstname', true)) {
				$data['user_firstname'] = $this->input->post('user_firstname', true);
			} else {
				$data['user_firstname'] = $q->user_firstname;
			}

			if ($this->input->post('user_lastname', true)) {
				$data['user_lastname'] = $this->input->post('user_lastname', true);
			} else {
				$data['user_lastname'] = $q->user_lastname;
			}

			if ($this->input->post('user_callsign', true)) {
				$data['user_callsign'] = $this->input->post('user_callsign', true);
			} else {
				$data['user_callsign'] = $q->user_callsign;
			}

			if ($this->input->post('user_locator', true)) {
				$data['user_locator'] = $this->input->post('user_locator', true);
			} else {
				$data['user_locator'] = $q->user_locator;
			}

			if ($this->input->post('user_timezone')) {
				$data['user_timezone'] = $this->input->post('user_timezone', true);
			} else {
				$data['user_timezone'] = $q->user_timezone;
			}

			if ($this->input->post('user_lotw_name')) {
				$data['user_lotw_name'] = $this->input->post('user_lotw_name', true);
			} else {
				$data['user_lotw_name'] = $q->user_lotw_name;
			}

			if ($this->input->post('user_clublog_name')) {
				$data['user_clublog_name'] = $this->input->post('user_clublog_name', true);
			} else {
				$data['user_clublog_name'] = $q->user_clublog_name;
			}

			if ($this->input->post('user_clublog_password')) {
				$data['user_clublog_password'] = $this->input->post('user_clublog_password', true);
			} else {
				$data['user_clublog_password'] = $q->user_clublog_password;
			}

			if ($this->input->post('user_lotw_password')) {
				$data['user_lotw_password'] = $this->input->post('user_lotw_password', true);
			} else {
				$data['user_lotw_password'] = $q->user_lotw_password;
			}

			if ($this->input->post('user_eqsl_name')) {
				$data['user_eqsl_name'] = $this->input->post('user_eqsl_name', true);
			} else {
				$data['user_eqsl_name'] = $q->user_eqsl_name;
			}

			if ($this->input->post('user_eqsl_password')) {
				$data['user_eqsl_password'] = $this->input->post('user_eqsl_password', true);
			} else {
				$data['user_eqsl_password'] = $q->user_eqsl_password;
			}

			if ($this->input->post('user_measurement_base')) {
				$data['user_measurement_base'] = $this->input->post('user_measurement_base', true);
			} else {
				$data['user_measurement_base'] = $q->user_measurement_base;
			}

			if ($this->input->post('user_date_format')) {
				$data['user_date_format'] = $this->input->post('user_date_format', true);
			} else {
				$data['user_date_format'] = $q->user_date_format;
			}

			if ($this->input->post('language')) {
				$data['language'] = $this->input->post('language', true);
			} else {
				$data['language'] = $q->language;
			}


			if ($this->input->post('user_stylesheet')) {
				$data['user_stylesheet'] = $this->input->post('user_stylesheet', true);
			} else {
				$data['user_stylesheet'] = $q->user_stylesheet;
			}

			if ($this->input->post('user_qth_lookup')) {
				$data['user_qth_lookup'] = $this->input->post('user_qth_lookup', true);
			} else {
				$data['user_qth_lookup'] = $q->user_qth_lookup;
			}

			if ($this->input->post('user_sota_lookup')) {
				$data['user_sota_lookup'] = $this->input->post('user_sota_lookup', true);
			} else {
				$data['user_sota_lookup'] = $q->user_sota_lookup;
			}

			if ($this->input->post('user_wwff_lookup')) {
				$data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup', true);
			} else {
				$data['user_wwff_lookup'] = $q->user_wwff_lookup;
			}

			if ($this->input->post('user_pota_lookup')) {
				$data['user_pota_lookup'] = $this->input->post('user_pota_lookup', true);
			} else {
				$data['user_pota_lookup'] = $q->user_pota_lookup;
			}

			if ($this->input->post('user_show_notes')) {
				$data['user_show_notes'] = $this->input->post('user_show_notes', true);
			} else {
				$data['user_show_notes'] = $q->user_show_notes;
			}

			if ($this->input->post('user_qso_end_times')) {
				$data['user_qso_end_times'] = $this->input->post('user_qso_end_times', true);
			} else {
				$data['user_qso_end_times'] = $q->user_qso_end_times;
			}

			if ($this->input->post('user_quicklog')) {
				$data['user_quicklog'] = $this->input->post('user_quicklog', true);
			} else {
				$data['user_quicklog'] = $q->user_quicklog;
			}

			if ($this->input->post('user_quicklog_enter')) {
				$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter', true);
			} else {
				$data['user_quicklog_enter'] = $q->user_quicklog_enter;
			}

			if ($this->input->post('user_show_profile_image')) {
				$data['user_show_profile_image'] = $this->input->post('user_show_profile_image', false);
			} else {
				$data['user_show_profile_image'] = $q->user_show_profile_image;
			}

			if ($this->input->post('user_previous_qsl_type')) {
				$data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type', false);
			} else {
				$data['user_previous_qsl_type'] = $q->user_previous_qsl_type;
			}

			if ($this->input->post('user_amsat_status_upload')) {
				$data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload', false);
			} else {
				$data['user_amsat_status_upload'] = $q->user_amsat_status_upload;
			}

			if ($this->input->post('user_mastodon_url')) {
				$data['user_mastodon_url'] = $this->input->post('user_mastodon_url', false);
			} else {
				$data['user_mastodon_url'] = $q->user_mastodon_url;
			}

			if ($this->input->post('user_default_band')) {
				$data['user_default_band'] = $this->input->post('user_default_band', false);
			} else {
				$data['user_default_band'] = $q->user_default_band;
			}

			if ($this->input->post('user_default_confirmation')) {
				$data['user_default_confirmation'] = ($this->input->post('user_default_confirmation_qsl') !== null ? 'Q' : '') . ($this->input->post('user_default_confirmation_lotw') !== null ? 'L' : '') . ($this->input->post('user_default_confirmation_eqsl') !== null ? 'E' : '') . ($this->input->post('user_default_confirmation_qrz') !== null ? 'Z' : '');
			} else {
				$data['user_default_confirmation'] = $q->user_default_confirmation;
			}

			if ($this->input->post('user_column1')) {
				$data['user_column1'] = $this->input->post('user_column1', true);
			} else {
				$data['user_column1'] = $q->user_column1;
			}

			if ($this->input->post('user_column2')) {
				$data['user_column2'] = $this->input->post('user_column2', true);
			} else {
				$data['user_column2'] = $q->user_column2;
			}

			if ($this->input->post('user_column3')) {
				$data['user_column3'] = $this->input->post('user_column3', true);
			} else {
				$data['user_column3'] = $q->user_column3;
			}

			if ($this->input->post('user_column4')) {
				$data['user_column4'] = $this->input->post('user_column4', true);
			} else {
				$data['user_column4'] = $q->user_column4;
			}

			if ($this->input->post('user_column5')) {
				$data['user_column5'] = $this->input->post('user_column5', true);
			} else {
				$data['user_column5'] = $q->user_column5;
			}

			if ($this->input->post('user_winkey')) {
				$data['user_winkey'] = $this->input->post('user_winkey', true);
			} else {
				$data['user_winkey'] = $q->winkey;
			}

			if ($this->input->post('user_winkey_websocket')) {
				$data['user_winkey_websocket'] = $this->input->post('user_winkey_websocket', true);
			} else {
				$data['user_winkey_websocket'] = $q->winkey_websocket;
			}

			if ($this->input->post('user_remote_operation')) {
				$data['user_remote_operation'] = $this->input->post('user_remote_operation', true);
			} else {
				$remote_operation_option = $this->user_options_model->get_options(
					'remote_operation',
					array('option_name' => 'enabled', 'option_key' => 'value'),
					$this->uri->segment(3)
				)->row();
				$data['user_remote_operation'] = isset($remote_operation_option->option_value)
					? (((string)$remote_operation_option->option_value === 'true' || (string)$remote_operation_option->option_value === '1') ? 1 : 0)
					: (isset($q->remote_operation) ? $q->remote_operation : 0);
			}
			
			$this->load->model('user_options_model');
			$callbook_type_object = $this->user_options_model->get_options('callbook')->result();

			if ($this->input->post('user_callbook_type', true)) {
				$data['user_callbook_type'] = $this->input->post('user_callbook_type', true);
			} else {
				if (isset($callbook_type_object[1]->option_value)) {
					$data['user_callbook_type'] = $callbook_type_object[1]->option_value;
				} else {
					$data['user_callbook_type'] = "";
				}
			}


			// Handle user_callbook_username
			if ($this->input->post('user_callbook_username', true)) {
				$data['user_callbook_username'] = $this->input->post('user_callbook_username', true);
			} else {
				if (isset($callbook_type_object[2]->option_value)) {
					$data['user_callbook_username'] = $callbook_type_object[2]->option_value;
				} else {
					$data['user_callbook_username'] = "";
				}
			}

			// Handle user_callbook_password
			if ($this->input->post('user_callbook_password', true)) {
				$data['user_callbook_password'] = $this->input->post('user_callbook_password', true);
			} else {
				if (isset($callbook_type_object[0]->option_value)) {
					$data['user_callbook_password'] = $callbook_type_object[0]->option_value;
				} else {
					$data['user_callbook_password'] = "";
				}
			}


			$this->load->model('user_options_model');
			$hamsat_user_object = $this->user_options_model->get_options('hamsat')->result();

			if ($this->input->post('user_hamsat_key', true)) {
				$data['user_hamsat_key'] = $this->input->post('user_hamsat_key', true);
			} else {
				// get $q->hamsat_key if its set if not null
				if (isset($hamsat_user_object[0]->option_value)) {
					$data['user_hamsat_key'] = $hamsat_user_object[0]->option_value;
				} else {
					$data['user_hamsat_key'] = "";
				}
			}

			if ($this->input->post('user_hamsat_workable_only')) {
				$data['user_hamsat_workable_only'] = $this->input->post('user_hamsat_workable_only', false);
			} else {
				if (isset($hamsat_user_object[1]->option_value)) {
					$data['user_hamsat_workable_only'] = $hamsat_user_object[1]->option_value;
				} else {
					$data['user_hamsat_workable_only'] = "";
				}
			}

			// Set defaults
			$data['dashboard_upcoming_dx_card'] = false;
			$data['dashboard_dxpedition_sat_worked'] = false;
			$data['dashboard_qslcard_card'] = false;
			$data['dashboard_eqslcard_card'] = false;
			$data['dashboard_lotw_card'] = false;
			$data['dashboard_vuccgrids_card'] = false;
			$data['dashboard_map_greyline'] = true;
			$data['menu_show_qsl_cards'] = true;
			$data['menu_show_sstv_images'] = false;

			$dashboard_options = $this->user_options_model->get_options('dashboard')->result();

			foreach ($dashboard_options as $item) {
				$option_name = $item->option_name;
				$option_key = $item->option_key;
				$option_value = $item->option_value;

				if ($option_name == 'dashboard_upcoming_dx_card' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_upcoming_dx_card'] = true;
					} else {
						$data['dashboard_upcoming_dx_card'] = false;
					}
				}

				if ($option_name == 'dashboard_dxpedition_sat_worked' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_dxpedition_sat_worked'] = true;
					} else {
						$data['dashboard_dxpedition_sat_worked'] = false;
					}
				}

				if ($option_name == 'dashboard_qslcards_card' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_qslcard_card'] = true;
					} else {
						$data['dashboard_qslcard_card'] = false;
					}
				}

				if ($option_name == 'dashboard_eqslcards_card' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_eqslcard_card'] = true;
					} else {
						$data['dashboard_eqslcard_card'] = false;
					}
				}

				if ($option_name == 'dashboard_lotw_card' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_lotw_card'] = true;
					} else {
						$data['dashboard_lotw_card'] = false;
					}
				}

				if ($option_name == 'dashboard_vuccgrids_card' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_vuccgrids_card'] = true;
					} else {
						$data['dashboard_vuccgrids_card'] = false;
					}
				}

				if ($option_name == 'dashboard_map_greyline' && $option_key == 'enabled') {
					if ($item->option_value == 'true') {
						$data['dashboard_map_greyline'] = true;
					} else {
						$data['dashboard_map_greyline'] = false;
					}
				}
			}

			$menu_options = $this->user_options_model->get_options('menu')->result();
			foreach ($menu_options as $item) {
				if ($item->option_name == 'show_qsl_cards' && $item->option_key == 'enabled') {
					$data['menu_show_qsl_cards'] = ($item->option_value == 'true');
				}

				if ($item->option_name == 'show_sstv_images' && $item->option_key == 'enabled') {
					$data['menu_show_sstv_images'] = ($item->option_value == 'true');
				}
			}

			// [QSO Form] Load field visibility preferences
			$data['qso_fields'] = [
				'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_opts = $this->user_options_model->get_options('qso_form')->result();
			foreach ($qso_form_opts as $qfo_item) {
				if ($qfo_item->option_key == 'visible' && array_key_exists($qfo_item->option_name, $data['qso_fields'])) {
					$data['qso_fields'][$qfo_item->option_name] = ($qfo_item->option_value == 'true');
				}
			}

			// [MAP Custom] GET user options //
			$this->load->model('user_options_model');
			$options_object = $this->user_options_model->get_options('map_custom')->result();
			if (count($options_object) > 0) {
				foreach ($options_object as $row) {
					if ($row->option_name == 'icon') {
						$option_value = json_decode($row->option_value, true);
						foreach ($option_value as $ktype => $vtype) {
							if ($this->input->post('user_map_' . $row->option_key . '_icon')) {
								$data['user_map_' . $row->option_key . '_' . $ktype] = $this->input->post('user_map_' . $row->option_key . '_' . $ktype, true);
							} else {
								$data['user_map_' . $row->option_key . '_' . $ktype] = $vtype;
							}
						}
					} else {
						$data['user_map_' . $row->option_name . '_' . $row->option_key] = $row->option_value;
					}
				}
			} else {
				$data['user_map_qso_icon'] = "fas fa-dot-circle";
				$data['user_map_qso_color'] = "#FF0000";
				$data['user_map_station_icon'] = "0";
				$data['user_map_station_color'] = "#0000FF";
				$data['user_map_qsoconfirm_icon'] = "0";
				$data['user_map_qsoconfirm_color'] = "#00AA00";
				$data['user_map_gridsquare_show'] = "0";
			}
			$data['map_icon_select'] = array(
				'station' => array('0', 'fas fa-home', 'fas fa-broadcast-tower', 'fas fa-user', 'fas fa-dot-circle'),
				'qso' => array('fas fa-broadcast-tower', 'fas fa-user', 'fas fa-dot-circle'),
				'qsoconfirm' => array('0', 'fas fa-broadcast-tower', 'fas fa-user', 'fas fa-dot-circle', 'fas fa-check-circle')
			);

			$this->load->view('interface_assets/header', $data);
			$this->load->view('user/edit', $data);
			$this->load->view('interface_assets/footer');
		} else {
			unset($data);


			$post_data = $this->input->post();
			if (!isset($post_data['user_winkey'])) {
				$post_data['user_winkey'] = '0';
			}
			if (!isset($post_data['user_winkey_websocket'])) {
				$post_data['user_winkey_websocket'] = '0';
			}
			if (!isset($post_data['user_remote_operation'])) {
				$post_data['user_remote_operation'] = '0';
			}
			switch ($this->user_model->edit($post_data)) {
				// Check for errors
				case EUSERNAMEEXISTS:
					$data['username_error'] = 'Username <b>' . $this->input->post('user_name', true) . '</b> already in use!';
					break;
				case EEMAILEXISTS:
					$data['email_error'] = 'E-mail address <b>' . $this->input->post('user_email', true) . '</b> already in use!';
					break;
				case ECALLSIGNEXISTS:
					$data['callsign_error'] = 'Callsign <b>' . strtoupper($this->input->post('user_callsign', true)) . '</b> already in use!';
					break;
				case ELASTADMIN:
					$data['usertype_error'] = 'At least one admin account must remain. You cannot change the only admin to another role.';
					break;
				case EPASSWORDINVALID:
					$data['password_error'] = 'Invalid password!';
					break;
				// All okay, return to user screen
				case OK:
					if ($this->session->userdata('user_id') == $this->uri->segment(3)) { // Editing own User? Set cookie!
						$cookie = array(

							'name'   => 'language',
							'value'  => $this->input->post('language', true),
							'expire' => time() + 1000,
							'secure' => FALSE

						);
						$this->input->set_cookie($cookie);
					}
					if ($this->session->userdata('user_id') == $this->input->post('id', true)) {

						// Handle user_callbook_password

						if (isset($_POST['user_callbook_password']) && !empty($_POST['user_callbook_password'])) {

							// Handle user_callbook_type
							if (isset($_POST['user_callbook_type'])) {
								$this->user_options_model->set_option('callbook', 'callbook_type', array('value' => $_POST['user_callbook_type']));
							} else {
								$this->user_options_model->set_option('callbook', 'callbook_type', array('value' => ''));
							}

							// Handle user_callbook_username
							if (isset($_POST['user_callbook_username'])) {
								$this->user_options_model->set_option('callbook', 'callbook_username', array('value' => $_POST['user_callbook_username']));
							} else {
								$this->user_options_model->set_option('callbook', 'callbook_username', array('value' => ''));
							}

							// Load the encryption library
							$this->load->library('encryption');

							// Encrypt the password
							$encrypted_password = $this->encryption->encrypt($_POST['user_callbook_password']);

							// Save the encrypted password
							$this->user_options_model->set_option('callbook', 'callbook_password', array('value' => $encrypted_password));

							// if callbook type is QRZ
							if ($_POST['user_callbook_type'] == 'QRZ') {
								// Lookup using QRZ
								$this->load->library('qrz');

								$qrz_session_key = $this->qrz->session($_POST['user_callbook_username'], $_POST['user_callbook_password']);
								$this->session->set_userdata('qrz_session_key', $qrz_session_key);
							} elseif ($_POST['user_callbook_type'] == "HamQTH") {
								$this->load->library('hamqth');
								$hamqth_session_key = $this->hamqth->session($_POST['user_callbook_username'], $_POST['user_callbook_password']);
								$this->session->set_userdata('hamqth_session_key', $hamqth_session_key);
							}

							// Update Session data
							$this->session->set_userdata('callbook_type', $_POST['user_callbook_type']);
							$this->session->set_userdata('callbook_username', $_POST['user_callbook_username']);
							$this->session->set_userdata('callbook_password', $encrypted_password);
						}

						if (isset($_POST['user_dashboard_enable_dxpedition_card'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_upcoming_dx_card', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_upcoming_dx_card', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_dxpedition_sat_worked'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_dxpedition_sat_worked', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_dxpedition_sat_worked', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_enable_qslcards_card'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_qslcards_card', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_qslcards_card', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_enable_eqslcards_card'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_eqslcards_card', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_eqslcards_card', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_enable_lotw_card'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_lotw_card', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_lotw_card', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_enable_vuccgrids_card'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_vuccgrids_card', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_vuccgrids_card', array('enabled' => 'false'));
						}

						if (isset($_POST['user_dashboard_enable_map_greyline'])) {
							$this->user_options_model->set_option('dashboard', 'dashboard_map_greyline', array('enabled' => 'true'));
						} else {
							$this->user_options_model->set_option('dashboard', 'dashboard_map_greyline', array('enabled' => 'false'));
						}

						if (isset($_POST['user_menu_show_sstv_images'])) {
							$this->user_options_model->set_option('menu', 'show_sstv_images', array('enabled' => 'true'));
							$this->session->set_userdata('user_show_sstv_images', true);
						} else {
							$this->user_options_model->set_option('menu', 'show_sstv_images', array('enabled' => 'false'));
							$this->session->set_userdata('user_show_sstv_images', false);
						}

						if (isset($_POST['user_menu_show_qsl_cards'])) {
							$this->user_options_model->set_option('menu', 'show_qsl_cards', array('enabled' => 'true'));
							$this->session->set_userdata('user_show_qsl_cards', true);
						} else {
							$this->user_options_model->set_option('menu', 'show_qsl_cards', array('enabled' => 'false'));
							$this->session->set_userdata('user_show_qsl_cards', false);
						}

						if (isset($post_data['user_remote_operation']) && (string)$post_data['user_remote_operation'] === '1') {
							$this->user_options_model->set_option('remote_operation', 'enabled', array('value' => 'true'));
						} else {
							$this->user_options_model->set_option('remote_operation', 'enabled', array('value' => 'false'));
						}

						// [QSO Form] Save field visibility preferences
						$qso_field_keys = ['rst', 'name', 'qth', 'locator', 'comment',
							'station_tab', 'freq_tx', 'freq_rx', 'band_rx', 'transmit_power', 'operator_callsign',
							'general_tab', 'iota', 'sota', 'wwff', 'pota', 'sig', 'dok', 'usa_state',
							'satellite_tab', 'notes_tab', 'qsl_tab', 'dxcluster_tab'];
						foreach ($qso_field_keys as $qso_key) {
							$this->user_options_model->set_option('qso_form', $qso_key,
								['visible' => isset($_POST['qso_field_' . $qso_key]) ? 'true' : 'false']);
						}

						// [MAP Custom] ADD to user options //
						$array_icon = array('station', 'qso', 'qsoconfirm');
						foreach ($array_icon as $icon) {
							$data_options['user_map_' . $icon . '_icon'] = xss_clean($this->input->post('user_map_' . $icon . '_icon', true));
							$data_options['user_map_' . $icon . '_color'] = xss_clean($this->input->post('user_map_' . $icon . '_color', true));
						}
						$this->load->model('user_options_model');
						if (!empty($data_options['user_map_qso_icon'])) {
							foreach ($array_icon as $icon) {
								$json = json_encode(array('icon' => $data_options['user_map_' . $icon . '_icon'], 'color' => $data_options['user_map_' . $icon . '_color']));
								$this->user_options_model->set_option('map_custom', 'icon', array($icon => $json));
							}
							$this->user_options_model->set_option('map_custom', 'gridsquare', array('show' => xss_clean($this->input->post('user_map_gridsquare_show', true))));
						} else {
							$this->user_options_model->del_option('map_custom', 'icon');
							$this->user_options_model->del_option('map_custom', 'gridsquare');
						}

						$remote_operation_status_message = ((string)$post_data['user_remote_operation'] === '1')
							? 'Remote Operation enabled.'
							: 'Remote Operation disabled.';
						$this->session->set_flashdata('success', lang('account_user') . ' ' . $this->input->post('user_name', true) . ' ' . lang('account_word_edited') . ' ' . $remote_operation_status_message);
						if ($this->session->userdata('user_id') == $this->input->post('id', true)) {
							$this->user_model->update_session($this->input->post('id', true));
						}
						redirect('user/edit/' . $this->uri->segment(3));
					} else {
						$this->session->set_flashdata('success', lang('account_user') . ' ' . $this->input->post('user_name', true) . ' ' . lang('account_word_edited'));
						redirect('user');
					}
					return;
			}
			$data['page_title'] = "Edit User";
			$this->load->view('interface_assets/header', $data);
			$data['user_name'] = $this->input->post('user_name', true);
			$data['user_email'] = $this->input->post('user_email', true);
			$data['user_password'] = $this->input->post('user_password', true);
			$data['user_type'] = $this->input->post('user_type', true);
			$data['user_firstname'] = $this->input->post('user_firstname', true);
			$data['user_lastname'] = $this->input->post('user_lastname', true);
			$data['user_callsign'] = $this->input->post('user_callsign', true);
			$data['user_locator'] = $this->input->post('user_locator', true);
			$data['user_timezone'] = $this->input->post('user_timezone', true);
			$data['user_stylesheet'] = $this->input->post('user_stylesheet');
			$data['user_qth_lookup'] = $this->input->post('user_qth_lookup');
			$data['user_sota_lookup'] = $this->input->post('user_sota_lookup');
			$data['user_wwff_lookup'] = $this->input->post('user_wwff_lookup');
			$data['user_pota_lookup'] = $this->input->post('user_pota_lookup');
			$data['user_show_notes'] = $this->input->post('user_show_notes');
			$data['user_column1'] = $this->input->post('user_column1');
			$data['user_column2'] = $this->input->post('user_column2');
			$data['user_column3'] = $this->input->post('user_column3');
			$data['user_column4'] = $this->input->post('user_column4');
			$data['user_column4'] = $this->input->post('user_column4');
			$data['user_column5'] = $this->input->post('user_column5');
			$data['user_show_profile_image'] = $this->input->post('user_show_profile_image');
			$data['user_previous_qsl_type'] = $this->input->post('user_previous_qsl_type');
			$data['user_amsat_status_upload'] = $this->input->post('user_amsat_status_upload');
			$data['user_mastodon_url'] = $this->input->post('user_mastodon_url');
			$data['user_default_band'] = $this->input->post('user_default_band');
			$data['user_default_confirmation'] = ($this->input->post('user_default_confirmation_qsl') !== null ? 'Q' : '') . ($this->input->post('user_default_confirmation_lotw') !== null ? 'L' : '') . ($this->input->post('user_default_confirmation_eqsl') !== null ? 'E' : '') . ($this->input->post('user_default_confirmation_qrz') !== null ? 'Z' : '');
			$data['user_qso_end_times'] = $this->input->post('user_qso_end_times');
			$data['user_quicklog'] = $this->input->post('user_quicklog');
			$data['user_quicklog_enter'] = $this->input->post('user_quicklog_enter');
			$data['language'] = $this->input->post('language');
			$data['user_winkey'] = $this->input->post('user_winkey');
			$data['user_winkey_websocket'] = $this->input->post('user_winkey_websocket');
			$data['user_hamsat_key'] = $this->input->post('user_hamsat_key');
			$data['user_hamsat_workable_only'] = $this->input->post('user_hamsat_workable_only');



			$this->load->view('user/edit');
			$this->load->view('interface_assets/footer');
		}
	}

	function profile()
	{
		$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');
		}
		$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
		$q = $query->row();
		$data['page_title'] = "Profile";
		$data['user_name'] = $q->user_name;
		$data['user_type'] = $q->user_type;
		$data['user_email'] = $q->user_email;
		$data['user_firstname'] = $q->user_firstname;
		$data['user_lastname'] = $q->user_lastname;
		$data['user_callsign'] = $q->user_callsign;
		$data['user_locator'] = $q->user_locator;

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


	/**
	 * Deletes a user by their ID.
	 *
	 * This function first loads the 'user_model'. It then checks if the current user has the authorization level of 99.
	 * If not, it sets a flash message and redirects the user to the dashboard.
	 * 
	 * If the user is authorized, it gets the user to be deleted by their ID from the URI segment 3.
	 * It then calls the 'delete' function from the 'user_model' with the user ID as a parameter.
	 * 
	 * If the 'delete' function executes successfully, it sets the HTTP status code to 200.
	 * If the 'delete' function fails, it sets the HTTP status code to 500.
	 *
	 * @param int $id The ID of the user to delete.
	 */
	function delete_new($id)
	{
		$this->load->model('user_model');
		if (!$this->user_model->authorize(99)) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}
		$query = $this->user_model->get_by_id($this->uri->segment(3));

		// call $this->user_model->delete and if no errors return true
		if ($this->user_model->delete($id)) {
			// request responds with a 200 status code and empty content
			$this->output->set_status_header(200);
		} else {
			// request responds with a 500 status code and empty content
			$this->output->set_status_header(500);
		}
	}

	function delete()
	{
		$this->load->model('user_model');
		if (!$this->user_model->authorize(99)) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}
		$query = $this->user_model->get_by_id($this->uri->segment(3));

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

		$this->form_validation->set_rules('id', 'user_id', 'required');

		$data = $query->row();

		if ($this->form_validation->run() == FALSE) {

			$this->load->view('interface_assets/header', $data);
			$this->load->view('user/delete');
			$this->load->view('interface_assets/footer');
		} else {
			if ($this->user_model->delete($data->user_id)) {
				$this->session->set_flashdata('notice', 'User deleted');
				redirect('user');
			} else {
				$this->session->set_flashdata('notice', '<b>Database error:</b> Could not delete user!');
				redirect('user');
			}
		}
	}

	function login()
	{
		// Check our version and run any migrations
		$this->load->library('Migration');
		$this->load->library('encryption');

		$this->migration->current();

		$this->load->model('user_model');
		$query = $this->user_model->get($this->input->post('user_name', true));

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

		$this->form_validation->set_rules('user_name', 'Username', 'required');
		$this->form_validation->set_rules('user_password', 'Password', 'required');

		$data['user'] = $query->row();

		// Read the cookie remeber_me and log the user in
		if ($this->input->cookie(config_item('cookie_prefix') . 'remember_me')) {
			try {
				$encrypted_string = $this->input->cookie(config_item('cookie_prefix') . 'remember_me');
				$decrypted_string = $this->encryption->decrypt($encrypted_string);
				$this->user_model->update_session($decrypted_string);
				$this->user_model->set_last_login($decrypted_string);

				log_message('debug', '[User ID: ' . $decrypted_string . '] Remember Me Login Successful');

				redirect('dashboard');
			} catch (Exception $e) {
				// Something went wrong with the cookie
				log_message('error', 'Remember Me Login Failed');
				$this->session->set_flashdata('error', 'Remember Me Login Failed');
				redirect('user/login');
			}
		}

		if ($this->form_validation->run() == FALSE) {
			$data['page_title'] = "Login";
			$this->load->view('interface_assets/mini_header', $data);
			$this->load->view('user/login');
			$this->load->view('interface_assets/footer');
		} else {
			if ($this->user_model->login() == 1) {
				$this->session->set_flashdata('notice', 'User logged in');
				$this->user_model->update_session($data['user']->user_id);
				$this->user_model->set_last_login($data['user']->user_id);
				$cookie = array(

					'name'   => 'language',
					'value'  => $data['user']->language,
					'expire' => time() + 1000,
					'secure' => FALSE

				);

				// Create a remember me cookie
				if ($this->input->post('remember_me') == '1') {
					$encrypted_string = $this->encryption->encrypt($data['user']->user_id);

					$cookie = array(
						'name'   => 'remember_me',
						'value'  => $encrypted_string,
						'expire' => '1209600',
						'secure' => FALSE
					);
					$this->input->set_cookie($cookie);
				}
				redirect('dashboard');
			} else {
				$this->session->set_flashdata('error', 'Incorrect username or password!');
				redirect('user/login');
			}
		}
	}

	// Public signup (open registration)
	public function signup()
	{
		// Gate: open registration must be enabled
		if ($this->config->item('disable_open_registration') || $this->optionslib->get_option('open_registration') != 'true') {
			$this->session->set_flashdata('notice', 'Registration is currently disabled.');
			redirect('user/login');
			return;
		}

		$this->load->helper(array('form', 'url'));
		$this->load->model('user_model');
		$this->load->library('form_validation');

		// Validation rules
		$this->form_validation->set_rules('user_name', 'Username', 'required');
		$this->form_validation->set_rules('user_email', 'E-mail', 'required|valid_email');
		$this->form_validation->set_rules('user_password', 'Password', 'required');
		$this->form_validation->set_rules('user_password_confirm', 'Password Confirmation', 'required|matches[user_password]');
		$this->form_validation->set_rules('user_firstname', 'First name', 'required');
		$this->form_validation->set_rules('user_lastname', 'Last name', 'required');
		$this->form_validation->set_rules('user_callsign', 'Callsign', 'trim|required|callback_check_unique_callsign');
		$this->form_validation->set_rules('user_locator', 'Locator', 'callback_check_locator');
		$this->form_validation->set_rules('user_timezone', 'Timezone', 'required');

		// Timezones for select
		$data['timezones'] = $this->user_model->timezones();
		$data['page_title'] = 'Sign Up';

		if ($this->form_validation->run() == FALSE) {
			// Show form
			$this->load->view('interface_assets/mini_header', $data);
			$this->load->view('user/signup', $data);
			$this->load->view('interface_assets/footer');
			return;
		}

		// Defaults for new users
		$user_type = 3; // operator (per config auth_level)
		$measurement = 'M';
		$user_date_format = 'd/m/y';
		$user_stylesheet = $this->optionslib->get_option('option_theme') ?: 'default';
		$user_qth_lookup = 0;
		$user_sota_lookup = 0;
		$user_wwff_lookup = 0;
		$user_pota_lookup = 0;
		$user_show_notes = 0;
		$user_column1 = '';
		$user_column2 = '';
		$user_column3 = '';
		$user_column4 = '';
		$user_column5 = '';
		$user_show_profile_image = 0;
		$user_previous_qsl_type = '';
		$user_amsat_status_upload = '';
		$user_mastodon_url = '';
		$user_default_band = '';
		$user_default_confirmation = '';
		$user_qso_end_times = 0;
		$user_quicklog = 0;
		$user_quicklog_enter = 1; // 1 = search, 0 = log
		$language = 'english';
		$user_hamsat_key = '';
		$user_hamsat_workable_only = '';
		$callbook_type = '';
		$callbook_username = '';
		$callbook_password = '';

		// Attempt to create user
		switch ($this->user_model->add(
			$this->input->post('user_name', true),
			$this->input->post('user_password', true),
			$this->input->post('user_email', true),
			$user_type,
			$this->input->post('user_firstname', true),
			$this->input->post('user_lastname', true),
			$this->input->post('user_callsign', true),
			$this->input->post('user_locator', true),
			$this->input->post('user_timezone', true),
			$measurement,
			$user_date_format,
			$user_stylesheet,
			$user_qth_lookup,
			$user_sota_lookup,
			$user_wwff_lookup,
			$user_pota_lookup,
			$user_show_notes,
			$user_column1,
			$user_column2,
			$user_column3,
			$user_column4,
			$user_column5,
			$user_show_profile_image,
			$user_previous_qsl_type,
			$user_amsat_status_upload,
			$user_mastodon_url,
			$user_default_band,
			$user_default_confirmation,
			$user_qso_end_times,
			$user_quicklog,
			$user_quicklog_enter,
			$language,
			$user_hamsat_key,
			$user_hamsat_workable_only,
			$callbook_type,
			$callbook_username,
			$callbook_password
		)) {
			case EUSERNAMEEXISTS:
				$data['username_error'] = 'Username <b>' . $this->input->post('user_name', true) . '</b> already in use!';
				break;
			case EEMAILEXISTS:
				$data['email_error'] = 'E-mail address <b>' . $this->input->post('user_email', true) . '</b> already in use!';
				break;
			case ECALLSIGNEXISTS:
				$data['callsign_error'] = 'Callsign <b>' . strtoupper($this->input->post('user_callsign', true)) . '</b> already in use!';
				break;
			case EPASSWORDINVALID:
				$data['password_error'] = 'Invalid password!';
				break;
			case OK:
				// Send a welcome email (without password) if email is configured
				if ($this->optionslib->get_option('emailProtocol') != '') {
					// Fetch newly created user by username
					$new_user_q = $this->user_model->get($this->input->post('user_name', true));
					if ($new_user_q && $new_user_q->num_rows() > 0) {
						$u = $new_user_q->row();

						$this->load->library('email');
						if ($this->optionslib->get_option('emailProtocol') == "smtp") {
							$config = Array(
								'protocol' => $this->optionslib->get_option('emailProtocol'),
								'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
								'smtp_host' => $this->optionslib->get_option('smtpHost'),
								'smtp_port' => $this->optionslib->get_option('smtpPort'),
								'smtp_user' => $this->optionslib->get_option('smtpUsername'),
								'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
								'crlf' => "\r\n",
								'newline' => "\r\n"
							);
							$this->email->initialize($config);
						}

						$email_data = array(
							'username' => $u->user_name,
							'user_firstname' => $u->user_firstname,
							'user_lastname' => $u->user_lastname,
							'callsign' => $u->user_callsign,
							'email' => $u->user_email,
							'base_url' => base_url(),
						);
						$message = $this->load->view('email/welcome_reminder.php', $email_data, TRUE);

						$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
						$this->email->to($u->user_email);
						$this->email->subject('Welcome to Cloudlog');
						$this->email->message($message);
						if (!$this->email->send()) {
							log_message('error', 'Failed to send signup welcome email to ' . $u->user_email . '. Error: ' . $this->email->print_debugger());
						}
					}
				}

				$this->session->set_flashdata('success', 'Account created. You can now log in.');
				redirect('user/login');
				return;
		}

		// If we get here, something went wrong; re-render form with errors
		$this->load->view('interface_assets/mini_header', $data);
		$this->load->view('user/signup', $data);
		$this->load->view('interface_assets/footer');
	}

	function logout()
	{
		$this->load->model('user_model');

		$user_name = $this->session->userdata('user_name');

		// Delete remember_me cookie
		setcookie('remember_me', '', time() - 3600, '/');

		$this->user_model->clear_session();

		$this->session->set_flashdata('notice', 'User ' . $user_name . ' logged out.');
		redirect('dashboard');
	}

	/**
	 * Function: forgot_password
	 *
	 * Allows users to input an email address and a password will be sent to that address.
	 *
	 */
	function forgot_password()
	{

		$this->load->helper(array('form', 'url'));

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

		$this->form_validation->set_rules('email', 'Email', 'required');

		if ($this->form_validation->run() == FALSE) {
			$data['page_title'] = "Forgot Password";
			$this->load->view('interface_assets/mini_header', $data);
			$this->load->view('user/forgot_password');
			$this->load->view('interface_assets/footer');
		} else {
			// Check email address exists
			$this->load->model('user_model');

			$check_email = $this->user_model->check_email_address($this->input->post('email', true));

			if ($check_email == TRUE) {
				// Generate password reset code 50 characters long
				$this->load->helper('string');
				$reset_code = random_string('alnum', 50);

				$this->user_model->set_password_reset_code($this->input->post('email', true), $reset_code);

				// Send email with reset code

				$this->data['reset_code'] = $reset_code;
				$this->load->library('email');

				if ($this->optionslib->get_option('emailProtocol') == "smtp") {
					$config = array(
						'protocol' => $this->optionslib->get_option('emailProtocol'),
						'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
						'smtp_host' => $this->optionslib->get_option('smtpHost'),
						'smtp_port' => $this->optionslib->get_option('smtpPort'),
						'smtp_user' => $this->optionslib->get_option('smtpUsername'),
						'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
						'crlf' => "\r\n",
						'newline' => "\r\n"
					);

					$this->email->initialize($config);
				}

				$message = $this->load->view('email/forgot_password', $this->data,  TRUE);

				$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
				$this->email->to($this->input->post('email', true));

				$this->email->subject('Cloudlog Account Password Reset');
				$this->email->message($message);

				if (!$this->email->send()) {
					// Redirect to login page with message
					$this->session->set_flashdata('warning', 'Email settings are incorrect.');
					redirect('user/login');
				} else {
					// Redirect to login page with message
					$this->session->set_flashdata('notice', 'Password Reset Processed.');
					redirect('user/login');
				}
			} else {
				// No account found just return to login page
				$this->session->set_flashdata('notice', 'Password Reset Processed.');
				redirect('user/login');
			}
		}
	}

	// Send an E-Mail to the user. Function is similar to forgot_password()
	function admin_send_passwort_reset()
	{

		$this->load->model('user_model');
		if (!$this->user_model->authorize(99)) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}
		$query = $this->user_model->get_by_id($this->uri->segment(3));

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

		$this->form_validation->set_rules('id', 'user_id', 'required');

		$data = $query->row();

		if ($this->form_validation->run() != FALSE) {
			$this->session->set_flashdata('notice', 'Something went wrong! User has no user_id.');
			redirect('user');
		} else {
			// Check email address exists
			$this->load->model('user_model');

			$check_email = $this->user_model->check_email_address($data->user_email);

			if ($check_email == TRUE) {
				// Generate password reset code 50 characters long
				$this->load->helper('string');
				$reset_code = random_string('alnum', 50);
				$this->user_model->set_password_reset_code(($data->user_email), $reset_code);

				// Send email with reset code and first Name of the User

				$this->data['reset_code'] = $reset_code;
				$this->data['user_firstname'] = $data->user_firstname; // We can call the user by their first name in the E-Mail
				$this->data['user_callsign'] = $data->user_callsign;
				$this->data['user_name'] = $data->user_name;
				$this->load->library('email');

				if ($this->optionslib->get_option('emailProtocol') == "smtp") {
					$config = array(
						'protocol' => $this->optionslib->get_option('emailProtocol'),
						'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
						'smtp_host' => $this->optionslib->get_option('smtpHost'),
						'smtp_port' => $this->optionslib->get_option('smtpPort'),
						'smtp_user' => $this->optionslib->get_option('smtpUsername'),
						'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
						'crlf' => "\r\n",
						'newline' => "\r\n"
					);

					$this->email->initialize($config);
				}

				$message = $this->load->view('email/admin_reset_password', $this->data,  TRUE);

				$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
				$this->email->to($data->user_email);
				$this->email->subject('Cloudlog Account Password Reset');
				$this->email->message($message);

				if (!$this->email->send()) {
					// Redirect to user page with message
					$this->session->set_flashdata('danger', lang('admin_email_settings_incorrect'));
					redirect('user');
				} else {
					// Redirect to user page with message
					$this->session->set_flashdata('success', lang('admin_password_reset_processed'));
					redirect('user');
				}
			} else {
				// No account found just return to user page
				$this->session->set_flashdata('danger', 'Nothing done. No user found.');
				redirect('user');
			}
		}
	}

	function reset_password($reset_code = NULL)
	{
		$data['reset_code'] = $reset_code;
		if ($reset_code != NULL) {
			$this->load->helper(array('form', 'url'));

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

			$this->form_validation->set_rules('password', 'Password', 'required');
			$this->form_validation->set_rules('password_confirm', 'Password Confirmation', 'required|matches[password]');

			if ($this->form_validation->run() == FALSE) {
				$data['page_title'] = "Reset Password";
				$this->load->view('interface_assets/mini_header', $data);
				$this->load->view('user/reset_password');
				$this->load->view('interface_assets/footer');
			} else {
				// Lets reset the password!
				$this->load->model('user_model');

				$this->user_model->reset_password($this->input->post('password', true), $reset_code);
				$this->session->set_flashdata('notice', 'Password Reset.');
				redirect('user/login');
			}
		} else {
			redirect('user/login');
		}
	}

	function check_clublog_email($email)
	{
		$email = $this->input->post('user_clublog_name');
		// Allow empty email (user may not use Clublog)
		if (empty($email)) return true;
		
		// Validate email format
		if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
			return true;
		} else {
			$this->form_validation->set_message('check_clublog_email', 'Clublog username must be a valid email address as Clublog no longer accepts callsigns as usernames.');
			return false;
		}
	}

	function check_unique_callsign($callsign)
	{
		$this->load->model('user_model');

		$callsign = strtoupper(trim((string) $callsign));
		if ($callsign === '') {
			return true;
		}

		$exclude_user_id = $this->input->post('id', true);
		if ($exclude_user_id === NULL || $exclude_user_id === '') {
			$exclude_user_id = $this->uri->segment(3);
		}

		if ($this->user_model->exists_by_callsign($callsign, $exclude_user_id)) {
			$this->form_validation->set_message('check_unique_callsign', 'The callsign ' . $callsign . ' is already in use.');
			return false;
		}

		return true;
	}

	function check_last_admin_role($user_type)
	{
		$this->load->model('user_model');

		$user_id = $this->input->post('id', true);
		if ($user_id === NULL || $user_id === '') {
			$user_id = $this->uri->segment(3);
		}

		if ($user_id && $this->user_model->would_remove_last_admin($user_id, $user_type)) {
			$this->form_validation->set_message('check_last_admin_role', 'At least one admin account must remain. You cannot change the only admin to another role.');
			return false;
		}

		return true;
	}

	function check_locator($grid)
	{
		$grid = $this->input->post('user_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-Za-z]{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-Za-z]{2}[0-9]{2}$/', $grid)) return true;
		else {
			$this->form_validation->set_message('check_locator', 'Please check value for grid locator (' . strtoupper($grid) . ').');
			return false;
		}
	}

	private function send_welcome_email($email, $username, $password, $firstname, $lastname, $callsign) {
		// Send welcome email to new user with login credentials
		
		// Check if email is configured
		if ($this->optionslib->get_option('emailProtocol') == '') {
			log_message('info', 'Email not configured - skipping welcome email for new user');
			return;
		}
		
		// Load email library
		$this->load->library('email');
		
		// Configure SMTP if needed
		if ($this->optionslib->get_option('emailProtocol') == "smtp") {
			$config = Array(
				'protocol' => $this->optionslib->get_option('emailProtocol'),
				'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
				'smtp_host' => $this->optionslib->get_option('smtpHost'),
				'smtp_port' => $this->optionslib->get_option('smtpPort'),
				'smtp_user' => $this->optionslib->get_option('smtpUsername'),
				'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
				'crlf' => "\r\n",
				'newline' => "\r\n"
			);
			$this->email->initialize($config);
		}
		
		// Prepare email data
		$email_data = array(
			'username' => $username,
			'password' => $password,
			'user_firstname' => $firstname,
			'user_lastname' => $lastname,
			'callsign' => $callsign,
			'email' => $email,
			'base_url' => base_url(),
		);
		
		$message = $this->load->view('email/welcome.php', $email_data, TRUE);
		
		$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
		$this->email->to($email);
		$this->email->subject('Welcome to Cloudlog - Your Account Has Been Created');
		$this->email->message($message);
		
		if (!$this->email->send()) {
			log_message('error', 'Failed to send welcome email to ' . $email . '. Error: ' . $this->email->print_debugger());
		} else {
			log_message('info', 'Welcome email sent to ' . $email);
		}
	}

	public function resend_welcome_email($user_id) {
		// Resend welcome email to existing user (without password)
		$this->load->model('user_model');
		
		// Check authorization
		if (!$this->user_model->authorize(99)) {
			$this->session->set_flashdata('notice', 'You\'re not allowed to do that!');
			redirect('dashboard');
		}
		
		// Get user details
		$user_query = $this->user_model->get_by_id($user_id);
		if ($user_query->num_rows() == 0) {
			$this->session->set_flashdata('danger', 'User not found');
			redirect('user');
			return;
		}
		
		$user = $user_query->row();
		
		// Check if email is configured
		if ($this->optionslib->get_option('emailProtocol') == '') {
			$this->session->set_flashdata('danger', 'Email is not configured. Please configure email settings first.');
			redirect('user');
			return;
		}
		
		// Load email library
		$this->load->library('email');
		
		// Configure SMTP if needed
		if ($this->optionslib->get_option('emailProtocol') == "smtp") {
			$config = Array(
				'protocol' => $this->optionslib->get_option('emailProtocol'),
				'smtp_crypto' => $this->optionslib->get_option('smtpEncryption'),
				'smtp_host' => $this->optionslib->get_option('smtpHost'),
				'smtp_port' => $this->optionslib->get_option('smtpPort'),
				'smtp_user' => $this->optionslib->get_option('smtpUsername'),
				'smtp_pass' => $this->optionslib->get_option('smtpPassword'),
				'crlf' => "\r\n",
				'newline' => "\r\n"
			);
			$this->email->initialize($config);
		}
		
		// Prepare email data (without password)
		$email_data = array(
			'username' => $user->user_name,
			'user_firstname' => $user->user_firstname,
			'user_lastname' => $user->user_lastname,
			'callsign' => $user->user_callsign,
			'email' => $user->user_email,
			'base_url' => base_url(),
		);
		
		// Use the reminder template without password
		$message = $this->load->view('email/welcome_reminder.php', $email_data, TRUE);
		
		$this->email->from($this->optionslib->get_option('emailAddress'), $this->optionslib->get_option('emailSenderName'));
		$this->email->to($user->user_email);
		$this->email->subject('Cloudlog Account Reminder');
		$this->email->message($message);
		
		if (!$this->email->send()) {
			log_message('error', 'Failed to resend welcome email to ' . $user->user_email . '. Error: ' . $this->email->print_debugger());
			$this->session->set_flashdata('danger', 'Failed to send email to ' . $user->user_email);
		} else {
			log_message('info', 'Welcome reminder email sent to ' . $user->user_email);
			$this->session->set_flashdata('success', 'Welcome email sent to ' . $user->user_name . ' (' . $user->user_email . ')');
		}
		
		redirect('user');
	}
}
