<?php

namespace Hura8\Components\Deal\Model;

use Hura8\Components\Product\AdminController\AProductController;
use Hura8\Interfaces\AppResponse;
use Hura8\Interfaces\TableName;
use Hura8\System\Model\aEntityBaseModel;
use Hura8\System\TimeManager;

class DealCollectionModel extends aEntityBaseModel
{

    protected $tb_deal = "tb_deal";
    protected $tb_collection_item = "tb_deal_collection_item";

    public function __construct()
    {
        parent::__construct('deal_collection');
    }

    protected function extendedFilterOptions(): array
    {
        return [

        ];
    }


    protected function _buildQueryConditionExtend(array $filter_condition): ?array
    {
        $where_clause = [];
        $bind_types = [];
        $bind_values = [];

        return [
            join(" ", $where_clause),
            $bind_types,
            $bind_values
        ];
    }

    public function getAllProductIdInCollection($collection_id) {
        $deal_id_list = $this->getAllDealIdInCollection($collection_id);

        if(!sizeof($deal_id_list)) return array();

        $query = $this->db->runQuery("SELECT `pro_id` FROM `".$this->tb_deal."`  WHERE `id` IN (". join(',', $deal_id_list).") ");

        return array_map(function ($item){
            return $item['pro_id'];
        }, $this->db->fetchAll($query));
    }

    public function getAllDealIdInCollection($collection_id) {
        $query = $this->db->runQuery("SELECT `deal_id` FROM `".$this->tb_collection_item."` WHERE `collection_id` = ? ", ['d'], [$collection_id]);

        return array_map(function ($item){
            return $item['deal_id'];
        }, $this->db->fetchAll($query));
    }

    public function updateAllDealInCollection($collection_id, $price, $time){

        $from_time = ($time['from_date'] != '') ? strtotime(TimeManager::convert_date_from_javascript($time['from_date'])." ".$time['from_time_minute'].":00") : 0;
        $to_time = ($time['to_date'] != '') ? strtotime(TimeManager::convert_date_from_javascript($time['to_date'])." ".$time['to_time_minute'].":00") : 0;

        $deal_id_list = $this->getAllDealIdInCollection($collection_id);

        if(!sizeof($deal_id_list)) return false;

        $query = $this->db->runQuery("SELECT `id`, `pro_id` FROM `".$this->tb_deal."` WHERE `id` IN (". join(',', $deal_id_list).") ");
        $product_list_id = array();
        foreach ( $this->db->fetchAll($query) as $info ) {
            $product_list_id[$info['pro_id']] = $info['id'];
        }

        //get product prices
        $query = $this->db->runQuery("
                SELECT `id`, price FROM ".TableName::PRODUCT."
                WHERE `id` IN (". join(',', array_keys($product_list_id)) .")
             ");

        $objDealModel = new DealModel();

        foreach ( $this->db->fetchAll($query) as $_info ) {
            $product_id = $_info['id'];
            $product_price = $_info['price'];
            $deal_price = ($price['type'] == 'percent') ? round($product_price * (100 - $price['value']) / 100) : ($product_price - $price['value']);

            //update
            $objDealModel->updatePriceAndTime(
                $product_list_id[$product_id],
                array(
                    "price"     => $deal_price,
                    "from_time" => $from_time,
                    "to_time"   => $to_time,
                )
            );
        }

        return true;
    }

    public function addProductToCollection($product_id, $collection_id){

        $objAProductController = new AProductController();
        $product_info = $objAProductController->getInfo($product_id);

        if($product_info){

            $objDealModel = new DealModel();

            $deal_id = $objDealModel->create(array(
                "pro_id"        => $product_id,
                "title"         => $product_info['title'],
                "price"         => $product_info['price'],
                "quantity"      => $product_info['quantity'],
                "min_purchase"  => 1,
                "from_time"     => 0,
                "to_time"       => 0,
                "ordering"      => $product_info[''],
                "description"   => '',
            ));

            $this->addToCollection($deal_id, $collection_id);

            return $deal_id;
        }

        return 0;
    }

    public function removeFromCollection($deal_id, $collection_id){
        $this->db->runQuery(
            "DELETE FROM `".$this->tb_collection_item."` WHERE `deal_id` = ? AND `collection_id` = ?  ",
            ['d', 'd'],
            [$deal_id, $collection_id]
        );

        $this->updateCollectionCount($collection_id);
    }

    public function addToCollection($deal_id, $collection_id){
        $query = $this->db->runQuery(
            "SELECT `deal_id` FROM `".$this->tb_collection_item."`  WHERE `deal_id`= ? AND `collection_id` = ? LIMIT 1 ",
            ['d', 'd'], [$deal_id, $collection_id]
        );

        if( ! $this->db->fetchAssoc($query) ){
            $this->db->insert(
                $this->tb_collection_item ,
                [
                    'collection_id' => $collection_id ,
                    'deal_id' => $deal_id,
                    'create_by' => ADMIN_ID,
                    'create_time' => CURRENT_TIME,
                ]
            );

            $this->updateCollectionCount($collection_id);
        }
    }

    protected function updateCollectionCount($collection_id){
        $this->db->runQuery(
            "UPDATE `".$this->tb_entity."` SET 
                                `deal_count` = (SELECT COUNT(*) FROM `".$this->tb_collection_item."` WHERE `collection_id` = ? )
						WHERE `id` = ? LIMIT 1 ",
            ['d', 'd'],
            [$collection_id, $collection_id]
        );
    }

    public function updateCollectionView($id){
        $this->db->runQuery("UPDATE `".$this->tb_entity."` SET `visit` = `visit` + 1 WHERE `id` = ? LIMIT 1 ", ['d'], [ $id ]);
    }


    protected function beforeCreateItem(array $input_info) : AppResponse
    {
        $info = $input_info;

        $info['create_time']    = CURRENT_TIME;
        $info['create_by']      = ADMIN_NAME;
        $info['last_update']    = CURRENT_TIME;
        $info['last_update_by'] = ADMIN_NAME;

        return new AppResponse('ok', null, $info);
    }

    protected function afterCreateItem($new_item_id, $new_item_info)
    {
        // TODO: Implement afterCreateItem() method.
    }

    protected function beforeUpdateItem($item_id, $current_item_info, $new_input_info) : AppResponse
    {
        $info = $new_input_info;

        $info['last_update']    = CURRENT_TIME;
        $info['last_update_by'] = ADMIN_NAME;

        return new AppResponse('ok', null, $info);
    }

    protected function afterUpdateItem($item_id, $old_item_info, $new_item_info)
    {
        // TODO: Implement afterUpdateItem() method.
    }

    protected function beforeDeleteItem($item_id, $item_info) : AppResponse
    {
        return new AppResponse('ok');
    }

    protected function afterDeleteItem($item_id, $item_info)
    {
        // TODO: Implement afterDeleteItem() method.
    }


}
