<?php

namespace OfficeBrain\Bundle\ServiceGroupBundle\Manager\Extended;

use OfficeBrain\Bundle\ServiceGroupBundle\Manager\AbstractManager\ServiceRuleAbstract;

/**
 * @author OfficeBrain 4589 <info@officebrain.com>
 *
 * Description : Service Group Abstract Class
 */
class ServiceRuleAdminExtended extends ServiceRuleAbstract
{
    public function __construct($entityManager, $request, $session, $serviceContainer, $translatorService, $countries, $languages, $coreManager, $productTagManager, $serviceGroupAPiClient,  $twigExtension)
    {
        parent::__construct($entityManager, $request, $session, $serviceContainer, $countries, $languages, $coreManager, $productTagManager, $serviceGroupAPiClient, $translatorService,  $twigExtension);

        $this->conditionAry = $this->getConditionArray();
        $this->conditionMutlipleValueAry = $this->getConditionMultipleValueList();
        $this->cultureList = $this->getCultureList();

        $this->actionTypes = $this->getActionTypes();
        $this->actionLimitPer = $this->getActionLimitPer();
        $this->actionRuleTypes = $this->getActionRuleTypes();
        $this->actionChargeTypes = $this->getActionChargeTypes();
        $this->actionAmountTypes = $this->getActionAmountTypes();

        $this->recordsPerPage = $this->projectSetting['configuration_rule']['promo_discount']['option']['rule_master']['option']['record_per_page'];

        $this->serviceRuleMasterRepository = $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMaster')
                                                ->setProjectSetting($this->projectSetting);

        $this->translatorService = $translatorService;
    }

    /**
     * @author Employee Id: 4589
     * Description : Get Rule master list
     *
     * @param 1 : Search Query
     * @param 2 : Culture
     *
     * @return type : Rule Master List
     *
     * @throws Exception: Null
     */
    public function getRuleMasterList()
    {
        $data = array();

        $countryId = $this->request->get('countryId', $this->countryId);
        $searchQuery = $this->request->get('search_query', null);
        $page = $this->request->get('page', 1);

        $ruleMasterList = $this->serviceRuleMasterRepository->findByCountryId($this->ruleType, $countryId, $searchQuery);

        $pagination = $this->paginatorService->paginate($ruleMasterList, $page, $this->recordsPerPage, array(), count($ruleMasterList));

        $data['pagination'] = $pagination;
        $data['records_per_page'] = $this->recordsPerPage;
        $data['page'] = $page;
        $data['search_query'] = $searchQuery;
        $data['country_id'] = $countryId;

        return $data;
    }

    /**
     * @author Employee Id: 4589
     * Description : Get rule master rule by rule type
     *
     * @param 1 : Rule type
     * @param 2 : Culture
     *
     * @return type : ServiceRuleMasterRule
     *
     * @throws Exception: Null
     */
    public function getRuleMasterListByCountry()
    {
        $countryId = $this->request->get('countryId', $this->countryId);

        return $ruleMasterList = $this->serviceRuleMasterRepository->findByCountryId($this->ruleType, $countryId);
    }

    /**
     * @author Employee Id: 4589
     * Description : Check Rule Name exist in rule Master
     *
     * @param 1 : Rule Name
     * @param 2 : Culture
     * @param 3 : Service rule Master Id
     *
     * @return type : boolean
     *
     * @throws Exception: Null
     */
    public function checkRuleNameExistServiceRuleMaster($ruleName, $countryId, $serviceRuleMasterId = null)
    {
        return $this->serviceRuleMasterRepository->isRuleNameExists($this->ruleType, $ruleName, $countryId, $serviceRuleMasterId);
    }

