<?php

namespace OfficeBrain\Bundle\RewardReferralBundle\Manager\Extended;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use OfficeBrain\Bundle\RewardReferralBundle\Manager\AbstractManager\RewardReferralAbstract;
use OfficeBrain\Bundle\RewardReferralBundle\Entity\ReferralMaster;
use OfficeBrain\Bundle\RewardReferralBundle\Entity\RewardEarnHistory;
use OfficeBrain\Bundle\RewardReferralBundle\Form\ReferralMasterType;

/**
 * @author OfficeBrain 4589 <info@officebrain.com>
 *
 * Description : Reward & Referral extended class.
 **/
class RewardReferralExtended extends RewardReferralAbstract
{
    protected $referralMasterRepo;
    protected $encodeSep = "-";
    
    public function __construct($entityManager, $request, $session, $paginatorService, $translatorService, $emailService, $countries, $languages)
    {
        parent::__construct($entityManager, $request, $session, $paginatorService, $translatorService, $emailService, $countries, $languages);
        $this->referralMasterRepo = $this->entityManager->getRepository("OfficeBrainRewardReferralBundle:ReferralMaster");
        $this->referralMasterRepo->setProjectSetting($this->projectSetting);
        $this->referralMasterRepo->setPaginatorService($this->paginatorService);
    }
    
    /**
     * @author Employee Id: 4589
     * Description : save recipient email with sender.
     *
     * @param 1 : Form $form form object
     *
     * @return : boolean or form object
     *
     * @throws Exception: Null
     */
    public function setReferAFriend($form)
    {
        $form->handleRequest($this->request);
        $isError = false;
        if ($form->isValid()) {
            $configuration = $this->getConfiguration($this->cultureId);
            $referralMaster = $form->getData();
            $referralMasterOld = $this->referralMasterRepo->findBySenderId($this->userId);
            $totalCount = $referralMaster->getReferralRecipient()->count();
            
            if ($referralMasterOld) {
                $totalCount += $referralMasterOld->getReferralRecipient()->count();
            }
            
            if ($totalCount > $configuration->getMaxReferralLimit()) {
                $form->get('referralRecipient')[0]->get('email')
                            ->addError(new \Symfony\Component\Form\FormError($this->translatorService
                                    ->trans('referral.form.error.email_limit_reached_%total_count%_%used_count%', array("%total_count%"=>$configuration->getMaxReferralLimit(), "%used_count%"=>$referralMasterOld->getReferralRecipient()->count()))));
                $isError = true;
            }
            
            foreach ($referralMaster->getReferralRecipient() as $index=>$referralRecipient) {
                if (!$this->referralMasterRepo->isEmailRequestExists($this->userId, $referralRecipient->getEmail())) {
                    $referralRecipient->setReferralCode($this->generateReferralCode($referralRecipient));
                    $referralRecipient->setPoint($configuration->getRegistrationPointReferrer());
                    $referralRecipient->setIsRegistered(0);
                    
                    if ($referralMasterOld) {
                        $referralRecipient->setReferralMasterId($referralMasterOld);
                        $referralMasterOld->addReferralRecipient($referralRecipient);
                    } else {
                        $referralRecipient->setReferralMasterId($referralMaster);
                    }
                } else {
                    $form->get('referralRecipient')[$index]->get('email')
                            ->addError(new \Symfony\Component\Form\FormError($this->translatorService->trans('referral.form.error.duplicate_email_request')));
                    $isError = true;
                }
            }
            
            if (!$isError) {
                if ($referralMasterOld) {
                    $this->referralMasterRepo->setReferralMaster($referralMasterOld);
                } else {
                    $this->referralMasterRepo->setReferralMaster($referralMaster);
                }
                $this->referralMasterRepo->commit();
                
                //send email to recipients
                $emailParams = array(
                    'sender_name'=>'',
                    'sender_email'=>'',
                );
                foreach ($referralMaster->getReferralRecipient() as $index=>$referralRecipient) {
                    $emailParams['email'] = $referralRecipient->getEmail();
                    $emailParams['referral_code'] = $referralRecipient->getReferralCode();
                    $this->emailService->sendMail("refer_friend", $referralRecipient->getEmail(), $emailParams);
                }
                return true;
            }
        }
        
        return $form;
    }
    
