<?php
namespace OfficeBrain\Bundle\FeedBackBundle\Manager\Extended;

use OfficeBrain\Bundle\FeedBackBundle\Manager\AbstractManager\FeedBackAbstract;
use OfficeBrain\Bundle\FeedBackBundle\Entity as Entity;

/**
 * @author OfficeBrain 4464 <info@officebrain.com>
 *
 * Description : This is the extended class of FeedBackAbstract class.
 * 		This class is used to perform the admin's tasks.
 *
 **/
class FeedBackExtended extends FeedBackAbstract
{
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to set member variables default value
     *
     * @param 1: $entityManager
     * @param 2: $request
     * @param 3: $orderManager
     * @param 4: $emailManager
     * @param 5: $userManager
     * @param 6: $feedbackApiManager
     * @param 7: $solrManager
     * @param 8: $knpPaginator
     * @param 9: $serializer
     * @param 10: $translator
     *
     * @return: NULL
     *
     * @throws Exception: Null
     */
    public function __construct($entityManager, $request, $orderManager, $emailManager, $userManager, $feedbackApiManager, $solrManager, $knpPaginator, $serializer, $translator)
    {
        parent::__construct($entityManager, $request, $orderManager, $emailManager, $userManager, $feedbackApiManager, $solrManager, $knpPaginator, $serializer, $translator);
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to unset member variables
     *
     * @param : None
     *
     * @return NULL
     *
     * @throws Exception: Null
     */
    public function __destruct()
    {
        parent::__destruct();
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to list feedbacks given by the users from the database
     *
     * @param 1: $userId
     *
     * @return Feedback Master Object
     *
     * @throws Exception : Null
     *
     **/
    public function listFeedBack($userId = null, $page)
    {
        $error = array();
        
        $option = $this->request->get('option');
        $keyword = $this->request->get('keywords');
        
        $productId = $searchUserId = $createdDate = '';
        
        switch ($option) {
            case 'prod_sku':
                $productId = $this->getProductIdBySku($keyword);
                if (count($productId) == 0) {
                	$productId = array(0);
                }
                break;
                
            case 'prod_title':
                $productId = $this->getProductIdByTitle($keyword);
                if (count($productId) == 0) {
                	$productId = array(0);
                }
                break;
                
            case 'user_name':
                $searchUserId = $this->getUserIdByName($keyword);
                break;
                
            case 'productSlug':
                	$searchUserId = $this->getUserIdBySlug($keyword);
                	break;
            case 'feedback_date':
                $createdDate = $keyword;
                break;     
        }
        
        $feedBackList = $this->feedBackMasterRepository->getFeedBackList($userId, $productId, $searchUserId, $createdDate);
        
        foreach ($feedBackList as $key => $val) {
            $productId = $feedBackList[$key]->getProductId();
            $orderId = $feedBackList[$key]->getOrderId();
            
            if (empty($userId)) {
                $userDetails = $this->getUserDetails($feedBackList[$key]->getUserId());
                
                if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
                    //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
                    $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
                } else {
                    $userFirstName = $userDetails->getFirstName();
                    $userLastName = $userDetails->getLastName();
                    $feedBackList[$key]->user_name = trim($userFirstName.' '.$userLastName);
                }
                unset($userDetails);
                unset($userFirstName);
                unset($userLastName);
            }
            
            $productDetailArray = $this->getProductDetails($productId);
            $orderDetail = $this->getOrderDetailsById($orderId);
            if(is_array($orderDetail) && isset($orderDetail['order_not_found'])){
                $error['order_not_found'] = $orderDetail['order_not_found'];
            }
            
            /* if (isset($productDetailArray['product_not_found'])) {
                //throw new NotFoundHttpException($this->translator->trans('feedback.product_not_found'));
                $error['product_not_found'] = $this->translator->trans('feedback.product_not_found');
            } else {
                foreach ($productDetailArray as $productKey => $productValue) {
                    $feedBackList[$key]->product_sku = $productValue['basic_information']['sku_number'];
                    $feedBackList[$key]->product_title = $productValue['basic_information']['title'];
                    $feedBackList[$key]->product_image = $productValue['basic_information']['default_image_url'];
                    $feedBackList[$key]->product_price = (isset($productValue['unit_price'])) ? $productValue['unit_price'] : 0;
                    $feedBackList[$key]->product_currency = $productValue['currency']['symbol'];
                }
            } */
            
            if(!is_array($orderDetail) && !empty($orderDetail)){  
            	
            	$orderItemLine = $orderDetail->getOrderItemLine();
            	foreach ($orderItemLine as $productData){
                    if($productData->getProductId() == $productId){
		        		$feedBackList[$key]->product_sku = $productData->getProductSku();
		        		$feedBackList[$key]->product_title = $productDetailArray['basic_information']['title'];
		        		$feedBackList[$key]->product_slug = $productData->getProductSlug();
		        		$feedBackList[$key]->product_image = $productData->getProductThumbImage();
		        		$feedBackList[$key]->product_price = $productData->getUnitPrice();
		        		$feedBackList[$key]->product_currency = $productData->getCurrencySymbol();
			        	$feedBackList[$key]->order_date = $orderDetail->getCreatedAt()->format('Y-m-d');
					}
            	}
            }
        }
        
        if (!empty($error)) {
            return $error;
        }
        
        unset($error);
        unset($productId);
        unset($userId);
        unset($productDetailArray);
        
        return $this->knpPaginator->paginate($feedBackList, $page, $this->recordsPerPage, array(), count($feedBackList));
        //return $feedBackList;
        
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to view the feedback
     *
     * @param 1: $feedBackId
     *
     * @return Null
     *
     * @throws Exception : Returns error
     *
     **/
    public function viewFeedBack($feedBackId)
    {
        $error = array();
        
        $feedBackData = $this->feedBackMasterRepository->find($feedBackId);
        
        $productId = $feedBackData->getProductId();
        $orderId = $feedBackData->getOrderId();
        
        $userDetails = $this->getUserDetails($feedBackData->getUserId());
        
        if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
            $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
        } else {
            $userFirstName = $userDetails->getFirstName();
            $userLastName = $userDetails->getLastName();
        }
        
        $feedBackData->user_name = trim($userFirstName.' '.$userLastName);
        
        $productDetailArray = $this->getProductDetails($productId);
        $orderDetail = $this->getOrderDetailsById($orderId);
        
        if(is_array($orderDetail) && isset($orderDetail['order_not_found'])){
            $error['order_not_found'] = $orderDetail['order_not_found'];
        }
        
        /* if (isset($productDetailArray['product_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.product_not_found'));
            $error['product_not_found'] = $this->translator->trans('feedback.product_not_found');
        } else {
            foreach ($productDetailArray as $productKey => $productValue) {
                $feedBackData->product_sku = $productValue['basic_information']['sku_number'];
                $feedBackData->product_title = $productValue['basic_information']['title'];
                $feedBackData->product_image = $productValue['basic_information']['default_image_url'];
                $feedBackData->product_price = (isset($productValue['unit_price'])) ? $productValue['unit_price'] : 0;
                $feedBackData->product_currency = $productValue['currency']['symbol'];
            }
        }
        
        $feedBackData->order_date = '10/5/2015'; */
        if(!is_array($orderDetail) && !empty($orderDetail)){
             
            $orderItemLine = $orderDetail->getOrderItemLine();
            if(!empty($orderItemLine)){
                foreach ($orderItemLine as $productData){
                    if($productData->getProductId() == $productId){
                        $feedBackData->product_sku = $productData->getProductSku();
                        $feedBackData->product_title = $productDetailArray['basic_information']['title'];
                        $feedBackData->product_image = $productData->getProductThumbImage();
                        $feedBackData->product_price = $productData->getUnitPrice();
                        $feedBackData->product_currency = $productData->getCurrencySymbol();
                    }
                }
            }
            
            $feedBackList->order_date = $orderDetail->getCreatedAt()->format('Y-m-d');
        }
        
        unset($userDetails);
        unset($userFirstName);
        unset($userLastName);
        unset($feedBackId);
        
        if (!empty($error)) {
            return $error;
        }
    
        return $feedBackData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to insert feedback given by the user into the database
     *
     * @param 1: $formData
     * @param 2: $orderId
     * @param 3: $productId
     *
     * @return Null
     *
     * @throws Exception : Returns error
     *
     **/
    public function setFeedBack($formData, $orderId, $productId)
    {
        $error = array();
    
        if (is_array($this->isFeedbackModerationOn) && isset($this->isFeedbackModerationOn['no_configuration'])) {
            $error['no_configuration'] = $this->isFeedbackModerationOn['no_configuration'];
        }
    
        $userDetails = $this->getUserDetails($this->projectSetting['user_id']);
    
        if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
            $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
        }
    
        if (!empty($error)) {
            return $error;
        }
    
        $userDetailsArray = $this->serializeObject($userDetails);
        $feedbackMaster = $this->feedBackMasterRepository->setFeedBack($formData, $orderId, $productId, $this->isFeedbackModerationOn);
    
        if ($this->isFeedbackModerationOn == 0) {
            $feedBackData = $this->serializeObject($feedbackMaster);
            $this->setFeedBackToProductMaster($this->projectSetting['project_id'], $this->projectSetting['instance_id'], $productId, $userDetailsArray, $feedBackData);
            unset($feedBackData);
        }
        
        unset($error);
        unset($userDetails);
        unset($userDetailsArray);
        unset($feedbackMaster);
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to approve the feedback given by the user
     *
     * @param 1: $feedBackId
     *
     * @return Null
     *
     * @throws Exception : Returns error
     *
     **/
    public function approveFeedBack($feedBackId)
    {
        $params = array();
        $feedBackData = $this->feedBackMasterRepository->find($feedBackId);
        $sendMail = $feedBackData->getSendApprovalMail();
        
        $eventKey = 'feedback_approval_mail';
        
        $userDetails = $this->getUserDetails($feedBackData->getUserId());
        
        if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
            $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
        }
        
        $productDetailArray = $this->getProductDetails($feedBackData->getProductId());
        
        if (isset($productDetailArray['product_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.product_not_found'));
            $error['product_not_found'] = $this->translator->trans('feedback.product_not_found');
        }
        
        if (!empty($error)) {
            return $error;
        }
         
        $params['firstname'] = $userDetails->getFirstName();
        $params['lastname'] = $userDetails->getLastName();
        $params['instancename'] = $this->projectSetting['instance_type'];
        $params['ratings'] = $feedBackData->getRatings();
        $params['usercomment'] = $feedBackData->getComment();
        //$params['ratingdate'] = $feedBackData->getCreatedAt();
        $params['ratingdate'] = $feedBackData->getCreatedAt()->format('d M, Y');

        //foreach ($productDetailArray as $productKey => $productValue) {
            $params['producttitle'] = $productDetailArray['basic_information']['title'];
            $params['productimage'] = "<img src='".$productDetailArray['basic_information']['default_image_url']."' alt='Product Image' align='middle' />";
        //}
        
        $this->feedBackMasterRepository->approveFeedBack($feedBackId);
        if ($sendMail == 0 || $sendMail == null) {
            $this->sendMail($eventKey, $userDetails->getEmail(), $params, $feedBackData->getLanguageId());
        }
        
        //Converting symfony entity object into json
        $userDetailsArray = $this->serializeObject($userDetails);
        $feedBackDataArray = $this->serializeObject($feedBackData);
        $this->setFeedBackToProductMaster($this->projectSetting['project_id'], $this->projectSetting['instance_id'], $feedBackData->getProductId(), $userDetailsArray, $feedBackDataArray);
        
        unset($feedBackId);
        unset($params);
        unset($sendMail);
        unset($userDetails);
        unset($productDetailArray);
        unset($params);
        unset($userDetailsArray);
        unset($feedBackDataArray);

        return $feedBackData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to reject the feedback given by the user
     *
     * @param 1: $feedBackId
     *
     * @return Null
     *
     * @throws Exception : Returns error
     *
     **/
    public function rejectFeedBack($feedBackId)
    {
        $feedBackData = $this->feedBackMasterRepository->find($feedBackId);
        $deleteFromApi = false;
        
        if ($feedBackData->getIsApproved() == 1) {
            $deleteFromApi = true;
        }
        
        $userDetails = $this->getUserDetails($feedBackData->getUserId());
        
        if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
            $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
            return $error;
        }
        
        $this->feedBackMasterRepository->rejectFeedBack($feedBackId);
        
        //Converting symfony entity object into json
        $userDetailsArray = $this->serializeObject($userDetails);
        $feedBackDataArray = $this->serializeObject($feedBackData);
        
        if ($deleteFromApi === true) {
            $this->deleteFeedBackFromProductMaster($this->projectSetting['project_id'], $this->projectSetting['instance_id'], $feedBackData->getProductId(), $userDetailsArray, $feedBackDataArray);//This will do hard delete
        }
        
        
        unset($feedBackId);
        unset($deleteFromApi);
        unset($userDetails);
        unset($userDetailsArray);
        unset($feedBackDataArray);
        
        return $feedBackData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to (soft)delete the feedback given by the user
     *
     * @param 1: $feedBackId
     *
     * @return Null
     *
     * @throws Exception : Returns error
     *
     **/
    public function deleteFeedBack($feedBackId)
    {
        $feedBackData = $this->feedBackMasterRepository->find($feedBackId);
        
        $deleteFromApi = false;
        
        if ($feedBackData->getIsApproved() == 1) {
            $deleteFromApi = true;
        }
        
        $userDetails = $this->getUserDetails($feedBackData->getUserId());
        
        if (is_array($userDetails) && isset($userDetails['user_not_found'])) {
            //throw new NotFoundHttpException($this->translator->trans('feedback.user_not_found'));
            $error['user_not_found'] = $this->translator->trans('feedback.user_not_found');
            return $error;
        }
         
        $this->feedBackMasterRepository->deleteFeedBack($feedBackId); //This will do softdelete
        
        //Converting symfony entity object into json
        $userDetailsArray = $this->serializeObject($userDetails);
        $feedBackDataArray = $this->serializeObject($feedBackData);
        
        if ($deleteFromApi === true) {
            $this->deleteFeedBackFromProductMaster($this->projectSetting['project_id'], $this->projectSetting['instance_id'], $feedBackData->getProductId(), $userDetailsArray, $feedBackDataArray);//This will do hard delete
        }
        
        unset($feedBackId);
        unset($deleteFromApi);
        unset($userDetails);
        unset($userDetailsArray);
        unset($feedBackDataArray);
        
        return $feedBackData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to insert feedback given by the user into the product master database
     *
     * @param 1: $projectId
     * @param 2: $instanceId
     * @param 3: $productId
     * @param 4: $userDetails
     * @param 5: $feedBackData
     *
     * @return array
     *
     * @throws Exception : Null
     *
     **/
    public function setFeedBackToProductMaster($projectId, $instanceId, $productId, $userDetails, $feedBackData)
    {
        $params = array(
            'project_id' => $projectId,
            'instance_id' => $instanceId,
            'product_id' => $productId,
            'user_data' => $userDetails,
            'feedback_data' => $feedBackData,
            'language' => $this->locale
        );
        
        $this->feedbackApi->init('set_feed_back');
        $this->feedbackApi->setCallParameters($params);
        $this->feedbackApi->doProcess();
        
        $returnData = null;
        
        if ($this->feedbackApi->isSuccess()) {
            $returnData = $this->feedbackApi->getResultArray();
            $productDetails = $this->getProductDetails($productId);
            
            if (isset($productDetails['product_not_found'])) {
                //throw new NotFoundHttpException($this->translator->trans('feedback.product_not_found'));
                $error['product_not_found'] = $this->translator->trans('feedback.product_not_found');
                return $error;
            } else {
                //foreach ($productDetails as $key => $value) {
                    $this->updateRatingsToSolr($productDetails['product_id'], $productDetails['rating']);
                //}
            }
            
            unset($productDetails);
        }
        
        unset($projectId);
        unset($instanceId);
        unset($productId);
        unset($userDetails);
        unset($feedBackData);
        unset($params);
        return $returnData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to get feedback list given by the user for a product from the product master database
     *
     * @param 1: $projectId
     * @param 2: $instanceId
     * @param 3: $productId
     * @param 4: $page
     * @param 5: $recordsPerPage
     *
     * @return array
     *
     * @throws Exception : Null
     *
     **/
    public function getFeedBackListFromProductMaster($productId, $page, $recordsPerPage)
    {
        $params = array(
            'project_id' => $this->projectId,
            'instance_id' => $this->instanceId,
            'product_id' => $productId,
            'language' => $this->locale,
            'page' => $page,
            'records_per_page' => $recordsPerPage
        );
        
        $this->feedbackApi->init('get_feed_back');
        $this->feedbackApi->setCallParameters($params);
        $this->feedbackApi->doProcess();
        
        $returnData = null;
        
        if ($this->feedbackApi->isSuccess()) {
            $returnData = $this->feedbackApi->getResultArray();
        }
        
        unset($projectId);
        unset($instanceId);
        unset($productId);
        unset($page);
        unset($recordsPerPage);
        unset($params);
        
        return $returnData;
    }
    
    /**
     * @author Employee Id: 4861
     *
     * Description : This function is used to ceil array
     *
     * @param 1: $data
     *
     * @return array
     *
     * @throws Exception : Null
     *
     **/
    public function ceilArray($data)
    {
        $finalArray = array();
        foreach ($data['review_count'] as $rating) {
            $ceil_rate = ceil($rating['star']);
            $ceil_rate = (int)$ceil_rate;
            if (array_key_exists($ceil_rate, $finalArray)) {
                $finalArray[$ceil_rate]['rating_count'] = $finalArray[$ceil_rate]['rating_count'] + $rating['rating_count'];
            } else {
                $finalArray[$ceil_rate]['rating_count'] = $rating['rating_count'];
            }
            $finalArray[$ceil_rate]['star'] = $ceil_rate;
        }
        return $finalArray;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to get Rate wise count of reviews.
     *
     * @param 1: $projectId
     * @param 2: $instanceId
     * @param 3: $productId
     *
     * @return array
     *
     * @throws Exception : Null
     *
     **/
    public function getRateWiseCountFromProductMaster($productId)
    {
        $apiParameterArray = array('project_id' => $this->projectId,
                                   'instance_id' => $this->instanceId,
                                   'product_id' => $productId,
                                   'language' => $this->locale
                            );
        $this->feedbackApi->init('get_rate_wise_count');
        $this->feedbackApi->setCallParameters($apiParameterArray);
        $this->feedbackApi->doProcess();

        unset($productId);
        unset($apiParameterArray);
        
        if ($this->feedbackApi->isSuccess()) {
            return $this->feedbackApi->getResultArray();
        }

        return null;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to delete (permanantly) feedback given by the user from the product master database
     *
     * @param 1: $projectId
     * @param 2: $instanceId
     * @param 3: $productId
     * @param 4: $userDetails
     * @param 5: $feedBackData
     *
     * @return array
     *
     * @throws Exception : Null
     *
     **/
    public function deleteFeedBackFromProductMaster($projectId, $instanceId, $productId, $userDetails, $feedBackData)
    {
        $params = array(
            'project_id' => $projectId,
            'instance_id' => $instanceId,
            'product_id' => $productId,
            'user_data' => $userDetails,
            'feedback_data' => $feedBackData,
            'language' => $this->locale
        );
        
        $this->feedbackApi->init('delete_feed_back');
        $this->feedbackApi->setCallParameters($params);
        $this->feedbackApi->doProcess();
        
        $returnData = null;
        
        if ($this->feedbackApi->isSuccess()) {
            $returnData = $this->feedbackApi->getResultArray();
            
            $productDetails = $this->getProductDetails($productId);
            
            if (isset($productDetails['product_not_found'])) {
                $error['product_not_found'] = $this->translator->trans('feedback.product_not_found');
                return $error;
            } else {
                //foreach ($productDetails as $key => $value) {
                    $this->updateRatingsToSolr($productDetails['product_id'], $productDetails['rating']);
                //}
            }
            
            unset($productDetails);
        }
        
        unset($projectId);
        unset($instanceId);
        unset($productId);
        unset($userDetails);
        unset($feedBackData);
        unset($params);
        
        return $returnData;
    }
    
    /**
     * @author Employee Id: 4464
     *
     * Description : This function is used to check if the feedback for this product in an order is given or not
     *
     * @param 1: $orderId
     * @param 2: $productId
     * @param 3: $userId
     *
     * @return boolean
     *
     * @throws Exception : Null
     *
     **/
    public function isFeedBackGiven($orderId, $productId = null, $userId = null)
    {
        $isFeedbackGiven = $this->feedBackMasterRepository->isFeedBackGiven($orderId, $productId, $userId);
        
        if (!empty($isFeedbackGiven)) {
            return true;
        } else {
            return false;
        }
    }
}