    /**
     * @author Employee Id: 4589
     * Description : Set Rule Master
     *
     * @param 1 : Form
     *
     * @return type : boolean or error message
     *
     * @throws Exception: Null
     */
    public function setRuleMaster($form)
    {
        $ruleMasterRepo = $this->serviceRuleMasterRepository;
        $form->bind($this->request);

        $ruleCondError = null;
        $dataAry = $this->request->request->all();

        if (isset($dataAry['has_rule_cond_error']) && $dataAry['has_rule_cond_error'] == 'true') {
            $ruleCondError = array('rule-condition' => 'There is error(s) in Rules, please check it.');
        } elseif (!isset($dataAry['rule_condition']) || trim($dataAry['rule_condition']) == null) {
            $ruleCondError = array('rule-condition' => 'Please enter at-least one Rule.');
        } elseif (isset($dataAry['rule_condition']) && isset($dataAry['rules'])) {
            $ruleConditionAry = null;
            $rule_condition = (isset($dataAry['rule_condition']) ? $dataAry['rule_condition'] : '');
            $rule_condition = explode('=', $rule_condition);
            $ruleConditionAry = array('condition' => $rule_condition[1],'rules' => $dataAry['rules']);
            $ruleCondError = $this->validateRules($dataAry['rules']);
        }

        if ($form->isValid() && $ruleCondError === null) {
            $data = array();
            $data['rule_name'] = $form->get('ruleName')->getData();
            $data['rule_type'] = $form->get('ruleType')->getData();
            $data['country_id'] = $form->get('countryId')->getData();

            $data['status'] = $dataAry['service_group_data']['status'];
            $data['rule_condition'] = null;
            $rule_condition = (isset($dataAry['rule_condition']) ? $dataAry['rule_condition'] : '');

            if (isset($dataAry['rules'])) {
                $rule_condition = explode('=', $rule_condition);
                $data['rule_condition'] = array('condition' => $rule_condition[1],'rules' => $dataAry['rules']);
            }

            $ruleName = $data['rule_name'];
            $ruleType = $data['rule_type'];

            $status = $data['status'];
            $countryId = $data['country_id'];
            $ruleCondition = isset($data['rule_condition']) ? ($data['rule_condition']) : '';

            if ($ruleName) {
                $ruleMasterObj =
                            $ruleMasterRepo->setServiceRuleMaster($ruleName, $ruleType, $status, $countryId);

                if ($ruleMasterObj == null) {
                    return array('error_message' => $this->translatorService->trans('admin.service_group_management.rule_master.rule_master_blank'));
                } else {
                    if ($ruleCondition != null) {
                        //$this->setRuleCondition($ruleMasterObj, $ruleCondition->rules, $ruleCondition->condition);
                        $this->setRuleCondition($ruleMasterObj, $ruleCondition['rules'], $ruleCondition['condition']);

                        $this->copyRuleMaster($ruleMasterObj->getId());
                    }

                    return true;
                }
            } else {
                return array('error_message' => $this->translatorService->trans('admin.service_group_management.rule_master.rule_name_blank'));
            }
        } else {
            return $ruleCondError;
        }
    }

    /**
     * @author Employee Id: 4589
     * Description : Copy Rule Master
     *
     * @param 1 : Service Group Id
     *
     * @return type : Boolean
     *
     * @throws Exception: Null
     */
    public function copyRuleMaster($id = null)
    {
        if (!$id) {
            $id = $this->request->get('service_group_id', null);
        }
        if ($id) {
            $serviceRuleMaster = $this->serviceRuleMasterRepository->getServiceRuleMasterForCopy($id);
            if ($serviceRuleMaster) {
                $make_copy_country = $this->request->request->get('make_copy_country');
                $make_copy_status = $this->request->request->get('make_copy_status');
                if ($make_copy_country) {
                    foreach ($make_copy_country as $countryId => $value) {
                        if (isset($make_copy_status[$countryId])) {
                            $this->makeCopyRuleMaster(clone $serviceRuleMaster, $countryId, true);
                        } else {
                            $this->makeCopyRuleMaster(clone $serviceRuleMaster, $countryId, false);
                        }
                    }
                }

                // commit persist objects if any
                $this->serviceRuleMasterRepository->commit();
            }

            return true;
        }

        return false;
    }

    /**
     * @author Employee Id: 4589
     * Description : Make Rule master copy
     *
     * @param 1 : Service Rule Master
     * @param 2 : Country Id
     * @param 3 : isActive
     *
     * @return type : Null
     *
     * @throws Exception: Null
     */
    public function makeCopyRuleMaster($serviceRuleMaster, $countryId, $isActive)
    {
        $serviceRuleMaster->setId(null);

        if ($countryId) {
            $serviceRuleMaster->setStatus($isActive);
            $serviceRuleMaster->setCountryId($countryId);

            $ruleName = 'Copy of '.$serviceRuleMaster->getRuleName();
            $serviceRuleMaster->setRuleName($ruleName);

            $this->serviceRuleMasterRepository->copyRuleMaster($serviceRuleMaster);
        }
    }

