<?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\Math\Rand;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\ViewModel;
use Operation\Entity\RechargeCode;
use Operation\Entity\RechargeCodeRule;
use Operation\Form\CreateRechargeCodeForm;
use Operation\Form\RechargeCodeRuleForm;
use Operation\Service\RechargeCodeManager;
use Operation\Service\RechargeCodeRuleManager;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * 充值码
 * Class RechargeCodeController
 * @package Operation\Controller
 */
class RechargeCodeController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $rechargeCodeRuleManager;
    private $rechargeCodeManager;

    public function __construct(
        Translator $translator,
        EntityManager $entityManager,
        RechargeCodeRuleManager $rechargeCodeRuleManager,
        RechargeCodeManager $rechargeCodeManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->rechargeCodeRuleManager = $rechargeCodeRuleManager;
        $this->rechargeCodeManager = $rechargeCodeManager;
    }

    /**
     * 充值码规则列表
     * @return array|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $rechargeCodeRule = $this->entityManager->getRepository(RechargeCodeRule::class)->findRechargeCodeRuleList();

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

    /**
     * 添加充值码规则，并生成充值码
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addAction()
    {
        $form = new RechargeCodeRuleForm();

        if ($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

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

                $ruleInfo = $this->rechargeCodeRuleManager->addRechargeCodeRule($data);
                $this->rechargeCodeManager->addRechargeCode($ruleInfo);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('充值码规则 %s 添加成功，并生成充值码!'), $ruleInfo->getCodeRuleTitle()), $this->translator->translate('充值码'));

                return $this->redirect()->toRoute('operation-recharge-code');
            }
        }

        return [
            'form' => $form,
            'currencySymbol'=> Common::configValue('default', 'currency')['symbol']
        ];
    }

    /**
     * 编辑充值码规则
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editAction()
    {
        $rechargeRuleId = (int) $this->params()->fromRoute('id', 0);
        $rechargeRuleInfo = $this->entityManager->getRepository(RechargeCodeRule::class)->findOneBy(['codeRuleId' => $rechargeRuleId]);
        if ($rechargeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该充值码规则不存在!'));
            return $this->redirect()->toRoute('operation-recharge-code');
        }

        $form = new RechargeCodeRuleForm(true);

        if ($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

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

                $rechargeRuleInfo = $this->rechargeCodeRuleManager->editRechargeCodeRule($data, $rechargeRuleInfo);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('充值码规则 %s 编辑成功!'), $rechargeRuleInfo->getCodeRuleTitle()), $this->translator->translate('充值码'));

                return $this->redirect()->toRoute('operation-recharge-code');
            }
        } else {
            $ruleArray = $rechargeRuleInfo->valuesArray();
            $ruleArray['codeStartTime'] = $ruleArray['codeStartTime'] > 0 ? date("Y-m-d", $ruleArray['codeStartTime']) : '';
            $ruleArray['codeEndTime']   = $ruleArray['codeEndTime'] > 0 ? date("Y-m-d", $ruleArray['codeEndTime']) : '';
            $form->setData($ruleArray);
        }

        return [
            'form' => $form,
            'rechargeRuleInfo'  => $rechargeRuleInfo,
            'currencySymbol'    => Common::configValue('default', 'currency')['symbol']
        ];
    }

    /**
     * 充值码列表
     * @return array|\Laminas\Http\Response
     */
    public function rechargeCodeListAction()
    {
        $rechargeRuleId = (int) $this->params()->fromRoute('id', 0);
        $rechargeRuleInfo = $this->entityManager->getRepository(RechargeCodeRule::class)->findOneBy(['codeRuleId' => $rechargeRuleId]);
        if ($rechargeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该充值码规则不存在!'));
            return $this->redirect()->toRoute('operation-recharge-code');
        }

        $rechargeCodeList = $this->entityManager->getRepository(RechargeCode::class)->findBy(['codeRuleId' => $rechargeRuleId], ['codeId' => 'DESC']);

        return [
            'rechargeRuleInfo'  => $rechargeRuleInfo,
            'rechargeCodeList'  => $rechargeCodeList
        ];
    }

    /**
     * 充值码导出
     * @return \Laminas\Http\PhpEnvironment\Response|\Laminas\Http\Response|\Laminas\Stdlib\ResponseInterface|mixed
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportRechargeCodeAction()
    {
        $rechargeRuleId = (int) $this->params()->fromRoute('id', 0);
        $rechargeRuleInfo = $this->entityManager->getRepository(RechargeCodeRule::class)->findOneBy(['codeRuleId' => $rechargeRuleId]);
        if ($rechargeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该充值码规则不存在!'));
            return $this->redirect()->toRoute('operation-recharge-code');
        }

        $codeState = $this->params()->fromPost('codeState', 0);
        if (!in_array($codeState, [1, 2, 3])) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('非正常状态导出!'));
            return $this->redirect()->toRoute('operation-recharge-code', ['action' => 'rechargeCodeList', 'id' => $rechargeRuleId]);
        }

        $rechargeCodeList = $this->entityManager->getRepository(RechargeCode::class)->findExportRechargeCode($rechargeRuleId, $codeState);

        $spreadsheet= new Spreadsheet();
        $spreadsheet->getProperties()->setCreator('DBShop');
        $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(20);
        $spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(10);
        $spreadsheet->getActiveSheet()->getColumnDimension('C')->setWidth(30);
        $spreadsheet->getActiveSheet()->getStyle('B')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);

        $sheet      = $spreadsheet->getActiveSheet();

        $sheet->setCellValue('A1', $this->translator->translate('充值码名称'));
        $sheet->setCellValue('B1', $this->translator->translate('金额'));
        $sheet->setCellValue('C1', $this->translator->translate('充值码'));

        if ($rechargeCodeList) {
            $num = 2;
            foreach ($rechargeCodeList as $codeValue) {
                $sheet->setCellValueByColumnAndRow(1, $num, $rechargeRuleInfo->getCodeRuleTitle());
                $sheet->setCellValueByColumnAndRow(2, $num, $codeValue->getCodeMoney());
                $sheet->setCellValueByColumnAndRow(3, $num, $codeValue->getCodeStr());
                $num++;
            }
        }

        $response   = $this->getResponse();
        $headers    = $response->getHeaders();
        $headers->addHeaderLine("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        $headers->addHeaderLine("Content-Disposition: attachment;filename=".$this->translator->translate('充值码').'-'.$rechargeRuleInfo->getCodeRuleId().".xlsx");
        $headers->addHeaderLine("Cache-Control: max-age=0");
        $response->sendHeaders();

        $writer = new Xlsx($spreadsheet);
        return $response->setContent($writer->save('php://output'));
    }

    /**
     * 删除充值码规则及所有充值码（已使用的和未使用的都删除）
     * @return mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function deleteAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $rechargeRuleId = (int) $this->params()->fromRoute('id', 0);
        $rechargeRuleInfo = $this->entityManager->getRepository(RechargeCodeRule::class)->findOneBy(['codeRuleId' => $rechargeRuleId]);
        if ($rechargeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该充值码规则不存在!'));
            return $this->adminCommon()->toReferer();
        }

        $this->rechargeCodeRuleManager->deleteRechargeCodeRule($rechargeRuleInfo);
        $this->rechargeCodeManager->deleteRechargeRuleAllCode($rechargeRuleId);

        $this->adminCommon()->addOperLog(sprintf($this->translator->translate('充值码规则 %s 删除成功!'), $rechargeRuleInfo->getCodeRuleTitle()), $this->translator->translate('充值码'));

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

    /**
     * 生成充值码
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function createRechargeCodeAction()
    {
        $rechargeRuleId = (int) $this->params()->fromRoute('id', 0);
        $rechargeRuleInfo = $this->entityManager->getRepository(RechargeCodeRule::class)->findOneBy(['codeRuleId' => $rechargeRuleId]);
        if ($rechargeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该充值码规则不存在!'));
            return $this->redirect()->toRoute('operation-recharge-code');
        }

        $form = new CreateRechargeCodeForm();

        if ($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();
                $this->rechargeCodeRuleManager->editRechargeCodeRule(['codeNum' => $rechargeRuleInfo->getCodeNum() + $data['codeNum']], $rechargeRuleInfo);
                $this->rechargeCodeManager->addRechargeCode($rechargeRuleInfo, $data['codeNum']);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('充值码 %s 生成成功!'), $rechargeRuleInfo->getCodeRuleTitle()), $this->translator->translate('充值码'));
                return $this->redirect()->toRoute('operation-recharge-code');
            }
        }

        return [
            'form' => $form,
            'rechargeRuleInfo'  => $rechargeRuleInfo,
            'currencySymbol'    => Common::configValue('default', 'currency')['symbol']
        ];
    }
}