<?php
namespace BooklyOutlookCalendar\Backend\Modules\Staff\ProxyProviders;

use Bookly\Backend\Modules\Staff\Proxy;
use Bookly\Lib as BooklyLib;
use Bookly\Lib\Entities\Staff;
use BooklyOutlookCalendar\Lib\Config;
use BooklyOutlookCalendar\Lib\Microsoft;

/**
 * Class Shared
 * @package BooklyOutlookCalendar\Backend\Modules\Staff\ProxyProviders
 */
class Shared extends Proxy\Shared
{
    /**
     * @inheritdoc
     */
    public static function editStaff( array $data, Staff $staff )
    {
        if ( $errors = BooklyLib\Session::get( 'staff_outlook_auth_error' ) ) {
            foreach ( (array) json_decode( $errors, true ) as $error ) {
                $data['alert']['error'][] = $error;
            }
            BooklyLib\Session::destroy( 'staff_outlook_auth_error' );
        }

        $auth_url    = null;
        $calendars   = array();
        $calendar_id = null;
        if ( $staff->getOutlookData() == '' ) {
            if ( Config::getSyncMode() !== null ) {
                $ms       = new Microsoft\Client();
                $auth_url = $ms->createAuthUrl( $staff->getId() );
            } else {
                $auth_url = false;
            }
        } else {
            $ms = new Microsoft\Client();
            if ( $ms->auth( $staff, true ) && ( $list = $ms->getCalendarList() ) !== false ) {
                $calendars   = $list;
                $calendar_id = $ms->data()->calendar->id;
            } else {
                foreach ( $ms->getErrors() as $error ) {
                    $data['alert']['error'][] = 'Outlook Calendar: ' . $error;
                }
            }
        }

        $data['tpl']['oc'] = compact( 'staff', 'auth_url', 'calendars', 'calendar_id' );

        return $data;
    }

    /**
     * @inheritdoc
     */
    public static function renderStaffPage( $active_staff_id, $params )
    {
        if ( isset ( $params['outlook_disconnect'] ) ) {
            $active_staff_id = $params['outlook_disconnect'];
            $staff = new Staff();
            if ( $staff->load( $active_staff_id ) ) {
                $ms = new Microsoft\Client();
                if ( $ms->auth( $staff ) ) {
                    $ms->calendar()->deleteSubscription( false );
                }
                $staff
                    ->setOutlookData( null )
                    ->save()
                ;
            }
        }

        return $active_staff_id;
    }

    /**
     * @inheritdoc
     */
    public static function preUpdateStaff( Staff $staff, array $params )
    {
        if ( isset ( $params['outlook_calendar_id'] ) ) {
            $calendar_id = str_replace( '/', '', $params['outlook_calendar_id'] );
            $ms          = new Microsoft\Client();
            $update_data = false;
            if ( $ms->auth( $staff, true ) ) {
                if ( $staff->isArchived() && $params['visibility'] != 'archive' && $ms->calendar()->clearDeltaLink()->sync() ) {
                    // Change visibility from archive.
                    $ms->calendar()->createSubscription();
                    $update_data = true;
                } elseif ( ! $staff->isArchived() && $params['visibility'] == 'archive' ) {
                    // Change visibility to archive.
                    $ms->calendar()->clearDeltaLink();
                    $update_data = true;
                } elseif ( $calendar_id != $ms->data()->calendar->id ) {
                    // Calendar changed.
                    if ( $staff->isArchived() ) {
                        wp_send_json_error( array( 'error' => 'Outlook Calendar: ' . esc_html__( 'Can\'t change calendar for archived staff', 'bookly' ) ) );
                    } elseif ( $calendar_id != '' ) {
                        if ( ! $ms->validateCalendarId( $calendar_id ) ) {
                            $errors = array();
                            foreach ( $ms->getErrors() as $error ) {
                                $errors[] = 'Outlook Calendar: ' . $error;
                            }
                            wp_send_json_error( array( 'error' => implode( '<br/>', $errors ) ) );
                        }
                    } else {
                        $calendar_id = null;
                    }
                    $ms->calendar()->clearDeltaLink()->deleteSubscription( false );
                    $ms->data()->calendar->id = $calendar_id;
                    $update_data = true;
                }
                if ( $update_data ) {
                    $staff->setOutlookData( $ms->data()->toJson() );
                }
            }
        }
    }

    /**
     * @inheritdoc
     */
    public static function updateStaff( BooklyLib\Entities\Staff $staff, array $params )
    {
        if ( Config::getSyncMode() == '2-way' ) {
            $ms = new Microsoft\Client();
            if ( $ms->auth( $staff ) ) {
                $ms->calendar()->sync();
                // Register new notification channel.
                if ( ! $ms->calendar()->createSubscription() ) {
                    $errors = array();
                    foreach ( $ms->getErrors() as $error ) {
                        $errors[] = 'Outlook Calendar: ' . $error;
                    }
                    wp_send_json_error( array( 'error' => implode( '<br/>', $errors ) ) );
                }
            }
        }
    }
}