<?php
namespace WpBookingHotelAdmin\app\models;
defined('_WPBOOKINGHOTEL_EXEC') or die;

use Exception;
use WpBookingHotel\Factory;
use WpBookingHotel\Language\Text;
use WpBookingHotel\Mvc\Model\ModelForm;
use WpBookingHotel\Filesystem\File as FileAlias;
use WpBookingHotel\Mvc\Model\Model;
use WpBookingHotel\Form\Form;
use WpBookingHotel\Mvc\Model\ModelList;
use WpBookingHotel\Registry\Registry;
use WpBookingHotel\Utilities\Utility;
use WpBookingHotelAdmin\app\helpers\AdminHelper;
use WpBookingHotelAdmin\app\helpers\RoomTypeHelper;

class HotelModel extends ModelForm
{
    /**
     * @var string
     */
    public $context = "hotel";
    /**
     * @var string
     */
    public $table_name = "hotel";

    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();
        $now = Factory::getDate();
        $is_new = (isset($data['id']) && $data['id'] != '' && is_numeric($data['id']))?false:true;
        if(!isset($data['id']) && $is_new) {
            $data['created_date'] = $now->toSql();
        } else {
            $data['update_time'] = $now->toSql();
        }
        $item =  parent::save($data); // TODO: Change the autogenerated stub

        if($is_new) {
            $hotel_id = $item->id;
        } else {
            $hotel_id = $data['id'];
        }
        $list_key_properties=AdminHelper::$list_key_hotel_properties;
        unset($list_key_properties['roomtype']);
        unset($list_key_properties['service']);
        unset($list_key_properties['rate']);
        unset($list_key_properties['tag']);

        foreach ($list_key_properties as $key_hotel=>$description){
            if(!isset($data[$key_hotel]))
                continue;
            $data_properties=array();
            $data_properties[]=$data[$key_hotel];
            AdminHelper::deletePropertyByKey($key_hotel,$hotel_id);
            AdminHelper::insertNewPropertyByKey($key_hotel,$data_properties, $hotel_id);
            $item->{$key_hotel}=$data_properties;
        }
        $room_type_id = isset($data['room_type_id'])?$data['room_type_id']:array();
        if(count($room_type_id) == 1 && trim($room_type_id['0']) == '') {
            $room_type_id = array();
        }

        $price_adult = isset($data['price_adult'])?$data['price_adult']:array();
        if(count($price_adult)== 1 && trim($price_adult['0']) == '') {
            $price_adult = array();
        } else {
            foreach ($price_adult as &$value_price_adult) {
                $value_price_adult = str_replace("$ ",'',$value_price_adult);
            }
        }
        $price_child = isset($data['price_child'])?$data['price_child']:array();
        if(count($price_child) == 1 && trim($price_child['0']) == '') {
            $price_child = array();
        } else {
            foreach ($price_child as &$value_price_child) {
                $value_price_child = str_replace("$ ",'',$value_price_child);
            }
        }

        $query = $this->_db->getQuery(true);
        if(!empty((array)$room_type_id)) {
            $query->clear()
                ->delete($this->getTableName('hotelproperty'))
                ->where('type='.$query->quote(AdminHelper::getWpBookingRoomtypeKey()))
                ->where('hotel_id='.(int)$hotel_id)
            ;
            $this->_db->setQuery($query)->execute();

            foreach ($room_type_id as $key => $value)  {
                $query->clear()
                    ->insert($this->getTableName('hotelproperty'))
                    ->set('object_id=' . (int)$value)
                    ->set('hotel_id=' . (int)$hotel_id)
                    ->set('price_adult='.(float)$price_adult[$key])
                    ->set('price_child='.(float)$price_child[$key])
                    ->set('type='.$query->quote(AdminHelper::getWpBookingRoomtypeKey()))
                ;
                $this->_db->setQuery($query)->execute();

            }
        }



        // save service

        $service_id = isset($data['service'])?$data['service']:array();
        if(count($service_id) == 1 && trim($service_id['0']) == '') {
            $service_id = array();
        }
        $price_service = isset($data['price_service'])?$data['price_service']:array();
        if(count($price_service) == 1 && trim($price_service['0']) == '') {
            $price_service = array();
        } else {
            foreach ($price_service as &$value_price_service) {
                $value_price_service = str_replace("$ ",'',$value_price_service);
            }
        }

