<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Shop\Controller;

use Admin\Data\Common;
use Doctrine\ORM\EntityManager;
use Laminas\Mvc\I18n\Translator;
use Sales\Entity\Order;
use Sales\Entity\OrderGoods;
use Sales\Entity\OrderGoodsReturn;
use Sales\Service\OrderGoodsReturnManager;
use Shop\Form\GoodsChangeForm;
use Shop\Form\GoodsReturnForm;

class HomeServiceController extends HomeActionController
{
    private $translator;
    private $entityManager;
    private $orderGoodsReturnManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        OrderGoodsReturnManager $orderGoodsReturnManager
    )
    {
        $this->translator   = $translator;
        $this->entityManager= $entityManager;
        $this->orderGoodsReturnManager = $orderGoodsReturnManager;
    }

    /**
     * 申请售后
     * @return array|\Laminas\Http\Response|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('售后服务'));

        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($orderGoodsInfo === null || $orderGoodsInfo->getGoodsType() == 2) return $this->redirect()->toRoute('shop-home');

        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);
        if (!$this->checkOrderGoodsMayReturn($orderInfo)) return $this->redirect()->toRoute('shop-home');

        $returnInfo = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);

        return ['orderInfo' => $orderInfo, 'orderGoods' => $orderGoodsInfo, 'returnInfo' => $returnInfo];
    }

    /**
     * 退款不退货
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function returnMoneyAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('退款(无需退货)'));

        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($orderGoodsInfo === null || $orderGoodsInfo->getGoodsType() == 2) return $this->redirect()->toRoute('shop-home');

        $returnGoods = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($returnGoods) return $this->redirect()->toRoute('shop-home');

        $orderInfo      = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);
        if (!$this->checkOrderGoodsMayReturn($orderInfo)) return $this->redirect()->toRoute('shop-home');

        $returnAmount   = $this->returnGoodsAmount($orderGoodsInfo, $orderInfo);

        $form = new GoodsReturnForm($returnAmount);
        $form->get('returnReason')->setValueOptions($this->shopPlugin()->getReturnGoodsReason());
        $form->get('refundPayType')->setValueOptions(Common::goodsReturnPayType($this->translator));

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data['orderId'] = $orderInfo->getOrderId();
                $data['orderSn'] = $orderInfo->getOrderSn();
                $data['userId']     = parent::$userId;
                $data['userName']   = parent::$userName;
                $data['orderGoodsId'] = $orderGoodsId;
                $data['returnType'] = 2;
                $data['addTime']    = time();
                $goodsReturnInfo = $this->orderGoodsReturnManager->addGoodsReturn($data);

                return $this->redirect()->toRoute('shop-service', ['action' => 'successPage', 'id' => $goodsReturnInfo->getReturnId()]);
            }
        }

        return ['orderInfo' => $orderInfo, 'orderGoods' => $orderGoodsInfo, 'form' => $form, 'returnMaxAmount' => $returnAmount];
    }

    /**
     * 退款退货
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function returnGoodsAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('退货退款'));

        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($orderGoodsInfo === null || $orderGoodsInfo->getGoodsType() == 2) return $this->redirect()->toRoute('shop-home');

        $returnGoods = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($returnGoods) return $this->redirect()->toRoute('shop-home');

        $orderInfo      = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);
        if (!$this->checkOrderGoodsMayReturn($orderInfo)) return $this->redirect()->toRoute('shop-home');

        $returnAmount   = $this->returnGoodsAmount($orderGoodsInfo, $orderInfo);

        $form = new GoodsReturnForm($returnAmount);
        $form->get('returnReason')->setValueOptions($this->shopPlugin()->getReturnGoodsReason($this->translator->translate('退货原因')));
        $form->get('refundPayType')->setValueOptions(Common::goodsReturnPayType($this->translator));
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data['orderId'] = $orderInfo->getOrderId();
                $data['orderSn'] = $orderInfo->getOrderSn();
                $data['userId']     = parent::$userId;
                $data['userName']   = parent::$userName;
                $data['orderGoodsId'] = $orderGoodsId;
                $data['returnType'] = 1;
                $data['addTime']    = time();
                $goodsReturnInfo = $this->orderGoodsReturnManager->addGoodsReturn($data);

                return $this->redirect()->toRoute('shop-service', ['action' => 'successPage', 'id' => $goodsReturnInfo->getReturnId()]);
            }
        }

        return ['orderInfo' => $orderInfo, 'orderGoods' => $orderGoodsInfo, 'form' => $form, 'returnMaxAmount' => $returnAmount];
    }

    /**
     * 换货
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function changeGoodsAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('商品换货'));

        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($orderGoodsInfo === null || $orderGoodsInfo->getGoodsType() == 2) return $this->redirect()->toRoute('shop-home');

        $returnGoods = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($returnGoods) return $this->redirect()->toRoute('shop-home');

        $orderInfo      = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);
        if (!$this->checkOrderGoodsMayReturn($orderInfo)) return $this->redirect()->toRoute('shop-home');

        $form = new GoodsChangeForm();
        $form->get('returnReason')->setValueOptions($this->shopPlugin()->getReturnGoodsReason($this->translator->translate('换货原因')));
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data['orderId'] = $orderInfo->getOrderId();
                $data['orderSn'] = $orderInfo->getOrderSn();
                $data['userId']     = parent::$userId;
                $data['userName']   = parent::$userName;
                $data['orderGoodsId'] = $orderGoodsId;
                $data['returnType'] = 3;
                $data['addTime']    = time();
                $goodsReturnInfo = $this->orderGoodsReturnManager->addGoodsReturn($data);

                return $this->redirect()->toRoute('shop-service', ['action' => 'successPage', 'id' => $goodsReturnInfo->getReturnId()]);
            }
        }

        return ['orderInfo' => $orderInfo, 'orderGoods' => $orderGoodsInfo, 'form' => $form];
    }

    /**
     * 售后申请完成
     * @return array|\Laminas\Http\Response
     */
    public function successPageAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('售后申请提交完成'));

        $returnId = (int) $this->params()->fromRoute('id', 0);
        $returnInfo = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['returnId' => $returnId, 'userId' => parent::$userId]);
        if ($returnInfo == null) return $this->redirect()->toRoute('shop-home');

        return ['returnInfo' => $returnInfo];
    }


    /**
     * 退换货列表
     * @return array
     */
    public function returnAndChangeListAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('退换货/售后'));

        $page       = (int) $this->params()->fromQuery('page', 1);
        $query      = $this->entityManager->getRepository(OrderGoodsReturn::class)->shopFindOrderReturnList(parent::$userId);
        $paginator  = $this->shopPlugin()->shopPaginator($query, $page);

        return ['returnGoodsList' => $paginator];
    }

    /**
     * 查看退换货详情
     * @return array|\Laminas\Http\Response
     */
    public function viewReturnAndChangeAction()
    {
        $this->layout()->setVariable('titleName', $this->translator->translate('退换货/售后详情'));

        $orderGoodsId = (int) $this->params()->fromRoute('id', 0);
        $orderGoodsInfo = $this->entityManager->getRepository(OrderGoods::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);
        if ($orderGoodsInfo === null || $orderGoodsInfo->getGoodsType() == 2) return $this->redirect()->toRoute('shop-home');

        $orderInfo = $this->entityManager->getRepository(Order::class)->findOneBy(['orderId' => $orderGoodsInfo->getOrderId()]);

        $returnInfo = $this->entityManager->getRepository(OrderGoodsReturn::class)->findOneBy(['orderGoodsId' => $orderGoodsId, 'userId' => parent::$userId]);

        return ['orderInfo' => $orderInfo, 'orderGoods' => $orderGoodsInfo, 'returnInfo' => $returnInfo];
    }

    /**
     * 获取可退款的金额
     * @param OrderGoods $orderGoods
     * @param Order $orderInfo
     * @return int|mixed
     */
    private function returnGoodsAmount(OrderGoods $orderGoods, Order $orderInfo)
    {
        $orderGoodsList = $this->entityManager->getRepository(OrderGoods::class)->orderGoodsAndReturn($orderInfo->getOrderId());
        $amount = $orderInfo->getOrderAmount() - $orderInfo->getShippingFee();

        $subAmount = 0;
        foreach ($orderGoodsList as $value) {
            if ($value[0]->getOrderGoodsId() == $orderGoods->getOrderGoodsId()) continue;
            if ($value['returnState'] == 3) $subAmount = $subAmount + $value[0]->getGoodsAmount();
            else {
                if ($value['returnType'] == 3) $subAmount = $subAmount + $value[0]->getGoodsAmount();
                else $subAmount = $subAmount + $value['returnAmount'];
            }
        }

        if ($subAmount > 0) $amount = $amount - $subAmount;

        if ($orderGoods->getGoodsAmount() > $amount) return $amount;

        return $orderGoods->getGoodsAmount();
    }

    /**
     * 检查订单是否可以退款
     * @param Order $orderInfo
     * @return bool
     */
    private function checkOrderGoodsMayReturn(Order $orderInfo)
    {
        if (
            $orderInfo === null || $orderInfo->getOrderStatus() < $this->shopPlugin()->getOrderStatusCode('GOODS_RECEIVED')
            || Common::configValue('order', 'config')['order_return'] != 1
            || (Common::configValue('order', 'config')['order_return'] == 1 && time() > $orderInfo->getOrderFinishTime() + Common::configValue('order', 'config')['order_return_limit'] * 86400)
        ) return false;

        return true;
    }
}