    /**
     * @author Employee Id: 4589
     * Description : Update Rule master
     *
     * @param 1 : Form
     * @param 2 : Rule Master Id
     * @param 3 : Cultrure
     *
     * @return type : Messages
     *
     * @throws Exception: Null
     */
    public function updateRuleMaster($form, $id, $countryId)
    {
        $ruleMasterRepo = $this->serviceRuleMasterRepository;
        $form->bind($this->request);

        $ruleCondError = null;

        $dataAry = $this->request->request->all();

        if (isset($dataAry['has_rule_cond_error']) && $dataAry['has_rule_cond_error'] == 'true') {
            $ruleCondError = array('rule-condition' => 'There is error(s) in Rules, please check it.');
        } elseif (!isset($dataAry['rule_condition']) || trim($dataAry['rule_condition']) == null) {
            $ruleCondError = array('rule-condition' => 'Please enter at-least one Rule.');
        } elseif (isset($dataAry['rule_condition']) && isset($dataAry['rules'])) {
            $ruleConditionAry = null;
            $rule_condition = (isset($dataAry['rule_condition']) ? $dataAry['rule_condition'] : '');
            $rule_condition = explode('=', $rule_condition);
            $ruleConditionAry = array('condition' => $rule_condition[1],'rules' => $dataAry['rules']);
            $ruleCondError = $this->validateRules($dataAry['rules']);
        }

        if ($form->isValid() && $ruleCondError === null) {
            $data = array();

            $data['rule_name'] = $form->get('ruleName')->getData();
            $data['status'] = $dataAry['service_group_data']['status'];
            $data['rule_condition'] = null;
            $rule_condition = (isset($dataAry['rule_condition']) ? $dataAry['rule_condition'] : '');
            if (isset($dataAry['rules'])) {
                $rule_condition = explode('=', $rule_condition);
                $data['rule_condition'] = array('condition' => $rule_condition[1],'rules' => $dataAry['rules']);
            }

            $serviceRuleMastID = $id;

            if ($serviceRuleMastID) {
                $ruleName = $data['rule_name'];

                $status = $data['status'];

                $ruleCondition = isset($data['rule_condition']) ? ($data['rule_condition']) : '';

                if ($ruleName && $serviceRuleMastID) {
                    $ruleMasterObj = $ruleMasterRepo->editServiceRuleMaster($serviceRuleMastID, $ruleName, $status);

                    if ($ruleMasterObj == null) {
                        return array('error_message' => $this->translatorService->trans('admin.service_group_management.rule_master.rule_master_blank'));
                    } else {
                        if ($ruleCondition != null) {
                            $this->removeExistingRuleCondition($serviceRuleMastID);
                            $this->setRuleCondition($ruleMasterObj, $ruleCondition['rules'], $ruleCondition['condition']);
                        }

                        return true;
                    }
                } else {
                    return array('error_message' => $this->translatorService->trans('admin.service_group_management.rule_master.rule_name_blank'));
                }
            } else {
                return array('error_message' => $this->translatorService->trans('admin.service_group_management.rule_master.rule_id_blank.'));
            }
        }
    }

    /**
     * @author Employee Id: 4589
     * Description : Delete Rule master
     *
     * @param 1 : Rule Master Id
     *
     * @return type : Rule Master
     *
     * @throws Exception: Null
     */
    public function deleteRuleMaster($id)
    {
        $ruleMasterRepo = $this->serviceRuleMasterRepository;
        $ruleMasterRepo->setProjectSetting($this->projectSetting);

        $removeRule = $ruleMasterRepo->deleteServiceRuleMaster($id);
        if ($removeRule) {
            $allMappings = $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMappingRules')->getAllMAppingForRule($id);

            foreach ($allMappings as $mapping) {
                if ($mapping->getRuleMappingId()->getId()) {
                    $this->deleteRuleMapping($mapping->getRuleMappingId()->getId());
                }
            }
        }
        return $removeRule;
    }

    /**
     * @author Employee Id: 4273
     * Description : Change Status Rule master
     *
     * @param 1 : Rule Master Id
     *
     * @return type : Rule Master
     *
     * @throws Exception: Null
     */
    public function changeRuleMasterStatus($id)
    {
        $ruleMasterRepo = $this->serviceRuleMasterRepository;
        $ruleMasterRepo->setProjectSetting($this->projectSetting);

        return $ruleMasterRepo->changeStatusServiceRuleMaster($id);
    }

