<?php

namespace app\controller\manager\mall;

use app\controller\manager\Base;
use app\exception\RepositoryException;
use app\model\Config;
use app\model\Log;
use app\model\Sku;
use app\model\Spu as SpuModel;
use app\model\SpuActivity;
use app\repository\SpuRepository;
use app\service\Math;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use think\facade\Db;
use think\response\Json;
use think\response\View;

class Activity extends Base
{
    protected $noNeedLogin = ['getOrder', 'getOrderGroupList'];

    /**
     * 列表
     *
     * @throws Exception
     */
    public function index()
    {
        if ($this->request->isPost()) {
            $params         = input();
            $params['type'] = SpuModel::TYPE_GROUP_BUY;
            $params['type'] = SpuModel::TYPE_GROUP_BUY;

            $res = $this->spuList($params);

            return $this->json(0, 'success', $res);
        }

        $this->data['statusList']  = SpuModel::statusTextList();
        $this->data['spuTypeList'] = SpuModel::spuTypeTextList();
        $this->data['type']        = SpuModel::TYPE_GROUP_BUY;

        $this->data['mpPath']     = Config::MINI_PATH_SPU_INFO;

        return $this->view();
    }

    /**
     * 拼团
     *
     * @return Json|View
     */
    public function groupMake()
    {
        if ($this->request->isPost()) {
            $params         = input();
            $params['type'] = SpuModel::TYPE_GROUP_MAKE;

            $res = $this->spuList($params);

            return $this->json(0, 'success', $res);
        }

        $this->data['statusList']  = SpuModel::statusTextList();
        $this->data['spuTypeList'] = SpuModel::spuTypeTextList();
        $this->data['type']        = SpuModel::TYPE_GROUP_MAKE;
        $this->data['url']         = '/manager/mall/activity/group-make';

        $this->data['mpPath']     = Config::MINI_PATH_SPU_INFO;

        return $this->view('/manager/mall/activity/index');
    }

    /**
     * 限时促销
     *
     * @return Json|View
     */
    public function limitTime()
    {
        if ($this->request->isPost()) {
            $params         = input();
            $params['type'] = SpuModel::TYPE_LIMIT_TIME;

            $res = $this->spuList($params);

            return $this->json(0, 'success', $res);
        }

        $this->data['statusList']  = SpuModel::statusTextList();
        $this->data['spuTypeList'] = SpuModel::spuTypeTextList();
        $this->data['type']        = SpuModel::TYPE_LIMIT_TIME;
        $this->data['url']         = '/manager/mall/activity/limit-time';

        $this->data['mpPath']     = Config::MINI_PATH_SPU_INFO;

        return $this->view('/manager/mall/activity/index');
    }

