<?php

// If this file is called directly, abort.
if (!defined('WPINC')) {
    die;
}

/**
 * Class EasyEAFullCalendar
 */
class EasyEAFullCalendar
{

    /**
     * @var EAOptions
     */
    protected $options;

    /**
     * @var EADBModels
     */
    protected $models;

    /**
     * @var EADateTime
     */
    protected $datetime;

    /**
     * @var EALogic
     */
    protected $logic;

    /**
     * @param EADBModels $models
     * @param $logic
     * @param EAOptions $options
     * @param $datetime
     */
    function __construct($models, $logic, $options, $datetime)
    {
        $this->options  = $options;
        $this->models   = $models;
        $this->datetime = $datetime;
        $this->logic = $logic;
    }

    public function init()
    {
        // register JS
         add_action('wp_enqueue_scripts', array($this, 'init_scripts'));
        // add_action( 'admin_enqueue_scripts', array( $this, 'init' ) );

        // add shortcode standard
        add_shortcode('ea_full_calendar', array($this, 'ea_full_calendar'));

        // allow public access for FullCalendar
        $is_public = $this->options->get_option_value('fullcalendar.public', '0');

        if (!empty($is_public)) {
            add_filter('easy_ea_calendar_public_access', function() { return true; });
        }
    }

    public function init_scripts()
    {
        // bootstrap script
        wp_register_script(
            'ea-full-calendar',
            EA_PLUGIN_URL . 'js/libs/fullcalendar/fullcalendar.min.js',
            array('jquery', 'ea-momentjs', 'wp-api', 'thickbox', 'underscore'),
            '2.0.0',
            true
        );

        wp_register_style(
            'ea-full-calendar-style',
            EA_PLUGIN_URL . 'js/libs/fullcalendar/fullcalendar.css',
            array(),
            EASY_APPOINTMENTS_VERSION
        );

        // admin style
        wp_register_style(
            'ea-full-calendar-custom-css',
            EA_PLUGIN_URL . 'css/full-calendar.css',
            array(),
            EASY_APPOINTMENTS_VERSION
        );
    }

    function get_time_format_by_locale($format = '00-24') {
        if ($format === '00-24') {
             return 'H:mm'; // 24-hour format
        } elseif ($format === 'am-pm') {
            return 'h:mm a'; // 12-hour format
        }
    }