    /**
     * @author Employee Id: 4589
     * Description : Set Rule condition
     *
     * @param 1 : object $masterIdObj
     * @param 2 : array  $ruleArray
     * @param 3 : array  $condOp
     * @param 4 : int    $parentId
     * @param 5 : object &$counter
     *
     * @return type: NULL
     *
     * @throws Exception: Null
     * */
    public function setRuleCondition($masterIdObj, $ruleArray, $condOp, $parentId = 0, &$counter = 0)
    {

        //*** Add into rule_main_condition
        $ruleMasterMainCondObj = $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMainCondition')
        ->addServiceRuleMainCondition($masterIdObj, $parentId, $condOp);

        foreach ($ruleArray as $rule) {
            if (isset($rule['rules'])) {
                //$this->setRuleCondition($masterIdObj, $rule->rules, $rule->condition, $ruleMasterMainCondObj->getId(), $counter);
                $this->setRuleCondition($masterIdObj, $rule['rules'], $rule['condition'], $ruleMasterMainCondObj->getId(), $counter);
            } else {
                ++$counter;

                //*** Add into rule_inner_condition
                $ruleMasterInnerCond = $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleInnerCondition')
                ->addServiceRuleInnerCondition($ruleMasterMainCondObj, $rule['field'], $rule['operator'], $rule['value'], $counter);
            }
        }
    }

    /**
     * @author Employee Id: 4589
     * Description : Check Rule Action Exists
     *
     * @param 1 : Rule Id
     *
     * @return type : Rule action
     *
     * @throws Exception: Null
     */
    public function checkRuleActionExists($rulesId)
    {
        return $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMappingActions')->checkRuleActionExists($rulesId);
    }

    /**
     * @author Employee Id: 4589
     * Description : Add Service Rule Action
     *
     * @param 1 :  $ruleMappingRuleId
     * @param 2 :  $type
     * @param 3 :  $limitBy
     * @param 4 :  $limitAllowed
     * @param 5 :  $ruleType
     * @param 6 :  $chargeType
     * @param 7 :  $amountType
     * @param 8 :  $amount
     * @param 9 :  $maxQty
     * @param 10 : $isShippingFree
     * @param 11 : $isTaxFree
     * @param 12 : $isActive
     *
     * @return type : Rule action
     *
     * @throws Exception: Null
     */
    public function addServiceRuleMappingActions($ruleMappingRuleId, $type, $limitBy, $limitAllowed, $ruleType, $chargeType, $amountType, $amount, $maxQty, $isShippingFree, $isTaxFree, $isActive)
    {
        return $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMappingActions')->addServiceRuleMappingActions($ruleMappingRuleId, $type, $limitBy, $limitAllowed, $ruleType, $chargeType, $amountType, $amount, $maxQty, $isShippingFree, $isTaxFree, $isActive);
    }

    /**
     * @author Employee Id: 4589
     * Description : Edit Service  Rule Action
     *
     * @param 1 :  $id
     * @param 2 :  $type
     * @param 3 :  $limitBy
     * @param 4 :  $limitAllowed
     * @param 5 :  $ruleType
     * @param 6 :  $chargeType
     * @param 7 :  $amountType
     * @param 8 :  $amount
     * @param 9 :  $maxQty
     * @param 10 : $isShippingFree
     * @param 11 : $isTaxFree
     * @param 12 : $isActive
     *
     * @return type : Rule action
     *
     * @throws Exception: Null
     */
    public function editServiceRuleMappingActions($id, $type, $limitBy, $limitAllowed, $ruleType, $chargeType, $amountType, $amount, $maxQty, $isShippingFree, $isTaxFree, $isActive)
    {
        return $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMappingActions')->editServiceRuleMappingActions($id, $type, $limitBy, $limitAllowed, $ruleType, $chargeType, $amountType, $amount, $maxQty, $isShippingFree, $isTaxFree, $isActive);
    }

    /**
     * @author Employee Id: 4589
     * Description : List service rule mapping
     *
     * @param 1 : Language Id
     * @param 2 : isReward
     *
     * @return type : ServiceRuleMapping
     *
     * @throws Exception: Null
     */
    public function listServiceRuleMapping($languageId = null, $isReward = false)
    {
        return $this->entityManager->getRepository('OfficeBrainServiceGroupBundle:ServiceRuleMappingMaster')->listServiceRuleMapping($languageId, $isReward);
    }
}
