<?php
namespace WpBookingProFrontend\app\models;
defined('_WPBOOKINGPRO_EXEC') or die;

use Exception;
use WpBookingPro\Factory;
use WpBookingPro\Filesystem\File as FileAlias;
use WpBookingPro\Language\Text;
use WpBookingPro\Mvc\Model\Model;
use WpBookingPro\Mvc\Model\ModelForm;
use WpBookingPro\Form\Form;
use WpBookingPro\Mvc\Model\ModelList;
use WpBookingPro\Registry\Registry;
use WpBookingPro\Utilities\Utility;
use WpBookingProAdmin\app\helpers\AdminHelper;
use WpBookingProFrontend\app\helpers\FrontendHelper;

class ServiceModel extends ModelForm
{
    /**
     * @var string
     */
    public $context = "service";
    /**
     * @var string
     */
    public $table_name = "service";
    public function save($data = array())
    {

        $params = array();
        foreach ($data as $key => $value) {
            if (strpos($key, "params") !== false) {
                $key = substr($key, 7);
                $params[$key] = $value;
            }
        }
        $params=reset($params);//TODO: Fix later
        $register = new Registry();
        $register->loadArray($params);
        $data['params'] = $register->toString();

        $item= parent::save($data); // TODO: Change the autogenerated stub
        $image=Factory::getInput()->files->get('image','','raw');
        $check_user_demo = FrontendHelper::checkUserDemo();
        if(!empty($image['name'])) {
            $name = str_replace(' ', '_',Utility::gen_random_string()) . $image['name'];
            if($check_user_demo['is_demo']) {
                $short_path_image = "service/images/cover/$name";
                $new_file_image_activity_path  = WP_CONTENT_DIR . '/uploads/sites/' . $check_user_demo['blog_id']. DS . $short_path_image;
            } else {
                $short_path_image = "upload/service/images/cover/$name";
                $new_file_image_activity_path = WPBOOKINGPRO_PATH_ROOT . DS . $short_path_image;
            }

            if (!FileAlias::write($new_file_image_activity_path, FileAlias::read($image['tmp_name']))) {
                throw new Exception(Text::_("can not upload image cover"));
            }
            $item->image = $short_path_image;
            $data = (array)$item;
            $item = parent::save($data);
        }
        $galleryModel=Model::getInstance('gallery');

        $gallery=Factory::getInput()->files->get('gallery','','raw');
        if($gallery && count($gallery["name"]))for($i=0;$i<count($gallery["name"]);$i++){
            $name = str_replace(' ', '_',Utility::gen_random_string()) . $gallery['name'][$i];
            if($check_user_demo['is_demo']) {
                $short_path_image = "services/gallery/$name";
                $new_file_image_appointment_path  = WP_CONTENT_DIR . '/uploads/sites/' . $check_user_demo['blog_id']. DS . $short_path_image;
            } else {
                $short_path_image = "upload/services/gallery/$name";
                $new_file_image_appointment_path = WPBOOKINGPRO_PATH_ROOT . DS . $short_path_image;
            }

            if (!FileAlias::write($new_file_image_appointment_path, FileAlias::read($gallery['tmp_name'][$i]))) {
                throw new Exception(Text::_("can not upload image gallery"));
            }

            $item->gallery[] = $short_path_image;

            $data_gallery=array(
                "id"=>0,
                "type"=>'service',
                "object_id"=>$item->id,
                "path"=>$short_path_image,
                "name"=>$gallery['name'][$i],
            );
            $galleryModel->save($data_gallery);
        }
        if(isset($data['list_image_gallery_deleted'])) {
            $list_image_gallery_deleted = $data['list_image_gallery_deleted'];
            $list_image_gallery_deleted = (array)json_decode($list_image_gallery_deleted);
        }else{
            $list_image_gallery_deleted=array();
        }
        if(count($list_image_gallery_deleted))foreach ($list_image_gallery_deleted as $id){
            $galleryModel->delete($id);
        }
        $query = $this->_db->getQuery(true);
        $list_employee_id = isset($data['list_employee_id'])?$data['list_employee_id']:array();
        $query->clear()
            ->delete($this->getTableName('service_employee'))
            ->where('service_id=' . (int)$item->id);
        $this->_db->setQuery($query)->execute();
        foreach ($list_employee_id as $employee_id) {
            $query->clear()
                ->insert($this->getTableName('service_employee'))
                ->set('service_id=' . (int)$item->id)
                ->set('employee_id=' . (int)$employee_id);
            $this->_db->setQuery($query)->execute();
        }
        return $item;
    }
    public function getItem($id = 0)
    {
        if(isset($id) && $id > 0) {
            $item = (object)parent::getItem($id); // TODO: Change the autogenerated stub
            if(isset($item->id) && $item->id !== 0) {
                $input = Factory::getInput();
                $input->set('id', $id);
                $query = $this->db->getQuery(true);
                $query->select('gallery.*')
                    ->from($this->getTableName('gallery') . ' as gallery')
                    ->where('gallery.object_id=' . (int)$item->id)
                    ->where('gallery.type=' . $query->quote("service"));
                $item->list_image = $this->db->setQuery($query)->loadObjectList();
                $query->clear()
                    ->select('category.*')
                    ->from($this->getTableName('category') . ' AS category')
                    ->where('category.id=' . (int)$item->category_id);
                $item->category = $this->db->setQuery($query)->loadObject();
                $query->clear()
                    ->select('employee.*')
                    ->from($this->getTableName('employee') . ' AS employee')
                    ->leftJoin($this->getTableName('service_employee') . ' AS service_employee ON service_employee.employee_id=employee.id')
                    ->select('service_employee.start_time AS start_time, service_employee.end_time AS end_time, service_employee.price AS price')
                    ->where('service_employee.service_id=' . (int)$item->id);
                $list_employee = $this->db->setQuery($query)->loadObjectList();
                $list_employee_id = [];
                foreach ($list_employee as $employee) {
                    $employee->full_name = $employee->first_name.' '.$employee->last_name;
                    array_push($list_employee_id, $employee->id);
                }
                $item->list_employee = $list_employee;
                $item->list_employee_id = $list_employee_id;
                $query->clear()
                    ->select('location.*')
                    ->from($this->getTableName('location') . ' AS location')
                    ->where('location.id=' . (int)$item->location_id)
                ;
                $location = $this->db->setQuery($query)->loadObjectList();
                $item->location = reset($location);

                $query->clear()
                    ->select('*')
                    ->from($this->getTableName('user'))
                    ->where('id='.(int)$item->user_id)
                    ->orWhere('id='.(int)$item->category->user_id)
                ;
                $item->vendor = $this->_db->setQuery($query)->loadObject();

                $query->clear()
                    ->select('review.*')
                    ->from($this->getTableName('review').' AS review')
                    ->leftJoin($this->getTableName('service_review').' AS service_review ON service_review.review_id=review.id')
                    ->where('service_review.service_id='.(int)$item->id)
                    ->where('review.published=1')
                    ;
                $list_review = $this->_db->setQuery($query)->loadObjectList();
                $arr_rating_ambience = array();
                $arr_rating_cleanliness = array();
                $arr_rating_staff = array();
                $arr_rating_value = array();
                $arr_rating_avg = array();
                foreach ($list_review as $review) {
                    $rating_ambience = isset($review->rating_ambience)?$review->rating_ambience:0;
                    array_push($arr_rating_ambience,$rating_ambience);
                    $rating_cleanliness = isset($review->rating_cleanliness)?$review->rating_cleanliness:0;
                    array_push($arr_rating_cleanliness, $rating_cleanliness);
                    $rating_staff = isset($review->rating_staff)?$review->rating_staff:0;
                    array_push($arr_rating_staff, $rating_staff);
                    $rating_value = isset($review->rating_value)?$review->rating_value:0;
                    array_push($arr_rating_value, $rating_value);
                    $review->avg_rating = ($rating_ambience + $rating_cleanliness + $rating_staff + $rating_value) / 4;
                    array_push($arr_rating_avg,$review->avg_rating);
                }
                $item->list_review = $list_review;
                if(!empty($arr_rating_ambience)) {
                    $item->rating_ambience = array_sum($arr_rating_ambience) / count($arr_rating_ambience);
                } else {
                    $item->rating_ambience = 0;
                }
                if (!empty($arr_rating_cleanliness)) {
                    $item->rating_cleanliness = array_sum($arr_rating_cleanliness) / count($arr_rating_cleanliness);
                } else {
                    $item->rating_cleanliness = 0;
                }
                if(!empty($arr_rating_staff)) {
                    $item->rating_staff = array_sum($arr_rating_staff) / count($arr_rating_staff);
                } else {
                    $item->rating_staff = 0;
                }
                if(!empty($arr_rating_value)) {
                    $item->rating_value = array_sum($arr_rating_value) / count($arr_rating_value);
                } else {
                    $item->rating_value = 0;
                }
                if (!empty($arr_rating_avg)) {
                    $item->rating_avg = array_sum($arr_rating_avg) / count($arr_rating_avg);
                }else {
                    $item->rating_avg = 0;
                }


                $register = new Registry();
                $register->loadString($item->params);
                $item->params = $register;

                return $item;
            }

        }
    }
    public function getEventByServiceId($id=0) {
        $list_event=[];
        $query = $this->db->getQuery(true);
        $query->select('event.*')
            ->from($this->getTableName('event').' AS event')
            ->where('event.service_id='.(int)$id)
        ;
        $list_event = $this->db->setQuery($query)->loadObjectList();
        foreach ($list_event as &$item) {
            $query->clear()
                ->select("employee.*")
                ->from($this->getTableName('employee') . ' AS employee')
                ->leftJoin($this->getTableName('event_employee') . ' AS event_employee ON event_employee.employee_id=employee.id')
                ->where('event_employee.event_id=' . (int)$item->id);
            $list_employee = $this->db->setQuery($query)->loadObjectList();
            foreach ($list_employee as &$employee) {
                $employee->full_name = $employee->first_name. ' ' .$employee->last_name;
            }
            $item->list_employee = $list_employee;
            $query->clear()
                ->select('location.*')
                ->from($this->getTableName('location') . ' AS location')
                ->where('location.id=' . (int)$item->location_id);
            $item->list_location = $this->db->setQuery($query)->loadObjectList();

            $query->clear()
                ->select('rate.*')
                ->from($this->getTableName('rate') . ' AS rate')
                ->where('rate.object_id=' . (int)$item->id)
                ->where('rate.type=' . $query->quote(AdminHelper::getWpBookingEventKey()));
            $list_rate = $this->db->setQuery($query)->loadObjectList();
            $arrDate = [];
            $dateView = '';
            foreach ($list_rate as &$rate) {
                $arrDateFrom = date_parse_from_format('Y-m-d H:i:s', $rate->from);
                $arrDateTo = date_parse_from_format('Y-m-d H:i:s', $rate->to);
                $dateFromTs = mktime(0, 0, 0, $arrDateFrom['month'], $arrDateFrom['day'], $arrDateFrom['year']);
                $dateToTs = mktime(0, 0, 0, $arrDateTo['month'], $arrDateTo['day'], $arrDateTo['year']);
                $timeFromTs = mktime($arrDateFrom['hour'], $arrDateFrom['minute'], $arrDateFrom['second'],
                    $arrDateFrom['month'], $arrDateFrom['day'], $arrDateFrom['year']);
                $timeToTs = mktime($arrDateTo['hour'], $arrDateTo['minute'], $arrDateTo['second'], $arrDateTo['month'],
                    $arrDateTo['day'], $arrDateTo['year']);
                $dateFrom = date('F j, Y', $dateFromTs);
                $dateTo = date('F j, Y', $dateToTs);
                $timeFrom = date('g:i a', $timeFromTs);
                $timeTo = date('g:i a', $timeToTs);
                if ($dateFromTs != $dateToTs) {
                    $dateView .= ' , ' . $dateFrom . ' - ' . $dateTo . ' ' . $timeFrom . ' - ' . $timeTo;
                } else {
                    $dateView .= ' , ' . $dateFrom . ' ' . $timeFrom . ' - ' . $timeTo;
                }
                $arrDate[] = $dateFromTs;
                $arrDate[] = $dateToTs;
                $rate->start_time = date('g:i A', $timeFromTs);
                $rate->end_time = date('g:i A', $timeToTs);

            }
            $item->date_view = $dateView;
            if (!empty($arrDate)) {
                $item->min_date = min($arrDate);
                $item->max_date = max($arrDate);
            } else {
                $item->min_date = 0;
                $item->max_date = 0;
            }
            $item->list_rate = $list_rate;
        }
        return $list_event;
    }
    public function getEmployeeByServiceId($id=0) {
        $query = $this->_db->getQuery(true);
        $query->clear()
            ->select('DISTINCT employee.*')
            ->from($this->getTableName('employee') . ' AS employee')
            ->leftJoin($this->getTableName('service_employee') . ' AS service_employee ON service_employee.employee_id=employee.id')
            ->select('service_employee.start_time AS start_time, service_employee.end_time AS end_time, service_employee.price AS price')
            ->where('service_employee.service_id=' . (int)$id)
        ;
        $list_employee = $this->db->setQuery($query)->loadObjectList();
        foreach ($list_employee as $employee) {
            $employee->full_name = $employee->first_name.' '.$employee->last_name;
        }
        return $list_employee;
    }

}
