<?php
/*
Module Name: Appointly
Description: Appointly
Version: 1.1.0
*/

defined('BASEPATH') or exit('No direct script access allowed');


$CI = &get_instance();

define('APPOINTLY_MODULE_NAME', 'appointly');
define('APPOINTLY_SMS_APPOINTMENT_APPROVED_TO_CLIENT', 'appointly_appointment_approved_send_to_client');
define('APPOINTLY_SMS_APPOINTMENT_CANCELLED_TO_CLIENT', 'appointly_appointment_cancelled_to_client');
define('APPOINTLY_SMS_APPOINTMENT_APPOINTMENT_REMINDER_TO_CLIENT', 'appointly_appointment_reminder_to_client');

hooks()->add_action('admin_init', 'appointly_register_permissions');
hooks()->add_action('admin_init', 'appointly_register_menu_items');
hooks()->add_action('after_cron_run', 'appointly_send_email_templates');

register_merge_fields('appointly/merge_fields/appointly_merge_fields');

hooks()->add_filter('other_merge_fields_available_for', 'appointly_register_other_merge_fields');
hooks()->add_filter('available_merge_fields', 'appointly_allow_staff_merge_fields_for_appointment_templates');

hooks()->add_filter('get_dashboard_widgets', 'appointly_register_dashboard_widgets');

// 10, 2 Priority default 10, 2 add second parameter
hooks()->add_filter('calendar_data', 'appointly_register_appointments_on_calendar', 10, 2);

/**
 * Register appointments on staff and clients calendar
 *
 * @param  [arrat] $data
 * @param  [array] $config
 * @return array
 */
function appointly_register_appointments_on_calendar($data, $config)
{
    $CI = &get_instance();
    $CI->load->model('appointly/appointly_model', 'apm');

    $data = $CI->apm->getCalendarData($config['start'], $config['end'], $data);

    return $data;
}

/**
 * Register new custom fields for
 */
hooks()->add_action('after_custom_fields_select_options', 'appointly_custom_fields');
function appointly_custom_fields($custom_field)
{
    $selected = (isset($custom_field) && $custom_field->fieldto == 'appointly') ? 'selected' : '';
    echo '<option value="appointly"  ' . ($selected) . '>' . _l('appointment_appointments') . '</option>';
}

/**
 * Get todays appointments to render in dashboard widget
 *
 * @param  [array] $widgets
 * @return array
 */
function appointly_register_dashboard_widgets($widgets)
{
    $widgets[] = [
        'container' => 'left-8',
        'path' => 'appointly/widgets/today_appointments',
    ];

    return $widgets;
}


/**
 * Get staff fields and insert into email templates for appointly
 *
 * @param  [array] $fields
 * @return array
 */
function appointly_allow_staff_merge_fields_for_appointment_templates($fields)
{
    $appointlyStaffFields = ['{staff_firstname}', '{staff_lastname}'];

    foreach ($fields as $index => $group) {
        foreach ($group as $key => $groupFields) {
            if ($key == 'staff') {
                foreach ($groupFields as $groupIndex => $groupField) {
                    if (in_array($groupField['key'], $appointlyStaffFields)) {
                        $fields[$index][$key][$groupIndex]['available'] = array_merge($fields[$index][$key][$groupIndex]['available'], ['appointly']);
                    }
                }
                break;
            }
        }
    }
    return $fields;
}

/**
 * Register other merge fields for appointly
 *
 * @param  [array] $for
 * @return void
 */
function appointly_register_other_merge_fields($for)
{
    $for[] = 'appointly';

    return $for;
}


/**
 * Hook for assigning staff permissions for apoointments module
 *
 * @return void
 */
function appointly_register_permissions()
{
    $capabilities = [];

    $capabilities['capabilities'] = [
        'view'   => _l('permission_view') . '(' . _l('permission_global') . ')',
        'view_own'   => _l('permission_view_own'),
        'create' => _l('permission_create'),
        'edit'   => _l('permission_edit'),
        'delete' => _l('permission_delete'),
    ];

    register_staff_capabilities('appointments', $capabilities, _l('appointment_appointments'), _l('calendar_permissions'));
}