    /**
     * Shortcode def for Full Calendar
     *
     * @param $atts
     * @return string
     */
    public function ea_full_calendar($atts)
    {
        $code_params = shortcode_atts(array(
            'location'             => null,
            'service'              => null,
            'worker'               => null,
            'color'                => false,
            'start_of_week'        => (int) get_option('start_of_week', 0),
            'rtl'                  => '0',
            'default_date'         => gmdate('Y-m-d'),
            'min_date'             => null,
            'max_date'             => null,
            'time_format'          => $this->get_time_format_by_locale($this->options->get_option_value('time_format')),
            'display_event_end'    => '0',
            'hide_cancelled'        => '0',
            'show_remaining_slots' => '0',
            'show_week'            => '0',
            'title_field'          => 'name',
            'default_view'         => 'month', // basicWeek, basicDay, agendaDay, agendaWeek
            'views'                => 'month,basicWeek,basicDay',
            'day_names_short'      => 'Sun,Mon,Tue,Wed,Thu,Fri,Sat',
            'day_names'            => 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
            'month_names_short'    => 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
            'month_names'          => 'January,February,March,April,May,June,July,August,September,October,November,December',
            'button_labels'        => 'today,month,week,day,list',
            'month_header_format'  => 'MMM YYYY',
            'week_header_format'   => 'MMM DD, YYYY',
            'day_header_format'    => 'MMM DD, YYYY',
            'column_header_format' => null,
        ), $atts);

        // all those values are used inside JS code part, escape all values to be JS strings
        foreach ($code_params as $key => $value) {
            if ($value === null || $value === '0' || $value === '1' || strlen($value) < 4) {
                continue;
            }

            // also remove '{', '}' brackets because no settings needs that
            $code_params[$key] = esc_js(str_replace(array('{','}',';', '(', ')'), array('','','','',''), $value));
        }

        // scripts that are going to be used
        wp_enqueue_script('underscore');
        wp_enqueue_script('ea-validator');
        wp_enqueue_script('ea-full-calendar');

        // add thickbox styles
        wp_enqueue_style('thickbox.css', includes_url('/js/thickbox/thickbox.css'), null, '1.0');

        wp_enqueue_style('ea-full-calendar-style');
        wp_enqueue_style('ea-full-calendar-custom-css');

        $customCss = $this->options->get_option_value('custom.css', '');

        $id = uniqid();

        $show_week_numbers = $code_params['show_week'] === '1' ? 'true' : 'false';
        $is_rtl = $code_params['rtl'] === '1' ? 'true' : 'false';

        /**
         * Convert string: 'Sun,Mon,Tue,Wed,Thu,Fri,Sat' to string
         * "['Sun','Mon','Tue','Wed','Thu','Fri','Sat']" etc
         */
        $day_names_short = $this->convert_csv_to_js_array_of_strings($code_params['day_names_short']);
        $day_names = $this->convert_csv_to_js_array_of_strings($code_params['day_names']);
        $month_names_short = $this->convert_csv_to_js_array_of_strings($code_params['month_names_short']);
        $month_names = $this->convert_csv_to_js_array_of_strings($code_params['month_names']);
        $button_labels = explode(',', $code_params['button_labels']);

        // set it as optional
        $location_param = $code_params['location'] !== null ? "location: '{$code_params['location']}'," : '';
        $service_param = $code_params['service'] !== null ? "service: '{$code_params['service']}'," : '';
        $worker_param = $code_params['worker'] !== null ? "worker: '{$code_params['worker']}'," : '';
        $service_color = $code_params['color'] === 'service' ? "color: true," : '';

        $display_end_time = $code_params['display_event_end'] ? 'true' : 'false';

        $event_click_link = '';
        $current_user = get_current_user_id();

        // event link
        if (!empty($this->options->get_option_value('fullcalendar.event.show'))) {
            $event_click_link =
              "element.addClass('thickbox');" .
              "element.addClass('ea-full-calendar-dialog-event');" .
              "element.attr('href', wpApiSettings.root + 'easy-appointments/v1/appointment/' + event.id + '?hash=' + event.hash + '&eventpopup=yes&_wpnonce=' + wpApiSettings.nonce + '&width=100%&height=100%');" .
              "element.attr('title', '#' + event.id + ' - ' + _.escape(event.title));";
          if (!empty($this->options->get_option_value('fullcalendar.manage_appointment.show'))) {
            $event_click_link =
            "var current_user = \"" . esc_js($current_user) . "\";" .
            "if (current_user && current_user > 0 && current_user === event.user) {" .
                "element.addClass('thickbox');" .
                "element.addClass('ea-full-calendar-dialog-event');" .
                "element.attr('href', wpApiSettings.root + 'easy-appointments/v1/appointment/' + event.id + '?hash=' + event.hash + '&eventpopup=yes&edit=yes&_wpnonce=' + wpApiSettings.nonce + '&width=100%&height=100%');" .
                "element.attr('title', '#' + event.id + ' - ' + _.escape(event.title));" .
            "}";
            
          }
           
        }else{
          if (!empty($this->options->get_option_value('fullcalendar.manage_appointment.show'))) {
            $event_click_link =
            "var current_user = \"" . esc_js($current_user) . "\";" .
            "if (current_user && current_user > 0 && current_user === event.user) {" .
                "element.addClass('thickbox');" .
                "element.addClass('ea-full-calendar-dialog-event');" .
                "element.attr('href', wpApiSettings.root + 'easy-appointments/v1/appointment/' + event.id + '?hash=' + event.hash + '&edit=yes&_wpnonce=' + wpApiSettings.nonce + '&width=100%&height=100%');" .
                "element.attr('title', '#' + event.id + ' - ' + _.escape(event.title));" .
            "}";
            
          }

        }
        $event_click_ajax = "";
        if (!empty($this->options->get_option_value('fullcalendar.manage_appointment.show')) && $current_user) {
            $ajaxurl = admin_url('admin-ajax.php');
            $event_click_ajax =
            "jQuery(document).on('submit', '#ea-appointment-edit-form', function (e) {" .
                "e.preventDefault();" .
                "var ajax_url = \"" . esc_js($ajaxurl) . "\";" .
                "const formData = jQuery(this).serialize();" .
                "jQuery.post(ajax_url, formData + '&action=ea_update_customer_data', function (res) {" .
                    "if (res.success) {" .
                        "alert('Updated successfully.');" .
                    "} else {" .
                        "alert('Failed to update.');" .
                    "}" .
                "});" .
            "});";

    
        }        

        $column_header_format = '';

        if ($code_params['column_header_format'] !== null) {
            $column_header_format = "columnHeaderFormat: '{$code_params['column_header_format']}',";
        }

        $script_section =
    "<style>{$customCss}</style>" .
    "<script>" .
      "jQuery(document).ready(function() {" .

        "jQuery(document).on('click', '.ea-edit-appointment-icon', function (e) {" .
            "jQuery('.ea-edit-appointment-wrapper').show();" .
            "jQuery('#ea_event_popup').hide();" .
            "jQuery('.ea-edit-appointment-icon').hide();" .
        "});" .

        "jQuery(document).on('click', '.ea-cancel-edit', function (e) {" .
            "jQuery('.ea-edit-appointment-wrapper').hide();" .
            "jQuery('#ea_event_popup').show();" .
            "jQuery('.ea-edit-appointment-icon').show();" .
        "});" .

        "jQuery('#ea-calendar-color-map-{$id}').find('.status').hover(" .
            "function(event) {" .
                "var el = jQuery(event.target);" .
                "var classSelector = '.' + el.data('class');" .
                "jQuery('#ea-full-calendar-{$id}').find('.fc-event:not(' + classSelector + ')').animate({ opacity: 1/2 }, 200);" .
            "}," .
            "function(event){" .
                "jQuery('#ea-full-calendar-{$id}').find('.fc-event').animate({ opacity: 1 }, 100);" .
            "}" .
        ");" .

        "jQuery('#ea-full-calendar-{$id}').fullCalendar({" .
            "header: {" .
                "left: 'prev,next today'," .
                "center: 'title'," .
                "right: '{$code_params['views']}'" .
            "}," .
            "dayNamesShort: {$day_names_short}," .
            "dayNames: {$day_names}," .
            "monthNamesShort: {$month_names_short}," .
            "monthNames: {$month_names}," .
            "buttonText: {" .
                "today: '{$button_labels[0]}'," .
                "month: '{$button_labels[1]}'," .
                "week: '{$button_labels[2]}'," .
                "day: '{$button_labels[3]}'," .
                "list: '{$button_labels[4]}'" .
            "}," .
            "views: {" .
                "month: { titleFormat: '{$code_params['month_header_format']}' }," .
                "week: { titleFormat: '{$code_params['week_header_format']}' }," .
                "day: { titleFormat: '{$code_params['day_header_format']}' }" .
            "}," .
            "isRTL: {$is_rtl}," .
            "defaultView: '{$code_params['default_view']}'," .
            "showNonCurrentDates: false," .
            "timeFormat: '{$code_params['time_format']}'," .
            "{$column_header_format}" .
            "displayEventEnd: {$display_end_time}," .
            "weekNumbers: {$show_week_numbers}," .
            "firstDay: {$code_params['start_of_week']}," .
            "defaultDate: '{$code_params['default_date']}'," .
            "navLinks: true," .
            "editable: false," .
            "eventLimit: true," .
            "events: {" .
                "url: wpApiSettings.root + 'easy-appointments/v1/appointments'," .
                "type: 'GET'," .
                "data: {" .
                    "_wpnonce: wpApiSettings.nonce," .
                    "hide_cancelled: '{$code_params['hide_cancelled']}'," .
                    "{$location_param}" .
                    "{$service_param}" .
                    "{$worker_param}" .
                    "{$service_color}" .
                    "title_field: '{$code_params['title_field']}'," .
                "}," .
                "error: function() { console.log('there was an error while fetching events!'); }," .
                "textColor: 'white'" .
            "}," .
            "eventClick: function(calEvent, jsEvent, view) {}," .
            "eventRender: function(event, element) {" .
                "var statusMapping = {" .
                    "canceled: 'graffit'," .
                    "confirmed: 'darkgreen'," .
                    "pending: 'grape'," .
                    "reserved: 'darkblue'" .
                "};" .
                "element.addClass(statusMapping[event.status]);" .
                "{$event_click_link}" .
            "}" .
        "});" .

        "{$event_click_ajax}" .

      "});" .
    "</script>";


        // wp_add_inline_script( 'ea-full-calendar', $script_section);

        $statuses = $this->logic->getStatus();
        $status_label = __('Status', 'easy-appointments');

        $status_html =
        '<div class="fc">' .
            '<div id="ea-calendar-color-map-' . $id . '" class="ea-calendar-color-map fc-view-container">' .
                '<div>' . $status_label . '</div>' .
                '<div data-class="grape" class="fc-event status grape">' . $statuses['pending'] . '</div>' .
                '<div data-class="darkgreen" class="fc-event status darkgreen">' . $statuses['confirmed'] . '</div>' .
                '<div data-class="darkblue" class="fc-event status darkblue">' . $statuses['reservation'] . '</div>' .
                '<div data-class="graffit" class="fc-event status graffit">' . $statuses['canceled'] . '</div>' .
            '</div>' .
        '</div>';


        // html and status legend
        $html = '<div id="ea-full-calendar-' . $id . '"></div>';

        if (!$service_color) {
            $html .= $status_html;
        }

        $html .= $script_section;

        return $html;
    }

    /**
     * Formatting JS values for Calendar
     *
     * @param $arrayString
     * @return string
     */
    protected function convert_csv_to_js_array_of_strings($arrayString)
    {
        $raw_array = explode(',', $arrayString);

        $wrapped_array = array_map(function($element) {
            return "'{$element}'";
        }, $raw_array);

        return '[' . implode(',', $wrapped_array) . ']';
    }
}