<?php

namespace App\Models;

use CodeIgniter\Model;
use App\Models\_approval_chain;
use App\Models\_validator;
use App\Models\_query_reader;
use App\Models\_messenger;

class _person extends Model
{
    #Constructor to set some default values at class load
    public function __construct()
    {
        // parent::__construct();
        helper('form');
        $this->validator = new _validator();
        $this->approval_chain = new _approval_chain();
        $this->query_reader = new _query_reader();
        $this->messenger = new _messenger();
        $this->session = \Config\Services::session();
        $this->db = \Config\Database::connect();
    }
    
    # Add a person's profile
    public function add_profile($profileDetails)
    {
        #Check if this is an admin adding the profile
        $isAdmin = check_access($this, 'add_new_user', 'boolean');
        
        $required = array('firstname', 'lastname', 'emailaddress');
        if (!$isAdmin && $this->session->get('__user_id')) {
            array_push($required, 'birthday', 'nin', 'birthplace');
        }
        
        # 1. Add all provided data into the session
        #If the user is editing, they may not be given the email address, let us add it
        $profileDetails['emailaddress'] = !empty($profileDetails['emailaddress'])? $profileDetails['emailaddress']: ($this->session->get('emailaddress')? $this->session->get('emailaddress'): '');
        $passed = process_fields($this, $profileDetails, $required, array("/"));
        $msg = !empty($passed['msg'])? $passed['msg']: "";
            
        # 2. Save the data into the database
        if ($passed['boolean']) {
            $details = $passed['data'];
            
            # First check if a user with the given email already exists
            $check = $this->query_reader->get_row_as_array('get_user_by_email', array('email_address'=>$details['emailaddress']));
            # Check if a user with the given NIN already exists
            $nin_check = !empty($details['nin'])? $this->db->query("SELECT nin FROM person WHERE nin = ".$this->db->escape($details['nin'])." limit 1")->getRow():null;
            
            if ((empty($check) && !$this->session->get('person_id') && empty($nin_check)) || ($this->session->get('person_id') && (!empty($check) || !empty($nin_check))) || (empty($check) && $isAdmin)) {
                # Determine whether to update the data or to create a new record
                if ($this->session->get('person_id')) {
                    $updateResult = $this->update_profile($this->session->get('person_id'), $details);
                    $result = $updateResult['boolean'];
                    $msg = $updateResult['msg'];
                } else {
                    $details['gender'] = !empty($details['gender'])? $details['gender']: 'unknown';
                    $details['birthday'] = !empty($details['birthday'])? format_date($details['birthday'], 'YYYY-MM-DD'): '0000-00-00';
                    
                    $personId = $this->query_reader->add_data('add_person_data', array('first_name'=>$details['firstname'], 'last_name'=>$details['lastname'], 'gender'=>$details['gender'], 'nin'=>(!empty($details['nin'])? strtoupper($details['nin']):null), 'citizenship_country'=>(!empty($details['citizenship__country'])? $details['citizenship__country']: ''), 'citizenship_type'=>(!empty($details['citizenship__citizentype'])?$details['citizenship__citizentype']: '') , 'marital_status'=>(!empty($details['marital']) ? $details['marital']  : '') , 'date_of_birth'=>$details['birthday'] ));
            
                    if (!empty($personId) || $personId == 0) {
                        $emailContactId = $this->query_reader->add_data('add_contact_data', array('contact_type'=>'email', 'carrier_id'=>'', 'details'=>$details['emailaddress'], 'parent_id'=>$personId, 'parent_type'=>'person'));
                        if (!empty($details['telephone'])) {
                            $phoneContactId = $this->query_reader->add_data('add_contact_data', array('contact_type'=>'telephone', 'carrier_id'=>'', 'details'=>$details['telephone'], 'parent_id'=>$personId, 'parent_type'=>'person'));
                        }
                        
                        # Save the birth place
                        if ($this->session->get('birthplace__addressline')) {
                            $birthPlaceId = $this->add_address($personId, array('address_type'=>'physical', 'importance'=>'birthplace', 'details'=>htmlentities($this->session->get('birthplace__addressline'), ENT_QUOTES), 'district'=>$this->session->get('birthplace__district'), 'country'=>$this->session->get('birthplace__country'), 'county'=>($this->session->get('birthplace__county')? $this->session->get('birthplace__county'): "") ));
                        }
        
                        # 3. Create an account and generate a confirmation code
                        # For the first account, use the user's email address as the login username.
                        $password = generate_temp_password();
                        $userId = $this->query_reader->add_data('add_user_data', array('person_id'=>$personId, 'login_name'=>$details['emailaddress'], 'login_password'=>sha1($password), 'permission_group'=>(!empty($details['role__roles'])? $details['role__roles']: 'Teacher Applicant'), 'status'=>($isAdmin || !empty($details['step1']) || !empty($details['step2'])? 'active':'completed') ));
                        if (empty($userId)) {
                            $msg = "ERROR: We could not create your user record.";
                        } else {
                            $this->session->set('user_id', $userId);
                        }
                    
                        # 4. Send confirmation code to contacts
                        if ($isAdmin) {
                            $result = $this->messenger->send($userId, array('code'=>'introduce_new_user', 'email_from'=>SITE_ADMIN_MAIL, 'from_name'=>SITE_ADMIN_NAME, 'password'=>$password, 'first_name'=>htmlentities($details['firstname'], ENT_QUOTES), 'emailaddress'=>$details['emailaddress'], 'login_link'=>base_url() ), array('email'));
                            if (!$result) {
                                $msg = "ERROR: We could not send the new account email message to the user.";
                            }
                        }
                        #This is a teacher
                        elseif (!empty($details['step1']) || !empty($details['step2'])) {
                            $this->query_reader->run('update_teacher_status', array('user_id'=>$userId, 'status'=>'pending', 'updated_by'=>$userId));
                            
                            $code = generate_person_code($personId);
                            $result = $this->messenger->send($userId, array('code'=>'new_teacher_first_step', 'email_from'=>SIGNUP_EMAIL, 'from_name'=>SITE_GENERAL_NAME, 'verification_code'=>$code, 'password'=>$password, 'first_name'=>htmlentities($details['firstname'], ENT_QUOTES), 'emailaddress'=>$details['emailaddress'], 'login_link'=>base_url() ), array('email'));
                            if (!$result) {
                                #Delete the saved record if any, since the user has no access to their account either way
                                $this->query_reader->run('delete_user_data', array('user_id'=>$userId));
                                $msg = "ERROR: We could not send the email message with your code.";
                            }
                        }
                        # This is a normal application
                        else {
                            $result = $this->messenger->send($userId, array('code'=>'introduce_new_user', 'email_from'=>SITE_ADMIN_MAIL, 'from_name'=>SITE_ADMIN_NAME, 'password'=>$password."<br>This password will not be active until your application has been approved.<br>We will notify you by this same email when your account has been approved.", 'first_name'=>htmlentities($details['firstname'], ENT_QUOTES), 'emailaddress'=>$details['emailaddress'], 'login_link'=>base_url() ), array('email'));
                            
                            if (!$result) {
                                $msg = "ERROR: We could not send the new account email message to your registered emailaddress.";
                            }
                        }
                        
                        if ($result) {
                            $this->session->set('person_id', $personId);
                        }
                    } else {
                        $msg = "ERROR: We could not create your record.";
                    }
                }
            } else {
                // $msg = "WARNING: A user with the email1 entered already exists. Please login or recover your password to continue. ";
                if (!empty($check)) {
                    $msg = "WARNING: A user with the email entered already exists. Please login or recover your password to continue.";
                } elseif (!empty($nin_check)) {
                    $msg = "WARNING: A user with the submitted National Identification Number (NIN) already exists. Please login or recover your password to continue.";
                } elseif (!empty($check) && !empty($nin_check)) {
                    $msg = "WARNING: A user with the submitted National Identification Number (NIN) and email address already exists. Please login or recover your password to continue.";
                }
            }
        } else {
            $msg = !empty($msg)? $msg: "WARNING: Some required fields were left empty or entered with invalid characters. Please recheck your data and submit.";
        }
        
        return array('boolean'=>(!empty($result)? $result: false), 'msg'=>$msg);
    }
    
    
    
