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

namespace Operation\Controller;

use Admin\Controller\AdminActionController;
use Admin\Data\Common;
use Carbon\Carbon;
use Doctrine\ORM\EntityManager;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\ViewModel;
use Operation\Entity\Ad;
use Operation\Entity\AdSlide;
use Operation\Form\AdForm;
use Operation\Form\AdSlideForm;
use Operation\Service\AdManager;
use Operation\Service\AdSlideManager;

class AdController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $adManager;
    private $adSlideManager;

    public function __construct(
        Translator  $translator,
        EntityManager $entityManager,
        AdManager   $adManager,
        AdSlideManager $adSlideManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->adManager        = $adManager;
        $this->adSlideManager   = $adSlideManager;
    }

    /**
     * 电脑端广告列表
     * @return array|ViewModel
     */
    public function indexAction()
    {
        $adPlaceList = Common::getDefaultTemplateTag('ad', 'pcTemplate');
        $adList = [];
        if($adPlaceList) foreach ($adPlaceList['adClassName'] as $key => $value) {
            if(isset($adPlaceList[$key]['place'])) foreach ($adPlaceList[$key]['place'] as $placeKey => $placeValue) {
                $adList[] = [
                    'classCode' => $key,
                    'className' => $value,
                    'placeCode' => $placeKey,
                    'placeName' => $placeValue
                ];
            }
        }

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

    /**
     * 添加和编辑电脑端广告
     * @return \Laminas\Http\Response|ViewModel
     * @throws \Doctrine\Common\Persistence\Mapping\MappingException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function adEditAction()
    {
        $view = new ViewModel();

        $class      = $this->getRequest()->getQuery('class');
        $placeCode  = $this->getRequest()->getQuery('placeCode');

        $adPlace    = Common::getDefaultTemplateTag('ad', 'pcTemplate');

        if(!isset($adPlace[$class]['place'][$placeCode])) return $this->redirect()->toRoute('operation-ad', ['action' => 'mobileAdList']);

        $templateCode = Common::getDefaultTemplateCode('pcTemplate');
        $array    = [
            'className' => $adPlace['adClassName'][$class],
            'placeName' => $adPlace[$class]['place'][$placeCode],
            'adType'    => $adPlace[$class][$placeCode]['type'],
            'imageSize' => $adPlace[$class][$placeCode]['imageSize'],
            'classCode' => $class,
            'placeCode' => $placeCode
        ];

        $slideImage = [];
        $adInfo = $this->entityManager->getRepository(Ad::class)->findOneBy(['templateCode' => $templateCode, 'adClass' => $class, 'adPlaceCode' => $placeCode]);
        if($adInfo) {
            $array['adInfo'] = $adInfo;

            $slideList  = $this->entityManager->getRepository(AdSlide::class)->findBy(['adId' => $adInfo->getAdId()], ['adSlideSort' => 'ASC']);
            if($slideList) foreach ($slideList as $slideKey => $slideValue) {
                $keyNum = $slideKey + 1;
                $slideImage['slideImage'.$keyNum]   = $slideValue->getAdSlideImage();
                $slideImage['slideId'.$keyNum]      = $slideValue->getAdSlideId();
                $slideImage['slideUrl'.$keyNum]     = $slideValue->getAdSlideUrl();
                $slideImage['slideSort'.$keyNum]    = $slideValue->getAdSlideSort();
            }
        }

        if($array['adType'] == 'image') $form = new AdForm($adInfo);
        else $form = new AdSlideForm($slideImage);

        if($this->getRequest()->isPost()) {
            $data = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data = array_merge($data, [
                    'adClass'       => $class,
                    'adPlaceCode'   => $placeCode,
                    'adType'        => $array['adType'],
                    'templateCode'  => $templateCode
                ]);

                if(!empty($data['adStartTime']))  $data['adStartTime']  = Carbon::parse($data['adStartTime'])->timestamp;
                if(!empty($data['adEndTime']))    $data['adEndTime']    = Carbon::parse($data['adEndTime'].' 23:59:59')->timestamp;

                if($adInfo) {
                    $this->adManager->editAd($data, $adInfo);
                    if($array['adType'] == 'slide') $this->adSlideManager->editAdSlide($data);
                }
                else {
                    $ad = $this->adManager->addAd($data);
                    if($array['adType'] == 'slide') $this->adSlideManager->addAdSlide($data, $ad->getAdId());
                }

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('广告 %s 设置成功!'), $array['placeName']), $this->translator->translate('电脑端广告'));

                return $this->redirect()->toRoute('operation-ad');
            }
        } else {
            if($adInfo) {
                $adArray = $adInfo->valuesArray();
                $adArray['adImage']     = $adArray['adBody'];
                $adArray['adStartTime'] = $adArray['adStartTime'] > 0 ? date("Y-m-d", $adArray['adStartTime']) : '';
                $adArray['adEndTime']   = $adArray['adEndTime'] > 0 ? date("Y-m-d", $adArray['adEndTime']) : '';
                if(!empty($slideImage)) $adArray = array_merge($adArray, $slideImage);
                $form->setData($adArray);
            }
        }

        $array['form'] = $form;

        //判断是图片还是幻灯片
        if($array['adType'] == 'image') $view->setTemplate('operation/ad/ad-edit');
        else $view->setTemplate('operation/ad/ad-slide-edit');

        return $view->setVariables($array);
    }

    /**
     * 广告清除
     * @return mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function adDeleteAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $data = $this->params()->fromQuery();
        if (!in_array($data['type'], ['pc', 'mobile']) || !$data['class'] || !$data['placeCode']) return $this->adminCommon()->toReferer();

        $templateCode = Common::getDefaultTemplateCode($data['type'].'Template');

        $adInfo = $this->entityManager->getRepository(Ad::class)->findOneBy(['templateCode' => $templateCode, 'adClass' => $data['class'], 'adPlaceCode' => $data['placeCode']]);
        if ($adInfo) {
            switch ($adInfo->getAdType()) {
                case 'image':   //图片
                    $this->adminCommon()->deleteImage($adInfo->getAdBody());
                    break;
                case 'slide':   //幻灯片
                    $adSlide = $this->entityManager->getRepository(AdSlide::class)->findBy(['adId' => $adInfo->getAdId()]);
                    if ($adSlide) foreach ($adSlide as $slideValue) {
                        $this->adminCommon()->deleteImage($slideValue->getAdSlideImage());
                        $this->adSlideManager->deleteAdSlide($slideValue);
                    }
                    break;
            }
            $this->adManager->deleteAd($adInfo);

            $this->adminCommon()->addOperLog($this->translator->translate('广告信息清除成功!'), $this->translator->translate('广告'));
        }

        return $this->adminCommon()->toReferer();
    }

    /**
     * 手机端广告位置列表
     * @return array
     */
    public function mobileAdListAction()
    {
        $adPlaceList = Common::getDefaultTemplateTag('ad');
        $adList = [];
        if($adPlaceList) foreach ($adPlaceList['adClassName'] as $key => $value) {
            if(isset($adPlaceList[$key]['place'])) foreach ($adPlaceList[$key]['place'] as $placeKey => $placeValue) {
                $adList[] = [
                    'classCode' => $key,
                    'className' => $value,
                    'placeCode' => $placeKey,
                    'placeName' => $placeValue
                ];
            }
        }

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

    /**
     * 添加和编辑手机广告
     * @return \Laminas\Http\Response|ViewModel
     * @throws \Doctrine\Common\Persistence\Mapping\MappingException
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function mobileAdEditAction()
    {
        $view = new ViewModel();

        $class      = $this->getRequest()->getQuery('class');
        $placeCode  = $this->getRequest()->getQuery('placeCode');

        $adPlace    = Common::getDefaultTemplateTag('ad');

        if(!isset($adPlace[$class]['place'][$placeCode])) return $this->redirect()->toRoute('operation-ad', ['action' => 'mobileAdList']);

        $templateCode = Common::getDefaultTemplateCode();
        $array    = [
            'className' => $adPlace['adClassName'][$class],
            'placeName' => $adPlace[$class]['place'][$placeCode],
            'adType'    => $adPlace[$class][$placeCode]['type'],
            'imageSize' => $adPlace[$class][$placeCode]['imageSize'],
            'classCode' => $class,
            'placeCode' => $placeCode
        ];

        $slideImage = [];
        $adInfo = $this->entityManager->getRepository(Ad::class)->findOneBy(['templateCode' => $templateCode, 'adClass' => $class, 'adPlaceCode' => $placeCode]);
        if($adInfo) {
            $array['adInfo'] = $adInfo;

            $slideList  = $this->entityManager->getRepository(AdSlide::class)->findBy(['adId' => $adInfo->getAdId()], ['adSlideSort' => 'ASC']);
            if($slideList) foreach ($slideList as $slideKey => $slideValue) {
                $keyNum = $slideKey + 1;
                $slideImage['slideImage'.$keyNum]   = $slideValue->getAdSlideImage();
                $slideImage['slideId'.$keyNum]      = $slideValue->getAdSlideId();
                $slideImage['slideUrl'.$keyNum]     = $slideValue->getAdSlideUrl();
                $slideImage['slideSort'.$keyNum]    = $slideValue->getAdSlideSort();
            }
        }

        if($array['adType'] == 'image') $form = new AdForm($adInfo);
        else $form = new AdSlideForm($slideImage);

        if($this->getRequest()->isPost()) {
            $data = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $data = array_merge($data, [
                    'adClass'       => $class,
                    'adPlaceCode'   => $placeCode,
                    'adType'        => $array['adType'],
                    'templateCode'  => $templateCode
                ]);

                if(!empty($data['adStartTime']))  $data['adStartTime']  = Carbon::parse($data['adStartTime'])->timestamp;
                if(!empty($data['adEndTime']))    $data['adEndTime']    = Carbon::parse($data['adEndTime'].' 23:59:59')->timestamp;

                if($adInfo) {
                    $this->adManager->editAd($data, $adInfo);
                    if($array['adType'] == 'slide') $this->adSlideManager->editAdSlide($data);
                }
                else {
                    $ad = $this->adManager->addAd($data);
                    if($array['adType'] == 'slide') $this->adSlideManager->addAdSlide($data, $ad->getAdId());
                }

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('广告 %s 设置成功!'), $array['placeName']), $this->translator->translate('手机端广告'));

                return $this->redirect()->toRoute('operation-ad', ['action' => 'mobileAdList']);
            }
        } else {
            if($adInfo) {
                $adArray = $adInfo->valuesArray();
                $adArray['adImage']     = $adArray['adBody'];
                $adArray['adStartTime'] = $adArray['adStartTime'] > 0 ? date("Y-m-d", $adArray['adStartTime']) : '';
                $adArray['adEndTime']   = $adArray['adEndTime'] > 0 ? date("Y-m-d", $adArray['adEndTime']) : '';
                if(!empty($slideImage)) $adArray = array_merge($adArray, $slideImage);
                $form->setData($adArray);
            }
        }

        $array['form'] = $form;

        //判断是图片还是幻灯片
        if($array['adType'] == 'image') $view->setTemplate('operation/ad/mobile-ad-edit');
        else $view->setTemplate('operation/ad/mobile-ad-slide-edit');

        return $view->setVariables($array);
    }
}