<?php

namespace app\controller\api;

use app\controller\manager\mall\Category;
use app\exception\RepositoryException;
use app\model\AccountRecord;
use app\model\Spu as SpuModel;
use app\model\SpuActivity;
use app\repository\OrderRepository;
use app\repository\SpuRepository;
use Exception;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;
use think\response\Json;

class Spu extends Base
{
    protected $noNeedLogin = ['list', 'category', 'condition', 'detail', 'home'];

    /**
     * 商品列表筛选条件
     *
     */
    public function category(): Json
    {
        $list = SpuRepository::getInstance()->category(0,["id,pid,title,cover"])->toArray();
        return $this->json(0, 'success', $list);
        if(input("hasChildren/d",0)){
            $list = SpuRepository::getInstance()->categoryAll(["id,sort,pid,title,cover"]);

        }else{
            $list = SpuRepository::getInstance()->category(0,["id,pid,title,cover"])->toArray();
        }
        return $this->json(0, 'success', $list);
    }

    /**
     * 商品列表筛选条件
     *
     */
    public function condition(): Json
    {
        $list = [
            [
                'title' => '分类',
                'field' => 'category_id',
                'children' => array_merge([['name' => '全部', 'value' => '']], SpuRepository::getInstance()->category(0, ['id as value', 'title as name'])->toArray())
            ],
            [
                'title' => '活动',
                'field' => 'activity',
                'children' => array_merge([['name' => '全部', 'value' => '']], SpuModel::activity())
            ]
        ];

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

    /**
     * 首页商品列表
     *
     * @return Json
     * @throws RepositoryException
     * @throws Exception
     */
    public function home(): Json
    {
        $repo = SpuRepository::getInstance();

        $fields = [
            'id', 'name', 'subtitle', 'original_price', 'cover',
        ];

        $params             = input();
        $params['fields']   = $fields;
        $params['is_home']  = SpuModel::COMMON_ON;
        //$params['is_score'] = SpuModel::COMMON_OFF;//排除积分商品

//        if (!isset($params['category_id']) || empty($params['category_id'])) {
//            $params['category_id'] = \app\model\mall\Category::getFirst();
//        }

        $list = $repo->listForFront($params, function ($q) {
            return $q->withAttr('cover', function ($value, $data) {
                return resourceJoin($value, $this->request->domain());
            });
        });

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

    /**
     * 获取已发布的商品列表
     *
     * @return Json
     * @throws RepositoryException
     * @throws Exception
     */
    public function list(): Json
    {
        $repo = SpuRepository::getInstance();

        $fields = SpuModel::spuListFields();

        $params             = input();
        $params['fields']   = $fields;
        $params['is_score'] = SpuModel::COMMON_OFF;//排除积分商品

        $list = $repo->listForFront($params, function ($q) {
            return $q->withAttr('cover', function ($value, $data) {
                return resourceJoin($value, $this->request->domain());
            });
        });

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

    /**
     * 获取已发布的积分商品列表
     *
     * @return Json
     * @throws RepositoryException
     * @throws Exception
     */
    public function score(): Json
    {
        $repo = SpuRepository::getInstance();

        $type      = input('type/s', SpuModel::TYPE_NORMAL);//normal=综合 newest=最新
        $sortField = input('sort_field/s', '');// score=积分 num=兑换量
        $sortValue = input('sort_value/s', '');//desc=降序 asc=升序

        $rules = [
            'page|页数'         => 'integer|gt:0',
            'size|每页数量'       => 'integer|gt:0',
            'type|类型'         => 'in:newest,'.SpuModel::TYPE_NORMAL,
            'sort_field|排序字段' => 'in:score,amount',
            'sort_value|排序值'  => 'in:asc,desc',
        ];

        $message = [
            'type.in'       => '类型错误',
            '$sortField.in' => '排序字段错误',
            'sort_value.in' => '排序值错误',
        ];

        $params = input();

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

        $order = [];//排序

        // 综合排序
        if ($type === SpuModel::TYPE_NORMAL) {
            $order = [
                'sort' => 'desc',
                'id'   => 'desc',
            ];
        }

        // 最新排序
        if ($type === 'newest') {
            $order = ['published_at' => 'desc'];
        }

        // 兑换量排序
        if (!empty($sortField)) {
            if (empty($sortValue)) {
                return $this->json(4003, '排序参数错误');
            }
            $order = [
                $sortField => $sortValue
            ];
        }

        $params['is_score'] = SpuModel::COMMON_ON;
        $params['fields']   = SpuModel::scoreListFields();

        $list = $repo->listForFront($params, function ($q) {
            return $q->withAttr('cover', function ($value, $data) {
                return resourceJoin($value, $this->request->domain());
            });
        }, $order);

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

    /**
     * 收藏列表
     *
     * @return Json
     * @throws Exception
     */
    public function collection(): Json
    {
        $rules = [
            'page|页数'   => 'integer',
            'size|每页数量' => 'integer',
        ];

        $params    = input();
        $page      = $params['page'] ?? 1;
        $size      = $params['size'] ?? 10;
        $accountId = $this->request->user['user_id'] ?? 0;


        $params['page'] = 1;
        $params['size'] = 0;

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

        //获取收藏相关
        $collection = AccountRecord::where('type', AccountRecord::TYPE_SPU)
            ->where('action', AccountRecord::ACTION_COLLECT)
            ->where('account_id', $accountId)
            ->where('is_record', AccountRecord::COMMON_ON)
            ->order('recorded_at', 'desc');

        $total = $collection->count();
        if ($total <= 0) {
            return $this->json(0, 'success', [
                'total'   => 0,
                'current' => $page,
                'size'    => $size,
                'list'    => new Collection(),
            ]);
        }

        $recordList = $collection->page($page)->limit($size)->field('relation_id,recorded_at')->select();

        $where   = [];
        $where[] = ['id', 'in', $recordList->column('relation_id')];

        $list = SpuRepository::getInstance()->listForFront($params, function ($q) {
            return $q->withAttr('cover', function ($value, $data) {
                return resourceJoin($value, $this->request->domain());
            });
        }, [], $where);

        $data    = [];
        $spuList = $list['list']->toArray();
        foreach ($recordList as $record) {
            foreach ($spuList as $key => $spu) {
                if ($record['relation_id'] == $spu['id']) {
                    $data[] = $spu;
                    unset($spuList[$key]);
                }
            }
        }

        $list['total']   = $total;
        $list['current'] = $page;
        $list['size']    = $size;
        $list['list']    = $data;

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


    /**
     * SPU 详情
     */
    public function detail(): Json
    {
        $repo       = SpuRepository::getInstance();
        $id         = input('id/d', 0);
        $accountId  = $this->request->user['user_id'] ?? 0;
        $domain = $this->request->domain();

        try {
            $data = $repo->detail($id, $accountId);
            $data['detail']['cover'] = $data['detail']['cover'] ?? '';
            $data['detail']['cover'] = resourceJoin($data['detail']['cover'], $domain);

            $data['detail']['share_img'] = $data['detail']['share_img'] ?? '';
            $data['detail']['share_img'] = resourceJoin($data['detail']['share_img'], $domain);

            $pregRule = "/<[img|IMG].*?src=[\'|\"][\/storage]{1}(.*?(?:[\.jpg|\.jpeg|\.png|\.gif|\.bmp]))[\'|\"].*?[\/]?>/";
            $data['detail']['content']  = preg_replace($pregRule, '<img src="' . $this->request->domain() . '/${1}" style="max-width:100%">', (string)$data['detail']['content']  );


            if(isset($data['detail']['images']) && !empty($data['detail']['images'])){
                $images = explode(',', $data['detail']['images']);
                $imageArr = [];
                foreach ($images as $image) {
                    if(!empty($image)){
                        $imageArr[] = resourceJoin($image, $domain);
                    }
                }
                $data['detail']['images'] = $imageArr;
            }
            return $this->json(0, 'success', $data);
        } catch (RepositoryException $e) {
            return $this->json(4001, $e->getMessage());
        } catch (Exception $e) {
            $repo->log($e->getMessage(), $e);
            return $this->json(5000, '获取详情失败');
        }
    }

    /**
     * 收藏
     */
    public function record(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4000, '无效请求');
        }

        $accountId = $this->request->user['user_id'] ?? 0;
        $id        = $this->request->param('id/d', 0);
        $action    = $this->request->param('action/s', '');

        try {
            if ($accountId <= 0 || $id <= 0) {
                return $this->json(4001, '无效请求');
            }

            if (!in_array($action, AccountRecord::allowActions())) {
                return $this->json(4001, '操作类型参数错误');
            }

            if (!SpuModel::findById($id)) {
                return $this->json(4001, '商品不存在');
            }

            AccountRecord::record($accountId, AccountRecord::TYPE_SPU, $action, $id);
        } catch (Exception $e) {
            Log::error('[商品记录失败]'.$e->getMessage());
            return $this->json(5000, '操作失败');
        }

        return $this->json();
    }

    /**
     * 取消 收藏
     */
    public function unRecord(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4000, '无效请求');
        }

        $accountId = $this->request->user['user_id'] ?? 0;
        $id        = $this->request->param('id/d', 0);
        $action    = $this->request->param('action/s', '');

        try {
            if ($accountId <= 0 || $id <= 0) {
                return $this->json(4001, '无效请求');
            }

            if (!in_array($action, AccountRecord::allowActions())) {
                return $this->json(4001, '操作类型参数错误');
            }

            if (!SpuModel::findById($id)) {
                return $this->json(4001, '商品不存在');
            }

            AccountRecord::unRecord($accountId, $id, AccountRecord::TYPE_SPU, $action);
        } catch (Exception $e) {
            Log::error('[取消商品记录失败]'.$e->getMessage());
            return $this->json(5000, '操作失败');
        }

        return $this->json();
    }

    /**
     * 获取商品规格信息
     *
     * @return Json
     * @throws RepositoryException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function spec(): Json
    {
        $spuId = input('id');
        return $this->json(0, 'success', SpuRepository::getInstance()->getSpec($spuId));
    }
}