    # Add a person's address
    public function add_address($personId, $addressDetails)
    {
        return $this->query_reader->add_data('add_new_address', array('parent_id'=>$personId, 'parent_type'=>'person', 'address_type'=>$addressDetails['address_type'], 'importance'=>$addressDetails['importance'], 'details'=>$addressDetails['details'], 'county'=>$addressDetails['county'], 'district'=>$addressDetails['district'], 'country'=>$addressDetails['country']));
    }
        
    
    
    # Update the person's profile
    public function update_profile($personId, $details)
    {
        $results = array();
        $details['gender'] = !empty($details['gender'])? $details['gender']: 'unknown';
        $details['marital'] = !empty($details['marital'])? $details['marital']: 'unknown';
        $details['birthday'] = !empty($details['birthday'])? format_date($details['birthday'], 'YYYY-MM-DD'): '0000-00-00';
                    
        $result = $this->query_reader->run('update_person_data', array('person_id'=>$personId, 'first_name'=>htmlentities($details['firstname'], ENT_QUOTES), 'last_name'=>htmlentities($details['lastname'], ENT_QUOTES), 'marital_status'=>$details['marital'], 'gender'=>$details['gender'], 'date_of_birth'=>$details['birthday'],
        'nin'=>htmlentities(strtoupper($details['nin']), ENT_QUOTES),'religion'=>empty($details['religion'])? null:htmlentities($details['religion'], ENT_QUOTES),
        'teacherQualCat'=>empty($details['teacherQualCat'])? null:htmlentities($details['teacherQualCat'], ENT_QUOTES),	'emp_school'=>empty($details['emp_school'])? null:htmlentities($details['emp_school'], ENT_QUOTES),
        // 'emis'=>empty($details['emis'])? null:htmlentities($details['emis'], ENT_QUOTES), 
        'title'=>empty($details['title'])? null:htmlentities($details['title'], ENT_QUOTES),	'employmentCat'=>empty($details['employmentCat'])? null:htmlentities($details['employmentCat'], ENT_QUOTES),
        'ipps'=>!empty($details['ipps'])? htmlentities($details['ipps'], ENT_QUOTES):null,	'region'=>empty($details['region'])? null:htmlentities($details['region'], ENT_QUOTES),
        'emp_district'=>empty($details['emp_district'])? null:htmlentities($details['emp_district'], ENT_QUOTES),	'emp_subCounty'=>empty($details['emp_subCounty'])? null:htmlentities($details['emp_subCounty'], ENT_QUOTES), 'gender'=>$details['gender'], 'date_of_birth'=>$details['birthday']));
        array_push($results, $result);
        
        if (!empty($details['telephone'])) {
            $queryCode = !empty($this->session->get('telephone'))? 'update_contact_data': 'add_contact_data';
            $result = $this->query_reader->run($queryCode, array('contact_type'=>'telephone', 'carrier_id'=>'', 'details'=>$details['telephone'], 'parent_id'=>$personId, 'parent_type'=>'person'));
            array_push($results, $result);
        }
        
        if ($this->session->get('birthplace__addressline')) {
            $result = $this->query_reader->run('update_address_data', array('parent_id'=>$personId, 'parent_type'=>'person', 'address_type'=>'physical', 'importance'=>'birthplace', 'details'=>htmlentities($this->session->get('birthplace__addressline'), ENT_QUOTES), 'district'=>$this->session->get('birthplace__district'), 'country'=>$this->session->get('birthplace__country'), 'county'=>($this->session->get('birthplace__county')? $this->session->get('birthplace__county'): "") ));
            array_push($results, $result);
        }
        
        $isUpdated = get_decision($results);
        
        return array('boolean'=>$isUpdated, 'msg'=>($isUpdated? 'The profile has been updated.': 'ERROR: The profile could not be updated.'));
    }
    
    
    