/**
 * Register new menu item in sidebar menu
 */
function appointly_register_menu_items()
{
    $CI = &get_instance();

    if (staff_can('view', 'appointments') || staff_can('view_own', 'appointments')) {
        /*$CI->app_menu->add_sidebar_menu_item(APPOINTLY_MODULE_NAME, [
            'name'     => 'appointly_module_name',
            'href'     => admin_url('appointly/appointments'),
            'position' => 10,
            'icon'     => 'fal fa-handshake',
        ]);

        $CI->app_menu->add_sidebar_children_item(APPOINTLY_MODULE_NAME, [
            'slug'     => 'appointly-user-dashboard',
            'name'     => 'appointment_appointments',
            'href'     => admin_url('appointly/appointments'),
            'position' => 5,
            'icon'     => 'fa fa-th-list',
        ]);

        $CI->app_menu->add_sidebar_children_item(APPOINTLY_MODULE_NAME, [
            'slug'     => 'appointly-user-history',
            'name'     => 'appointment_history_label',
            'href'     => admin_url('appointly/appointments_history'),
            'position' => 10,
            'icon'     => 'fa fa-history',
        ]);

        */

        $CI->app_menu->add_setup_children_item('communications', [
            'slug'     => 'appointly-user-settings',
            'name'     => _l('appointments'),
            'href'     => admin_url('appointly/appointments/user_settings_view/settings'),
            'position' => 1,
        ]);


        $CI->app_menu->add_sidebar_children_item('agenda', ['slug'     => 'appointly-user-dashboard',
            'name'     => _l('menu_agenda__appointments'),
            'href'     => admin_url('appointly/appointments'),
            'position' => 2,
        ]);

        $CI->app_menu->add_sidebar_children_item('agenda', ['slug'     => 'appointly-user-history',
            'name'     => _l('menu_agenda__appointments_history'),
            'href'     => admin_url('appointly/appointments_history'),
            'position' => 6,
        ]);
        $CI->app_menu->add_sidebar_children_item('agenda', ['slug'     => 'appointly-callbacks',
            'name'     => _l('menu_agenda__callbacks'),
            'href'     => admin_url('appointly/callbacks'),
            'position' => 4,
        ]);
    }
}


/**
 * Register activation hook
 */
register_activation_hook(APPOINTLY_MODULE_NAME, 'appointly_activation_hook');


/**
 * The activation function
 */
function appointly_activation_hook()
{
    //require(__DIR__ . '/install.php');
}


/**
 * Register module language files
 */
register_language_files(APPOINTLY_MODULE_NAME, ['appointly']);


/**
 * Loads the module function helper
 */
$CI->load->helper(APPOINTLY_MODULE_NAME . '/appointly');


/**
 * Register cron email templates
 *
 * @return void
 */
function appointly_send_email_templates()
{
    $CI = &get_instance();
    $CI->load->model('appointly/appointly_attendees_model', 'atm');

    // User events
    $CI->db->where('notification_date IS NULL'); // proof it is still not been notified
    $CI->db->where('reminder_before IS NOT NULL'); // proof have setup notification eg 30 min before
    $CI->db->where('approved = 1'); // appointment must be approved

    $appointments = $CI->db->get(db_prefix() . 'appointly_appointments')->result_array();
    $notified_users = [];
    $merge_fields = '';

    foreach ($appointments as $appointment) {
        $date_compare = date('Y-m-d H:i', strtotime('+' . $appointment['reminder_before'] . ' ' . strtoupper($appointment['reminder_before_type'])));

        if ($appointment['date'] . ' ' . $appointment['start_hour'] <= $date_compare) {
            if (date('Y-m-d H:i', strtotime($appointment['date'] . ' ' . $appointment['start_hour'])) < date('Y-m-d H:i')) {
                /**
                 * If appointment is missed then skip
                 */
                continue;
            }

            $attendees = $CI->atm->get($appointment['id']);

            foreach ($attendees as $staff) {
                add_notification([
                    'description'     => 'appointment_you_have_new_appointment',
                    'touserid'        => $staff['staffid'],
                    'fromcompany'     => true,
                    'link'            => 'appointly/appointments/view?appointment_id=' . $appointment['id'],
                ]);

                $notified_users[] = $staff['staffid'];

                send_mail_template('appointly_appointment_cron_reminder_to_staff', 'appointly', array_to_object($appointment), array_to_object($staff));
            }

            $template = mail_template('appointly_appointment_cron_reminder_to_contact', 'appointly', array_to_object($appointment));

            $merge_fields =  $template->get_merge_fields();

            $template->send();

            if ($appointment['by_sms']) {
                $CI->app_sms->trigger(APPOINTLY_SMS_APPOINTMENT_APPOINTMENT_REMINDER_TO_CLIENT, $appointment['phone'], $merge_fields);
            }

            $CI->db->where('id', $appointment['id']);
            $CI->db->update('appointly_appointments', ['notification_date' => date('Y-m-d H:i:s')]);
        }
    }
    pusher_trigger_notification(array_unique($notified_users));
}