        if(!empty((array)$service_id)) {
            $query->clear()
                ->delete($this->getTableName('hotelproperty'))
                ->where('type='.$query->quote(AdminHelper::getWpBookingServiceKey()))
                ->where('hotel_id='.(int)$hotel_id)
            ;
            $this->_db->setQuery($query)->execute();

            foreach ($service_id as $key => $value)  {
                $query->clear()
                    ->insert($this->getTableName('hotelproperty'))
                    ->set('object_id=' . (int)$value)
                    ->set('hotel_id=' . (int)$hotel_id)
                    ->set('price_service='.(float)$price_service[$key])
                    ->set('type='.$query->quote(AdminHelper::getWpBookingServiceKey()))
                ;
                $this->_db->setQuery($query)->execute();

            }
        }

        // save rate

        $check_in = isset($data['check_in'])?$data['check_in']:array();
        if(count($check_in) == 1 && trim($check_in['0']) == '') {
            $check_in = array();
        }
        $check_out = isset($data['check_out'])?$data['check_out']:array();
        if(count($check_out) == 1 && trim($check_out['0']) == '') {
            $check_out = array();
        }
        $modelRate = Model::getInstance('rate');

        if(!empty($check_in) && !empty($check_out)) {
            $query->clear()
                ->delete($this->getTableName('rate'))
                ->where('object_id='.(int)$hotel_id)
                ->where('type='.$query->quote('hotel'))
            ;
            $this->_db->setQuery($query)->execute();

            $query->clear()
                ->delete($this->getTableName('hotelproperty'))
                ->where('hotel_id='.(int)$hotel_id)
                ->where('type='.$query->quote(AdminHelper::getWpBookingRateKey()))
            ;
            $this->_db->setQuery($query)->execute();

            foreach ($check_in as $key => $checkin_item) {
                $item_rate = [
                    "id" => 0,
                    "check_in" => Factory::getDate($checkin_item)->toSql(),
                    "check_out" => Factory::getDate($check_out[$key])->toSql(),
                    "type"=>'hotel',
                    "object_id"=> $hotel_id
                ];
                $item_rate = $modelRate->save($item_rate);



                $query->clear()
                    ->insert($this->getTableName('hotelproperty'))
                    ->set('object_id=' . (int)$item_rate->id)
                    ->set('hotel_id=' . (int)$hotel_id)
                    ->set('type='.$query->quote(AdminHelper::getWpBookingRateKey()))
                ;
                $this->_db->setQuery($query)->execute();
            }
        }

        //save tag
        $tag_id = isset($data['tag'])?$data['tag']:array();
        $modelTag = Model::getInstance('tag');
        if(!empty((array)$tag_id)) {
            foreach ($tag_id as $tag_id_item) {
                if(!is_numeric($tag_id_item) && is_string($tag_id_item) && trim($tag_id_item) !='')  {
                    $data_tag = [
                        "name"=> $tag_id_item
                    ];
                    $tag_item_new = $modelTag->save($data_tag);
                    array_push($tag_id,$tag_item_new->id);
                }

            }
            $query->clear()
                ->delete($this->getTableName('hotelproperty'))
                ->where('type='.$query->quote(AdminHelper::getWpBookingTagKey()))
                ->where('hotel_id='.(int)$hotel_id)
            ;
            $this->_db->setQuery($query)->execute();

            foreach ($tag_id as $key => $value)  {
                $query->clear()
                    ->insert($this->getTableName('hotelproperty'))
                    ->set('object_id=' . (int)$value)
                    ->set('hotel_id=' . (int)$hotel_id)
                    ->set('type='.$query->quote(AdminHelper::getWpBookingTagKey()))
                ;
                $this->_db->setQuery($query)->execute();

            }
        }