    # Add identification and contact addresses for the person
    public function add_id_and_contacts($personId, $addressDetails)
    {
        $msg = "";
        $required = array('verificationcode', 'permanentaddress', 'teacherQualCat', 'religion', 'contactaddress', 'citizenship__country', 'citizenship__citizentype');
        
        # 1. Add all provided data into the session
        $passed = process_fields($this, $addressDetails, $required, array("/"));
        
        if ($passed['boolean']) {
            $details = $passed['data'];
            
            # Determine whether to update the data or to create a new record
            if ($this->session->get('edit_step_2')) {
                $updateResult = $this->update_id_and_contacts($personId, $details);
                $result = $updateResult['boolean'];
                $msg = $updateResult['msg'];
            }
            # New record
            else {
                # 2. Verify the confirmation code
                if ($this->validator->is_valid_confirmation_code($personId, $details['verificationcode'])) {
                    # Activate teacher user ID
                    $result = $this->query_reader->run('activate_teacher_applicant_user', array('person_id'=>$personId));
                    
                    # 3. Save all the data into the database
                    if (!empty($details['teacherid'])) {
                        $this->add_another_id($personId, array('id_type'=>'teacher_id', 'id_value'=>htmlentities(restore_bad_chars($details['teacherid']), ENT_QUOTES) ));
                    }
                    #Save permanent and contact addresses
                    $permanentId = $this->add_address($personId, array('address_type'=>$this->session->get('permanentaddress__addresstype'), 'importance'=>'permanent', 'details'=>htmlentities($this->session->get('permanentaddress__addressline'), ENT_QUOTES), 'district'=>$this->session->get('permanentaddress__district'), 'country'=>$this->session->get('permanentaddress__country'), 'county'=>($this->session->get('permanentaddress__county')? $this->session->get('permanentaddress__county'): "") ));
                    $contactId = $this->add_address($personId, array('address_type'=>$this->session->get('contactaddress__addresstype'), 'importance'=>'contact', 'details'=>htmlentities($this->session->get('contactaddress__addressline'), ENT_QUOTES), 'district'=>$this->session->get('contactaddress__district'), 'country'=>$this->session->get('contactaddress__country'), 'county'=>($this->session->get('contactaddress__county')? $this->session->get('contactaddress__county'): "") ));
                
                    #Save the citizenship information
                    $result = $this->query_reader->run('update_person_citizenship', array('person_id'=>$personId, 'citizen_country'=>htmlentities($details['citizenship__country'], ENT_QUOTES), 'citizenship_type'=>$details['citizenship__citizentype'] ));
                
                    #Save Techer's Religion and Teaching Qualification
                    $result = $this->query_reader->run('update_teacher_religion_and_teaching_qualification', array('person_id'=>$personId,
                    'religion'=>htmlentities($details['religion'], ENT_QUOTES), 'teacherQualCat'=>htmlentities($details['teacherQualCat'], ENT_QUOTES)));

                    #Save the teacher's employment information
                    if (!empty($details['emp_school'])) {
                        $result = $this->query_reader->run('update_teacher_employment', array('person_id'=>$personId,
                    'title'=>htmlentities($details['title'], ENT_QUOTES), 'emp_school'=>htmlentities($details['emp_school'], ENT_QUOTES),
                    // 'emis'=>htmlentities($details['emis'], ENT_QUOTES), 
                    'employmentCat'=>htmlentities($details['employmentCat'], ENT_QUOTES),
                    'ipps'=>!empty($details['ipps'])? htmlentities($details['ipps'], ENT_QUOTES):null,	'region'=>htmlentities($details['region'], ENT_QUOTES),
                    'emp_district'=>htmlentities($details['emp_district'], ENT_QUOTES),	'emp_subCounty'=>htmlentities($details['emp_subCounty'], ENT_QUOTES)));
                    }
                    
                    if ($result) {
                        $this->session->set('edit_step_2', 'Y');
                    } else {
                        $msg = "ERROR: We could not save your information. Please try again.";
                    }
                } else {
                    $msg = "WARNING: The provided confirmation code is not valid. Please re-check your email message.";
                }
            }
        } else {
            $msg = "WARNING: Some required fields were left empty or entered with invalid characters. Please recheck your data and submit.";
        }
        
        # 4. Prepare appropriate message and return
        return array('boolean'=>(!empty($result)? $result: false), 'msg'=>$msg);
    }
    
        
    
    
    # Add another ID that identifies that person on a third party system
    public function add_another_id($personId, $details)
    {
        return $this->query_reader->add_data('add_another_id', array('parent_id'=>$personId, 'parent_type'=>'person', 'id_type'=>$details['id_type'], 'id_value'=>$details['id_value'] ));
    }
    
    
    # Update the person's ID and contact details
    public function update_id_and_contacts($personId, $details)
    {
        $results = array();
        
        if (!empty($details['teacherid'])) {
            $queryCode = !empty($this->session->get('__telephone'))? 'update_contact_data': 'add_contact_data';
            $result = $this->query_reader->run($queryCode, array('parent_id'=>$personId, 'parent_type'=>'person', 'id_type'=>'teacher_id', 'id_value'=>$details['teacherid']));
        }
        
        $result = $this->query_reader->run('update_address_data', array('parent_id'=>$personId, 'parent_type'=>'person', 'address_type'=>$this->session->get('permanentaddress__addresstype'), 'importance'=>'permanent', 'details'=>htmlentities($this->session->get('permanentaddress__addressline'), ENT_QUOTES), 'district'=>$this->session->get('permanentaddress__district'), 'country'=>$this->session->get('permanentaddress__country'), 'county'=>($this->session->get('permanentaddress__county')? $this->session->get('permanentaddress__county'): "") ));
        array_push($results, $result);
        
        
        $result = $this->query_reader->run('update_address_data', array('parent_id'=>$personId, 'parent_type'=>'person', 'address_type'=>$this->session->get('contactaddress__addresstype'), 'importance'=>'contact', 'details'=>htmlentities($this->session->get('contactaddress__addressline'), ENT_QUOTES), 'district'=>$this->session->get('contactaddress__district'), 'country'=>$this->session->get('contactaddress__country'), 'county'=>($this->session->get('contactaddress__county')? $this->session->get('contactaddress__county'): "") ));
        array_push($results, $result);
                
        #Save the citizenship information
        $result = $this->query_reader->run('update_person_citizenship', array('person_id'=>$personId, 'citizen_country'=>htmlentities($details['citizenship__country'], ENT_QUOTES), 'citizenship_type'=>$details['citizenship__citizentype'] ));
        array_push($results, $result);

        #Save Techer's Religion and Teaching Qualification
        $result = $this->query_reader->run('update_teacher_religion_and_teaching_qualification', array('person_id'=>$personId,
        'religion'=>htmlentities($details['religion'], ENT_QUOTES), 'teacherQualCat'=>htmlentities($details['teacherQualCat'], ENT_QUOTES)));
        array_push($results, $result);

        #Save the teacher's employment information
        if (!empty($details['emp_school'])) {
            $result = $this->query_reader->run('update_teacher_employment', array('person_id'=>$personId,
        'title'=>htmlentities($details['title'], ENT_QUOTES), 'emp_school'=>htmlentities($details['emp_school'], ENT_QUOTES),
        // 'emis'=>htmlentities($details['emis'], ENT_QUOTES), 
        'employmentCat'=>htmlentities($details['employmentCat'], ENT_QUOTES),
        'ipps'=>!empty($details['ipps'])? htmlentities($details['ipps'], ENT_QUOTES):null,	'region'=>htmlentities($details['region'], ENT_QUOTES),
        'emp_district'=>htmlentities($details['emp_district'], ENT_QUOTES),	'emp_subCounty'=>htmlentities($details['emp_subCounty'], ENT_QUOTES)));
            array_push($results, $result);
        }
        $isUpdated = get_decision($results);
        
        return array('boolean'=>$isUpdated, 'msg'=>($isUpdated? 'Your Employment and contact information has been updated.': 'ERROR: Your Employment and contact information could not be updated.'));
    }
    
        
    
    
    # Add the person's education
    public function add_education($personId, $educationDetails)
    {
        $msg = "";
        $required = array('institutionname', 'institution__institutiontype', 'from__month', 'from__pastyear', 'to__month', 'to__pastyear', 'certificatename');
        $isAdded = false;
        
        $passed = process_fields($this, $educationDetails, $required);
        
        if ($passed['boolean']) {
            $details = $passed['data'];
            
            # Make sure the "to" is greater than the "from" date
            if ((strtotime($details['to__month'].' 01, '.$details['to__pastyear']) - strtotime($details['from__month'].' 01, '.$details['from__pastyear'])) > 0) {
                # Determine whether to update the data or to create a new record
                if ($this->session->get('edit_step_3_education') && !empty($details['education_id'])) {
                    $updateResult = $this->update_education($personId, $details);
                    $isAdded = $updateResult['boolean'];
                    $msg = $updateResult['msg'];
                    $this->session->remove('edit_step_3_education');
                }
                # New record - add to the education session array
                else {
                    $educationList = $this->session->get('education_list')? $this->session->get('education_list'): array();
                    
                    $education = array('institutionname'=>$details['institutionname'], 'institution__institutiontype'=>$details['institution__institutiontype'], 'from__month'=>$details['from__month'], 'from__pastyear'=>$details['from__pastyear'], 'to__month'=>$details['to__month'], 'to__pastyear'=>$details['to__pastyear'], 'certificatename'=>$details['certificatename'], 'certificatenumber'=>(!empty($details['certificatenumber'])?$details['certificatenumber']:''), 'highestcertificate'=>(!empty($details['highestcertificate'])? $details['highestcertificate']: ""), 'education_id'=>strtotime('now'));
                    
                    array_push($educationList, $education);
                    $this->session->set('education_list', $educationList);
                    $isAdded = true;
                }
            } else {
                $msg = "WARNING: The start date can not be equal to or greater than the end date.";
            }
        }
        
        return array('boolean'=>$isAdded, 'msg'=>(!empty($msg)? $msg: 'Your education information has been added.'));
    }
        
    
        
    
    