    /**
     * @author Employee Id: 4589
     * Description : check request already sent or not.
     *
     * @param 1 : string $email recipient email.
     *
     * @return : array with status error or success.
     *
     * @throws Exception: Null
     */
    public function isRequestSent($email)
    {
        return $this->referralMasterRepo->isEmailRequestExists($this->userId, $email);
    }
    
    /**
     * @author Employee Id: 4589
     * Description : create form for add or edit
     *
     * @param 1 : Controller $controller container object
     *
     * @return : object form object
     *
     * @throws Exception: Null
     *
     **/
    public function createForm(Controller $controller)
    {
        $referralMaster = new ReferralMaster();
        
        $form = $controller->createForm(new ReferralMasterType(), $referralMaster);
        
        return $form;
    }
    
    /**
     * @author Employee Id: 4589
     * Description : save points after registration
     *
     * @param 1 : int $registerUserId current registered user id
     * @param 2 : string $referralCode encoded referral code
     *
     * @return : bool point updated or not
     *
     * @throws Exception: Null
     *
     **/
    public function updateReferralPointByRegistration($registerUserId, $referralCode)
    {
        $decodeArray = $this->decodeReferralCode($referralCode);
        
        if ($decodeArray) {
            $senderId = $decodeArray['senderId'];
            $email = $decodeArray['email'];

            $referralMaster = $this->referralMasterRepo->findBySenderIdAndRecipientEmail($senderId, $email);

            if ($referralMaster) {
                $referralRequestArray = $referralMaster->getReferralRecipient();

                if ($referralRequestArray->count() > 0) {
                    $configuration = $this->getConfiguration();
                    $expiry_days = (int)$configuration->getExpiryInDays();
                    $registrationPointReferent = (int)$configuration->getRegistrationPointReferent();
                    
                    //for registered user
                    $rewardEarnHistory = new RewardEarnHistory();
                    $rewardEarnHistory->setUserId($registerUserId);
                    $rewardEarnHistory->setEarnedPoint($referralRequestArray[0]->getPoint());
                    $rewardEarnHistory->setBalancePoint($referralRequestArray[0]->getPoint());
                    $rewardEarnHistory->setActivityType('registration');
                    $rewardEarnHistory->setReferralUserId($senderId);
                    
                    //for sender user
                    $rewardEarnHistory1 = new RewardEarnHistory();
                    $rewardEarnHistory1->setUserId($senderId);
                    $rewardEarnHistory1->setEarnedPoint($registrationPointReferent);
                    $rewardEarnHistory1->setBalancePoint($registrationPointReferent);
                    $rewardEarnHistory1->setActivityType('registration');
                    $rewardEarnHistory1->setReferralUserId($senderId);

                    if ($expiry_days > 0) {
                        $endDate = new \DateTime();
                        $endDate->add(new \DateInterval('P'.$expiry_days.'D'));
                        $rewardEarnHistory->setEndDate($endDate);
                        $rewardEarnHistory1->setEndDate($endDate);
                    }

                    $rewardEarnHistoryRepo = $this->entityManager->getRepository("OfficeBrainRewardReferralBundle:RewardEarnHistory");
                    $referralPointRepo = $this->entityManager->getRepository("OfficeBrainRewardReferralBundle:ReferralPoint");
                    
                    $rewardEarnHistoryRepo->setProjectSetting($this->projectSetting);
                    $referralPointRepo->setProjectSetting($this->projectSetting, $configuration);
                    
                    $rewardEarnHistoryRepo->setRewardEarnHistory($rewardEarnHistory);
                    $rewardEarnHistoryRepo->setRewardEarnHistory($rewardEarnHistory1);
                    
                    //update total reward point
                    $referralPointRepo->updatePointByUserId($registerUserId, $referralRequestArray[0]->getPoint(), "add");
                    $referralPointRepo->updatePointByUserId($senderId, $registrationPointReferent, "add");
                    
                    //set is registered true
                    $referralRequestArray[0]->setIsRegistered(1);
                    
                    $rewardEarnHistoryRepo->commit();
                    
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * @author Employee Id: 4589
     * Description : save points after purchase order
     *
     * @param 1 : string $email logged in user email
     * @param 2 : int $orderCount order number
     * @param 2 : float $orderTotal Order Total
     *
     * @return : bool point updated or not
     *
     * @throws Exception: Null
     *
     **/
    public function updateReferralPointByPurchaseOrder($email, $orderCount, $orderTotal)
    {
        $referralMaster = $this->referralMasterRepo->findByEmail($email);
        if ($referralMaster) {
            $senderId = $referralMaster->getSenderId();
            
            $configuration = $this->getConfiguration();
            $purchasePointReferrer = $configuration->getPurchasePointReferrer();
            
            $conversationRate = (int) $configuration->getConversionRate();
            if (isset($purchasePointReferrer[$orderCount-1])) {
                $pointPer = $purchasePointReferrer[$orderCount-1]->getPurchasePointReferrer();
                if ($pointPer > 0) {
                    $point = ($orderTotal*$pointPer)/100;
                }
                if ($conversationRate > 0) {
                    $point = $point * $conversationRate;
                }
                if ($point > 0) {
                    $expiry_days = (int)$configuration->getExpiryInDays();

                    $rewardEarnHistory = new RewardEarnHistory();
                    $rewardEarnHistory->setUserId($senderId);
                    $rewardEarnHistory->setEarnedPoint($point);
                    $rewardEarnHistory->setBalancePoint($point);
                    $rewardEarnHistory->setActivityType('purchase_order');
                    $rewardEarnHistory->setReferralUserId($senderId);

                    if ($expiry_days > 0) {
                        $endDate = new \DateTime();
                        $endDate->add(new \DateInterval('P'.$expiry_days.'D'));
                        $rewardEarnHistory->setEndDate($endDate);
                    }

                    $rewardEarnHistoryRepo = $this->entityManager->getRepository("OfficeBrainRewardReferralBundle:RewardEarnHistory");
                    $referralPointRepo = $this->entityManager->getRepository("OfficeBrainRewardReferralBundle:ReferralPoint");

                    $rewardEarnHistoryRepo->setProjectSetting($this->projectSetting);
                    $referralPointRepo->setProjectSetting($this->projectSetting, $configuration);

                    $rewardEarnHistoryRepo->setRewardEarnHistory($rewardEarnHistory);

                    //update total reward point
                    $referralPointRepo->updatePointByUserId($senderId, $point, "add");

                    $rewardEarnHistoryRepo->commit();
                    return true;
                }
            }
        }
        
        return false;
    }
    
    public function getTotalPointEarnByProduct($data)
    {
        $productId = $data['product_id'];
        $cultureProductId = $data['culture_product_id'];
        $category = $data['category'];
        $brand = $data['brand'];
        $productWeight = ($data['shipping_information'] && $data['shipping_information']['product'])?$data['shipping_information']['product']['weight']:null;
        $qtyPrice = $data['regular_variations_charges'];
        
        $serviceRuleMappingMasterRepository = $this->entityManager->getRepository("OfficeBrainServiceGroupBundle:ServiceRuleMappingMaster");
        $allRules = $serviceRuleMappingMasterRepository->findAll(true);
        //$allAction = $allRules[0]->getRuleMapMasterId();
                //->getRuleMapActions();
        //print_r($allAction);
        //exit;
        
        return 100;
    }
}
