<?php

namespace Hura8\Components\Customer\Model;

use Hura8\Interfaces\AppResponse;
use Hura8\Interfaces\iEntityModel;
use Hura8\System\Controller\UrlManagerController;
use Hura8\System\IDGenerator;
use Hura8\System\Model\aEntityBaseModel;

class CustomerGroupModel extends aEntityBaseModel implements iEntityModel
{

    protected $tb_customer_per_group  = "tb_customer_per_group";

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


    public function updateItemCount($group_id) {
        $this->db->runQuery(
            "UPDATE `".$this->tb_entity."` SET 
                        `customer_count` = (SELECT COUNT(*) AS total  FROM `".$this->tb_customer_per_group."` WHERE `group_id` = ? ) 
                   WHERE `id` = ? LIMIT 1
                   ",
            ['d', 'd'], [$group_id, $group_id]
        );
    }


    public function getTotalCustomer($group_id, array $condition = [])
    {
        $query = $this->db->runQuery(
            " SELECT COUNT(*) as total FROM `".$this->tb_customer_per_group."` WHERE `group_id` = ? ",
            ['d'], [$group_id]
        );

        $total = 0;
        if ($rs = $this->db->fetchAssoc($query)) {
            $total = $rs['total'];
        }

        return $total;
    }


    public function getListCustomer($group_id, array $condition = [])
    {
        $numPerPage = (isset($condition['numPerPage']) && $condition['numPerPage'] > 0 ) ? intval($condition['numPerPage']) : 20 ;
        $page = (isset($condition['page']) && $condition['page'] > 0 ) ? intval($condition['page']) : 1 ;
        $order_by = " `id` DESC";

        $query = $this->db->runQuery(
            "SELECT `customer_id` FROM ".$this->tb_customer_per_group." WHERE `group_id` = ?  
                    ORDER BY ".$order_by."
                    LIMIT  ".(($page-1) * $numPerPage).", ".$numPerPage ,
            ['d'], [$group_id]
        ) ;

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

        $objCustomerModel = new CustomerModel();
        $list_info = $objCustomerModel->getListByIds($item_list_ids);

        // final list
        $final_list = [];
        foreach ($item_list_ids as $_id) {
            $final_list[] = $list_info[$_id] ?? null;
        }

        return $final_list;
    }


    public function removeCustomerFromAllGroup($customer_id)
    {
        $this->db->runQuery(
            "DELETE FROM `".$this->tb_customer_per_group."` WHERE `customer_id` = ?",
            ['d'], [$customer_id]
        );

        return true;
    }


    public function removeCustomer($customer_id, $group_id)
    {
        $this->db->runQuery(
            "DELETE FROM `".$this->tb_customer_per_group."` WHERE `group_id` =?  AND `customer_id` = ? LIMIT 1 ",
            ['d', 'd'],
            [$group_id, $customer_id]
        );

        $this->updateItemCount($group_id);

        return true;
    }


    public function addCustomer($customer_id, $group_id)
    {
        $query = $this->db->runQuery(
            " SELECT * FROM `".$this->tb_customer_per_group."` WHERE `group_id` = ?  AND `customer_id` = ? LIMIT 1 ",
            ['d', 'd'],
            [$group_id, $customer_id]
        );

        if ($this->db->fetchAssoc($query)) {
            return false;
        }

        $this->db->insert(
            $this->tb_customer_per_group,
            [
                "group_id" => $group_id,
                "customer_id" => $customer_id,
            ]
        );

        $this->updateItemCount($group_id);

        return true;
    }


    protected function _buildQueryConditionExtend(array $filter_condition): ?array
    {
        /*$condition = array(
            "q" => "",
            "status" => 0,
        );*/

        $catCondition = [];
        $bind_types = [];
        $bind_values = [];

        return array( join(" ", $catCondition), $bind_types, $bind_values);
    }


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

        if(!$info['group_code']) $info['group_code'] = $info['title'];
        $info['group_code'] = $this->createUniqueCode(0, $info['group_code']);

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

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


    protected function afterCreateItem($new_item_id, $new_item_info)
    {

    }

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

        if(isset($info['group_code'])) {
            if(!$info['group_code']) $info['group_code'] = $info['title'];
            $info['group_code'] = $this->createUniqueCode($item_id, $info['group_code']);
        }

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

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


    protected function createUniqueCode($current_item_id, $wanted_code){

        $clean_code = UrlManagerController::create_url_index($wanted_code);

        //if exist and belong other id, create a new one
        $query = $this->db->runQuery("SELECT `id` FROM `".$this->tb_entity."` WHERE `group_code` = ? LIMIT 1 ", ['s'], [$clean_code]) ;
        if($info = $this->db->fetchAssoc($query)){
            if($info['id'] != $current_item_id) {
                $new_code = $clean_code."-".IDGenerator::createStringId(3);
                return $this->createUniqueCode($current_item_id, $new_code);
            }
        }

        return $clean_code;
    }


    protected function afterUpdateItem($item_id, $old_item_info, $new_item_info)
    {

    }

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

    protected function afterDeleteItem($item_id, $item_info)
    {

    }

    protected function extendedFilterOptions(): array
    {
        return [];
    }
}