    # Update the person's education
    public function update_education($personId, $details)
    {
        $isUpdated = false;
        $list = $this->session->get('education_list');
        $position = get_row_from_list($list, 'education_id', $details['education_id'], 'key');
        
        if (!empty($position) || $position == 0) {
            $list[$position] = array('institutionname'=>$details['institutionname'], 'institution__institutiontype'=>$details['institution__institutiontype'], 'from__month'=>$details['from__month'], 'from__pastyear'=>$details['from__pastyear'], 'to__month'=>$details['to__month'], 'to__pastyear'=>$details['to__pastyear'], 'certificatename'=>$details['certificatename'], 'certificatenumber'=>(!empty($details['certificatenumber'])?$details['certificatenumber']:''), 'highestcertificate'=>(!empty($details['highestcertificate'])? $details['highestcertificate']: ""), 'education_id'=>$details['education_id']);
            
            $this->session->set('education_list', $list);
            $isUpdated = true;
        }
        
        return array('boolean'=>$isUpdated, 'msg'=>'Your education information has been updated.');
    }
    
    
    
    
    
    # Add a subject taught
    public function add_subject_taught($personId, $subjectDetails)
    {
        $msg = "";
        $required = array('subjectname', 'subject__subjecttype');
        $isAdded = false;
        
        $passed = process_fields($this, $subjectDetails, $required);
        
        if ($passed['boolean']) {
            $details = $passed['data'];
            
            # Determine whether to update the data or to create a new record
            if ($this->session->get('edit_step_3_subject') && !empty($details['subject_id'])) {
                $updateResult = $this->update_subject_taught($personId, $details);
                $isAdded = $updateResult['boolean'];
                $msg = $updateResult['msg'];
                $this->session->remove('edit_step_3_subject');
            }
            # New record - add to the subject session array
            else {
                $subjectList = $this->session->get('subject_list')? $this->session->get('subject_list'): array();
                    
                $subject = array('subjectname'=>$details['subjectname'], 'subject__subjecttype'=>$details['subject__subjecttype'], 'subject_id'=>strtotime('now'));
                    
                array_push($subjectList, $subject);
                $this->session->set('subject_list', $subjectList);
                $isAdded = true;
            }
        }
        
        return array('boolean'=>$isAdded, 'msg'=>(!empty($msg)? $msg: 'Your subject information has been added.'));
    }
        
    
    