        // insert image
        $image=Factory::getInput()->files->get('image','','raw');
        if(!empty($image['name'])) {
            $name = str_replace(' ', '_',Utility::gen_random_string()) . $image['name'];
            $short_path_image = "upload/hotels/images/cover/$name";
            $new_file_image_hotel_path = WPBOOKINGHOTEL_PATH_ROOT . DS . $short_path_image;
            if (!FileAlias::write($new_file_image_hotel_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);
        }
        // insert background
        $background_img=Factory::getInput()->files->get('background_img','','raw');
        if(!empty($background_img['name'])) {
            $name = str_replace(' ', '_',Utility::gen_random_string()) . $background_img['name'];
            $short_path_image = "upload/hotels/images/background_img/$name";
            $new_file_image_hotel_path = WPBOOKINGHOTEL_PATH_ROOT . DS . $short_path_image;
            if (!FileAlias::write($new_file_image_hotel_path, FileAlias::read($background_img['tmp_name']))) {
                throw new Exception(Text::_("can not upload image cover"));
            }
            $item->background_img = $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];
            $short_path_image = "upload/gallery/hotels/$name";
            $new_file_image_hotel_path = WPBOOKINGHOTEL_PATH_ROOT . DS . $short_path_image;
            if (!FileAlias::write($new_file_image_hotel_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"=>"hotel",
                "object_id"=>$hotel_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);
        }

        return $item;
    }


    public function getItem($id = 0)
    {
        $db=$this->_db;
        $query=$db->getQuery(true);
        $hotel= parent::getItem($id); // TODO: Change the autogenerated stub
        if(isset($hotel->id) && $hotel->id!=0) {
            $query->clear()
                ->select('roomtype.id')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->leftJoin($this->getTableName('roomtype').' AS roomtype ON roomtype.id=hotelproperty.object_id')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingRoomtypeKey()))
            ;
            $list_room_type= $this->_db->setQuery($query)->loadColumn();
            $hotel->room_type_id=$list_room_type;

            $query->clear()
                ->select('hotelproperty.price_adult')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingRoomtypeKey()))
                ;
            $price_adult = $this->_db->setQuery($query)->loadColumn();
            $hotel->price_adult = $price_adult;

            $query->clear()
                ->select('hotelproperty.price_child')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingRoomtypeKey()))
                ;
            $price_child = $this->_db->setQuery($query)->loadColumn();
            $hotel->price_child = $price_child;

            $query->clear()
                ->select('DISTINCT location.id')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->leftJoin($this->getTableName('location').' AS location ON location.id=hotelproperty.object_id')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingDestinationKey()))
            ;
            $list_destination= $this->_db->setQuery($query)->loadResult();
            $hotel->destination=$list_destination;

            $query->clear()
                ->select('service.id')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->leftJoin($this->getTableName('service').' AS service ON service.id=hotelproperty.object_id')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingServiceKey()))
            ;
            $list_service_id = $this->_db->setQuery($query)->loadColumn();
            $hotel->service = $list_service_id;

            $query->clear()
                ->select('hotelproperty.price_service')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingServiceKey()))
            ;
            $price_service = $this->_db->setQuery($query)->loadColumn();
            $hotel->price_service = $price_service;

            $query->clear()
                ->select('DISTINCT tag.id')
                ->from($this->getTableName('hotelproperty').' AS hotelproperty')
                ->leftJoin($this->getTableName('tag').' AS tag ON tag.id=hotelproperty.object_id')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingTagKey()))
            ;
            $list_tag= $this->_db->setQuery($query)->loadColumn();
            $hotel->tag=$list_tag;

            $query->clear()
                ->select('DISTINCT rate.*')
                ->from($this->getTableName('rate').' AS rate')
                ->leftJoin($this->getTableName('hotelproperty').' AS hotelproperty ON hotelproperty.object_id=rate.id')
                ->where('hotelproperty.hotel_id='.(int)$hotel->id)
                ->where('hotelproperty.type='.$query->quote(AdminHelper::getWpBookingRateKey()))
            ;
            $list_rate= $this->_db->setQuery($query)->loadObjectList();
            $hotel->list_rate=$list_rate;

            $query->clear()
                ->select('DISTINCT gallery.*')
                ->from($this->getTableName('gallery').' AS gallery')
                ->where('object_id='.(int)$hotel->id)
                ->where('type='.$query->quote('hotel'))
            ;
            $list_image= $this->_db->setQuery($query)->loadObjectList();
            $hotel->gallery=$list_image;

            $query->clear()
                ->select('country.countryname')
                ->from($this->getTableName('country').' AS country')
                ->where('country.phonecode='.(int)$hotel->phonecode)
                ->where('country.countrycode='.$query->quote($hotel->countrycode))
            ;
            $hotel->country_name = $this->_db->setQuery($query)->loadResult();

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

        }
        return $hotel;
    }

}