    protected function spuList(array $params): array
    {
        $res         = SpuRepository::getInstance()->activityList($params);
        $res['list'] = $res['list']->each(function ($item) {
            $status = '';
            $now    = date('Y-m-d H:i:s');
            if ($item['activity_begin_at'] > $now) {
                $status = '未开始';
            }

            if ($item['activity_begin_at'] < $now && $now < $item['activity_end_at']) {
                $status = '进行中';
            }

            if ($item['is_activity_history'] == SpuModel::COMMON_ON || $item['activity_end_at'] < $now) {
                $status = '已结束';
            }

            $item->status_text = $status;
        });

        return $res;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     * @throws Exception
     */
    public function add()
    {
        $repo = SpuRepository::getInstance();
        $type = input('type/s', SpuModel::TYPE_GROUP_BUY);
        if (!in_array($type, SpuModel::activityList())) {
            if ($this->request->isPost()) {
                return $this->json(4000, '活动类型错误');
            } else {
                return $this->error('活动类型错误');
            }
        }
        if ($this->request->isPost()) {
            $item  = $this->request->param('item/a', []);
            $sku   = $this->request->param('sku/a', []);
            $spuId = $this->request->param('spu_id/d', 0);

            $rules = [
                'cover|活动封面'             => 'require',
                'activity_begin_at|开始时间' => 'require|date',
                'activity_end_at|结束时间'   => 'require|date',
            ];

            $validate = $this->validateByApi($item, $rules);
            if ($validate !== true) {
                return $validate;
            }

            $item['is_score']      = SpuModel::COMMON_OFF;
            $item['is_activity']   = SpuModel::COMMON_ON;
            $item['activity_type'] = $type;

            try {
                foreach ($sku as &$val) {
                    if (isset($val['id'])) {
                        unset($val['id']);
                    }
                }

                $this->checkSku($sku);
                $repo->addActivity($type, $item, $spuId, $sku);
            } catch (RepositoryException $e) {
                return $this->json(4002, $e->getMessage());
            } catch (Exception $e) {
            }

            return $this->json();
        }

        $this->data['type']        = $type;
        $this->data['limitList']   = SpuModel::limitList();
        $this->data['limitFields'] = SpuRepository::getInstance()->activityFields($type);

        return $this->view();
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function edit()
    {
        $id      = $this->request->param('id/d', 0);
        $skuList = Sku::where('spu_activity_id', $id)
            ->where('enable', Sku::COMMON_ON)
            ->order('sort', 'asc')
            ->order('id', 'asc')->select()->toArray();

        if ($this->request->isPost()) {
            $item = $this->request->param('item/a', []);
            $sku  = $this->request->param('sku/a', []);
            try {
                $this->checkSku($sku);

                SpuRepository::getInstance()->editActivity($id, $item, $sku, $skuList);
            } catch (RepositoryException $e) {
                return $this->json(4002, $e->getMessage());
            } catch (Exception $e) {
            }

            return $this->json();
        }

        $spuActivity = SpuActivity::findById($id);
        if (empty($spuActivity)) {
            return $this->json(4000, '没有相关的商品记录!');
        }

        foreach ($skuList as &$val) {
            $val['price']          = Math::fen2Yuan($val['price']);
            $val['original_price'] = Math::fen2Yuan($val['original_price']);
        }

        $this->data['item']        = $spuActivity;
        $this->data['skuList']     = $skuList;
        $this->data['limitList']   = SpuModel::limitList();
        $this->data['limitFields'] = SpuRepository::getInstance()->activityFields($spuActivity['activity_type']);
        $this->data['id']          = $id;
        return $this->view();
    }

    /**
     * @throws RepositoryException
     * @throws Exception
     */
    protected function checkSku(array $sku)
    {
        // sku验证
        if (empty($sku)) {
            throw new RepositoryException('规格信息不能为空');
        }

        foreach ($sku as $k) {
            $validate = $this->validateByApi($k, [
                'title'      => 'require',
                'stock'      => 'require|number|gt:0',
                'price'      => 'number',
                'score'      => 'number',
                'is_default' => 'require|in:0,1',
            ]);

            if ($validate !== true) {
                return $validate;
            }
        }
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     * @throws Exception
     */
    public function modify()
    {
        if (!$this->request->isPost()) {
            return $this->json(4000, '非法请求');
        }

        $item     = input('post.');
        $validate = $this->validateByApi($item, [
            'field' => 'require',
            'value' => 'require',
        ]);

        if ($validate !== true) {
            return $validate;
        }

        if (!$info = SpuActivity::findById($item['id'])) {
            return $this->json(4001, '记录不存在');
        }

        $update = [$item['field'] => $item['value']];

        try {
            $info->save($update);
            if ($item['field'] == 'is_check' && $info['is_activity_history'] == SpuModel::COMMON_OFF) {
                SpuModel::where('id', $info['spu_id'])->save(['is_check' => $item['value']]);
            }
            return $this->json();
        } catch (ValidateException $e) {
            return $this->json(4001, $e->getError());
        } catch (Exception $e) {
            return $this->json(5000, '修改失败');
        }
    }

    /**
     * 立即结束-还原为普通商品
     *
     * @return Json
     */
    public function end(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4000, '非法请求');
        }

        $ids = $this->request->param('ids/a', []);
        if (empty($ids)) {
            $ids[] = $this->request->param('id/d', 0);
            $ids   = array_filter($ids);
        }

        try {
            if (count($ids)) {
                SpuRepository::getInstance()->restore($ids);
                Log::write(get_class(), 'end', '还原了活动商品,涉及到的ID为:'.implode(',', $ids));
            }
        } catch (RepositoryException $e) {
            return $this->json(4001, $e->getMessage());
        }

        return $this->json();
    }

    /**
     * 删除-还原为普通商品且隐藏
     *
     * @return Json
     */
    public function del(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4000, '非法请求');
        }