    # Update the person's subjects taught
    public function update_subject_taught($personId, $details)
    {
        $isUpdated = false;
        $list = $this->session->get('subject_list');
        $position = get_row_from_list($list, 'subject_id', $details['subject_id'], 'key');
        
        if (!empty($position) || $position == 0) {
            $list[$position] = array('subjectname'=>$details['subjectname'], 'subject__subjecttype'=>$details['subject__subjecttype'], 'subject_id'=>$details['subject_id']);
            
            $this->session->set('subject_list', $list);
            $isUpdated = true;
        }
        
        return array('boolean'=>$isUpdated, 'msg'=>'Your subject information has been updated.');
    }
    
    
    
    # Remove a list item
    public function remove_list_item($listType, $itemId)
    {
        $result = false;
        $list = $this->session->get($listType.'_list');
        $key = get_row_from_list($list, $listType.'_id', $itemId, 'key');
        if (!empty($key) || $key == 0) {
            
            #if this is a document, delete the saved document too
            if ($listType == 'document') {
                $result1 = $this->query_reader->run('delete_user_document_by_url', array('url'=>$list[$key]['documenturl']));
                if ($result1) {
                    @unlink(UPLOAD_DIRECTORY.'documents/'.$list[$key]['documenturl']);
                }
            }
            
            unset($list[$key]);
            $this->session->set($listType.'_list', $list);
            $result = !empty($result1)? $result1: true;
        }
        
        return $result;
    }
    
    
    
    
    # Add education and qualifications
    public function add_education_and_qualifications($personId, $details)
    {
        $isAdded = false;
        $results = array();
        
        # If the user is editing, first remove the old records
        if ($this->session->get('edit_step_3') || !empty($personId)) {
            $result1 = $this->query_reader->run('remove_academic_history', array('person_id'=>$personId));
            $result2 = $this->query_reader->run('remove_subject_data', array('parent_id'=>$personId, 'parent_type'=>'person'));
            array_push($results, $result1, $result2);
        }
        
        if ($this->session->get('education_list')) {
            foreach ($this->session->get('education_list') as $educationIndex=>$row) {
                $result = $this->query_reader->run('add_academic_history', array('person_id'=>$personId, 'institution'=>$row['institutionname'], 'institution_type'=>$row['institution__institutiontype'], 'start_date'=>format_date($row['from__month'].' 01, '.$row['from__pastyear'], 'YYYY-MM-DD'), 'end_date'=>format_date($row['to__month'].' 01, '.$row['to__pastyear'], 'YYYY-MM-DD'), 'certificate_name'=>$row['certificatename'], 'certificate_number'=>(!empty($row['certificatenumber'])?$row['certificatenumber']:''), 'is_highest'=>(!empty($row['highestcertificate'])? 'Y': 'N'), 'added_by'=>($this->session->get('__user_id')? $this->session->get('__user_id'): $this->session->get('user_id')) ));
                
                array_push($results, $result);
            }
        }
        
        
        if ($this->session->get('subject_list')) {
            foreach ($this->session->get('subject_list') as $subjectIndex=>$row) {
                $result = $this->query_reader->run('add_subject_data', array('parent_id'=>$personId, 'parent_type'=>'person', 'details'=>$row['subjectname'], 'study_category'=>$row['subject__subjecttype'] ));
                
                array_push($results, $result);
            }
        }
        
        $isAdded = get_decision($results);
        
        
        # If this is a new record mark this as a start of the editing of the page
        if ($isAdded && isset($educationIndex) && isset($subjectIndex) && !$this->session->get('edit_step_3')) {
            $this->session->set('edit_step_3', 'Y');
        } elseif (!isset($educationIndex) || (!isset($subjectIndex) && $_SESSION['teacherQualCat'] == 'Secondary')) {
            $isAdded = false;
            $msg = ($_SESSION['teacherQualCat'] == 'Secondary')? "WARNING: Your education and subjects are required to continue.":"WARNING: Your education qualifications are required to continue.";
        }
        
        
        # Prepare appropriate message to return
        $action = $this->session->get('edit_step_3')? "updated": "added";
        return array('boolean'=>$isAdded, 'msg'=>($isAdded? 'Your education and qualification information has been '.$action.'.': (!empty($msg)? $msg: 'ERROR: Your education and qualification information could not be '.$action.'.'))  );
    }
    
    
    
    
    # Submit the application
    public function submit_application($personId, $details)
    {
        $msg = "";
        
        # 1. Mark the user status as complete - for the admin to be able to approve it
        $result1 = $this->query_reader->run('update_teacher_status', array('user_id'=>$details['user_id'], 'status'=>'completed', 'updated_by'=>$details['user_id']));
        $result2 = $this->query_reader->run('update_user_status', array('user_id'=>$details['user_id'], 'status'=>'active', 'updated_by'=>$this->session->get('__user_id') ));
        if (!$result1) {
            $msg = "ERROR: We could not set up your user account for activation.";
        }
        
        # 2. Start the teacher approval chain
        $result = $this->approval_chain->add_chain($details['user_id'], 'registration', '1', 'approved', 'New application Submitted.');
        $result2 = $result['boolean'];
        if (!$result2) {
            $msg = "ERROR: We could not set up your registration for approval.";
        }
        
        # 3. Send notification of application submission
        $result3 =  $this->messenger->send($details['user_id'], array('code'=>'teacher_application_submitted', 'email_from'=>SIGNUP_EMAIL, 'from_name'=>SITE_GENERAL_NAME, 'first_name'=>htmlentities($details['first_name'], ENT_QUOTES), 'emailaddress'=>$details['emailaddress'], 'login_link'=>base_url() ), array('email'));
        
        if (!$result3) {
            $msg = "ERROR: We could not send your application confirmation email.";
        }
        $isSubmitted = get_decision(array($result1,$result2), false);
        
        return array('boolean'=>$isSubmitted, 'msg'=>($isSubmitted? "Your application has been submitted": $msg));
    }
    
    
        
    
    