hooks()->add_filter('sms_gateway_available_triggers', 'appointly_register_sms_triggers');
/**
 * Register SMS Triggers for appointly
 *
 * @param  [array] $triggers
 * @return array
 */
function appointly_register_sms_triggers($triggers)
{
    $triggers[APPOINTLY_SMS_APPOINTMENT_APPROVED_TO_CLIENT] = [
        'merge_fields' => [
            '{appointment_subject}',
            '{appointment_date}',
            '{appointment_client_name}',
        ],
        'label'        => 'Appointment approved (Sent to Contact)',
        'info'         => 'Trigger when appointment is approved, SMS will be sent to the appointment contact number.',
    ];

    $triggers[APPOINTLY_SMS_APPOINTMENT_CANCELLED_TO_CLIENT] = [
        'merge_fields' => [
            '{appointment_subject}',
            '{appointment_date}',
            '{appointment_client_name}',
        ],
        'label'        => 'Appointment cancelled (Sent to Contact)',
        'info'         => 'Trigger when appointment is cancelled, SMS will be sent to the appointment contact number.',
    ];

    $triggers[APPOINTLY_SMS_APPOINTMENT_APPOINTMENT_REMINDER_TO_CLIENT] = [
        'merge_fields' => [
            '{appointment_subject}',
            '{appointment_date}',
            '{appointment_client_name}',
        ],
        'label'        => 'Appointment reminder (Sent to Contact)',
        'info'         => 'Trigger when reminder before date is set when appointment is created, SMS will be sent to the appointment contact number.',
    ];

    return $triggers;
}

/**
 * Check if can have permissions then apply new tab in settings
 */
if (staff_can('view', 'settings')) {
    hooks()->add_action('admin_init', 'appointly_add_settings_tab');
}

/**
 * @return void
 */
function appointly_add_settings_tab()
{
    $CI = &get_instance();
    $CI->app_tabs->add_settings_tab('appointly-settings', [
        'name'     => _l('appointment_appointments'),
        'view'     => 'appointly/settings',
        'position' => 36,
    ]);
}

/**
 * Need to change encode array values to string for database before post
 * Intercepting settings-form
 * @return array
 */
hooks()->add_filter('before_settings_updated', 'modify_settings_form_post');

function modify_settings_form_post($form)
{
    if (isset($form['settings']['appointly_available_hours'])) {
        $form['settings']['appointly_available_hours'] = json_encode($form['settings']['appointly_available_hours']);
        if ($form['settings']['appointly_available_hours'] == null) {
            $form['settings']['appointly_available_hours'] = json_encode([]);
        }
    }
    if (isset($form['settings']['appointly_default_feedbacks'])) {
        $form['settings']['appointly_default_feedbacks'] = json_encode($form['settings']['appointly_default_feedbacks']);
        if ($form['settings']['appointly_default_feedbacks'] == null) {
            $form['settings']['appointly_default_feedbacks'] = json_encode([]);
        }
    }
    return $form;
}