        $ids = $this->request->param('ids/a', []);
        if (empty($ids)) {
            $ids[] = $this->request->param('id/d', 0);
            $ids   = array_filter($ids);
        }

        try {
            if (count($ids)) {
                SpuRepository::getInstance()->restore($ids, false, true);
//                (new SpuActivity())->whereIn('id', $ids)->save(['deleted_at' => date('Y-m-d H:i:s')]);
                Log::write(get_class(), 'del', '还原了活动商品,涉及到的ID为:'.implode(',', $ids));
            }
        } catch (RepositoryException $e) {
            return $this->json(4001, $e->getMessage());
        }

        return $this->json();
    }


    /**
     * 活动商品详情
     *
     * @return View
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @throws Exception
     */
    public function info(): View
    {
        $id   = input('id/d', 0);
        $item = SpuActivity::findById($id);

        $status = '';
        $now    = date('Y-m-d H:i:s');
        if ($item['activity_begin_at'] > $now) {
            $status = '未开始';
        }

        if ($item['activity_begin_at'] < $now && $now < $item['activity_end_at']) {
            $status = '进行中';
        }

        if ($item['is_activity_history'] == SpuModel::COMMON_ON || $item['activity_end_at'] < $now) {
            $status = '已结束';
        }

        $item->status_text = $status;

        if ($item->activity_type == SpuModel::TYPE_GROUP_MAKE) {
            //拼团
            $orderList = SpuRepository::getInstance()->getActivityGroupList($id);
        } else {
            // 团购 促销
            $orderList = SpuRepository::getInstance()->getActivityOrderList($id);
        }

        $totalPriceList      = $orderList['list']->where('is_paid', SpuActivity::COMMON_ON)->column('total_price');
        $codingList          = $orderList['list']->column('coding');
        $accountList         = $orderList['list']->column('account_id');
        $codingCount         = count(array_unique($codingList));
        $accountCount        = count(array_unique($accountList));
        $totalPrice          = array_sum($totalPriceList);
        $item->total_money   = Math::fen2Yuan($totalPrice) ?? 0;
        $item->order_count   = $codingCount;
        $item->account_count = $accountCount;

        $this->data['item']         = $item;
        $this->data['statusList']   = \app\model\Order::statusTextList();
        $this->data['activityList'] = SpuModel::activityTextList();
        $this->data['limitList']    = SpuModel::limitList();//限购天数展示

        return $this->view();
    }

    /**
     * 获取活动商品的订单列表
     *
     * @return Json
     * @throws Exception
     */
    public function getOrder(): Json
    {
        $id   = input('id/d', 0);
        $page = input('page/d', 1);
        $size = input('size/d', 20);

        $res = SpuRepository::getInstance()->getActivityOrderList($id, $page, $size);

        return $this->json(0, '操作成功', $res);
    }

    /**
     * 获取拼团列表
     *
     * @return Json
     * @throws Exception
     */
    public function getOrderGroupList(): Json
    {
        $id   = input('id/d', 0);
        $page = input('page/d', 1);
        $size = input('size/d', 20);

        $res = SpuRepository::getInstance()->getActivityGroupList($id, $page, $size);

        return $this->json(0, '操作成功', $res);
    }

    /**
     * 批量审核
     *
     * @return View|Json
     * @throws Exception
     */
    public function check()
    {
        $id = input('id/s', '');
        if ($this->request->isPost()) {
            $ids  = input('ids/s');
            $check = input('is_check/d');

            if (!in_array($check, [SpuActivity::COMMON_ON, SpuActivity::COMMON_OFF])) {
                return $this->json(4001, '请选择是否展示');
            }

            $ids = explode(',', $ids);

            Db::startTrans();
            try {
                (new SpuActivity())->whereIn('id', $ids)->save(['is_check' => $check]);
                // 活动商品对应的普通商品审核状态同步
                $spuIds = SpuActivity::whereid('id', $ids)
                    ->where('is_activity_history', SpuActivity::COMMON_OFF)
                    ->column('spu_id');
                SpuModel::whereIn('id', $spuIds)->save(['is_check' => $check]);
                Db::commit();
                return $this->json(0, '操作成功');
            } catch (Exception $e) {
                Db::rollback();
                Log::error('活动商品批量审核操作失败'.$e->getMessage());
                return $this->json(5001, '商品批量审核操作失败');
            }
        }

        $this->data['id'] = $id;

        return $this->view();
    }

}