    # Add a qualification document for this person
    public function add_document($personId, $details)
    {
        $response = array('boolean'=>false, 'msg'=>'ERROR: We could not add the document(add_document _person model).');
        $details['documenturl__fileurl'] =$_SESSION['upload__fileurl'];
        # Determine whether to update the data or to create a new record
        # UPDATE
        if (!empty($details['document_id']) && !empty($details['documentname'])) {
            $response['boolean'] = $this->query_reader->run('update_document_field', array('document_id'=>$details['document_id'], 'field_name'=>'description', 'field_value'=>htmlentities($details['documentname'], ENT_QUOTES) ));
            # proceed to update the session if the db update was successful
            if ($response['boolean']) {
                $documentList = $this->session->get('document_list');
                $key = get_row_from_list($documentList, 'document_id', $details['document_id'], 'key');
                $documentList[$key]['documentname'] = $details['documentname'];
                
                $response['msg'] = 'The document has been updated.';
                $this->session->set('document_list', $documentList);
                $this->session->remove('upload__fileurl');
            }
            $this->session->remove('edit_step_3_document');
        }
        
        # ADD NEW
        
        elseif (!empty($details['documenturl__fileurl']) && !empty($details['documentname'])) {
            # Determine how to get a person ID if it is not given
            $currentStamp = strtotime('now');
            if (empty($personId)) {
                if ($this->session->get('person_id')) {
                    $personId = $this->session->get('person_id');
                }
                # Make up a temporary person ID if it is not yet known (for single entry forms)
                elseif (!$this->session->get('temp_person_id')) {
                    $personId = 'TEMP-'.$this->session->get('__user_id').'-'.$currentStamp;
                    $this->session->set('temp_person_id', $personId);
                } else {
                    $personId = $this->session->get('temp_person_id');
                }
            }
                
            $documentId = $this->query_reader->add_data('add_user_document', array('url'=>$details['documenturl__fileurl'],'document_type'=>'qualification_document','tracking_number'=>$currentStamp,'description'=>htmlentities($details['documentname'], ENT_QUOTES), 'is_removable'=>'Y','parent_id'=>$personId,'parent_type'=>'person'));
            
            if (!empty($documentId)) {
                $documentList = $this->session->get('document_list')? $this->session->get('document_list'): array();
                array_push($documentList, array('document_id'=>$documentId, 'documenturl'=>$details['documenturl__fileurl'], 'documentname'=>$details['documentname']));
                $this->session->set('document_list', $documentList);
                
                $response = array('boolean'=>true, 'msg'=>'The document has been added.');
            }
        }
        
        return $response;
    }
}
