<?php

namespace app\controller\api;

use app\exception\RepositoryException;
use app\repository\OrderRepository;
use app\model\Order as OrderModel;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Intervention\Image\ImageManagerStatic;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Config as CConfig;
use think\response\Json;

/**
 * 订单
 *
 * Class Order
 * @package app\controller\api
 */
class Order extends Base
{

    /**
     * 创建订单
     *
     * @return Json
     * @throws GuzzleException
     */
    public function create(): Json
    {
        if ($this->request->isPost()) {
            $params    = $this->request->param();
            $accountId = $this->request->user['user_id'] ?? 0;


            try {
                $data = OrderRepository::getInstance()->createOrder($accountId, $params);
                OrderRepository::getInstance()->updateSpuStock([]);
                return $this->json(0, 'success', $data);
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('订单创建失败', $e, 'error', 'order');
                return $this->json(5000, '订单创建失败'.$e->getMessage());
            }
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 购物车列表
     *
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function shoppingCart(): Json
    {
        $params    = $this->request->param();
        $accountId = $this->request->user['user_id'] ?? 0;
        $type      = $params['type'] ?? '';
        $page      = $params['page'] ?? 1;
        $size      = $params['size'] ?? 20;

        $domain = $this->request->domain();

        $data = OrderRepository::getInstance()->shoppingCart($accountId, $type, $page, $size);
        $data['list'] = $data['list']->each(function ($item) use ($domain) {
            $item->spu->spu_cover = $item->spu->spu_cover ?? '';
            $item->spu->spu_cover = resourceJoin($item->spu->spu_cover, $domain);
        });

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

    /**
     * 添加购物车
     *
     * @return Json
     * @throws Exception
     */
    public function shoppingCartAdd(): Json
    {
        if ($this->request->isPost()) {
            $params    = $this->request->param();
            $accountId = $this->request->user['user_id'] ?? 0;
            $rules     = [
                'sku_id|商品' => 'require|number',
                'num|数量'    => 'require|number',
            ];

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

            try {
                OrderRepository::getInstance()->shoppingCartAdd($accountId, $params['sku_id'], $params['num'] ?? 1);
                return $this->json();
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('购物车添加失败', $e);
                return $this->json(5000, '购物车添加失败');
            }
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 购物车商品数量变更
     *
     * @return Json
     * @throws Exception
     */
    public function shoppingCartChangeNum(): Json
    {
        if ($this->request->isPost()) {
            $params = $this->request->param();
            $rules  = [
                'id|ID'  => 'require|number',
                'num|数量' => 'require|number',
            ];

            $validate = $this->validateByApi($params, $rules);
            if ($validate !== true) {
                return $validate;
            }
            try {
                OrderRepository::getInstance()->shoppingCartChangeNum($params['id'], $params['num']);
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('购物车数量加减失败', $e);
                return $this->json(5000, '操作失败');
            }

            return $this->json();
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 购物车商品删除
     *
     * @return Json
     */
    public function shoppingCartDel(): Json
    {
        if ($this->request->isPost()) {
            $id        = input('post.id/d', 0);
            $accountId = $this->request->user['user_id'] ?? 0;
            if (!$id) {
                return $this->json(4001, '参数错误');
            }

            try {
                OrderRepository::getInstance()->shoppingCartDel($accountId, $id);
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('购物车数量加减失败', $e);
                return $this->json(5000, '操作失败');
            }

            return $this->json();
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 订单准备信息
     * 结算页面 获取商品数据及汇总金额
     * @return Json
     */
    public function prepareInfo(): Json
    {
        if ($this->request->isPost()) {
            $params           = $this->request->param();
            $accountId        = $this->request->user['user_id'] ?? 0;
            $params['domain'] = $this->request->domain();

            try {
                $data = OrderRepository::getInstance()->prepareInfo($accountId, $params);
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('获取订单前置信息失败', $e, 'error', 'order');
                return $this->json(5000, '订单信息获取失败');
            }

            return $this->json(0, 'success', $data);
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 支付成功通知
     * 结算页面 获取商品数据及汇总金额
     *
     * @return Json
     * @throws Exception
     */
    public function paid(): Json
    {
        if ($this->request->isPost()) {
            $params    = $this->request->param();
            $accountId = $this->request->user['user_id'] ?? 0;
            $rules     = [
                'order_coding|订单编号' => 'require',
            ];

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

            try {
                if (OrderRepository::getInstance()->setPaid($params['order_coding'])) {
                    return $this->json();
                }
                return $this->json(4003, '支付失败');
            } catch (RepositoryException $e) {
                return $this->json(4000, $e->getMessage());
            } catch (Exception $e) {
                OrderRepository::log('支付成功通知操作失败', $e);
                return $this->json(5000, '操作失败');
            }
        }
        return $this->json(4002, '请求错误');
    }

    /**
     * 订单验收 - 确认收货
     *
     * @return Json
     */
    public function accepted(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4002, '请求错误');
        }

        $accountId = $this->request->user['user_id'] ?? 0;
        $orderId   = $this->request->param('order_id', 0);

        try {
            OrderRepository::getInstance()->orderAccepted($orderId, $accountId);

        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        }

        return $this->json();
    }

    /**
     * 发货
     *
     * @return Json
     */
    public function ship(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4002, '请求错误');
        }

        $orderId       = $this->request->param('order_id', 0);
        $expressId     = $this->request->param('express_id', 0);
        $expressNumber = $this->request->param('express_number', 0);

        try {
            OrderRepository::getInstance()->orderShipping($orderId, $expressId, $expressNumber);

        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        }

        return $this->json();
    }

    /**
     * 查询订单物流
     *
     * @return Json
     */
    public function logistics(): Json
    {
        $orderCoding = input('order_coding');

        try {
            $res = OrderRepository::getInstance()->logistics($orderCoding);
            return $this->json(0, 'success', $res);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        } catch (Exception $e) {
            OrderRepository::log('物流查询失败', $e);
            return $this->json(5000, '获取物流信息失败');
        }
    }

    /**
     * 取消订单
     *
     * @return Json
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function cancel(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4002, '请求错误');
        }

        $orderCoding = $this->request->param('order_coding', 0);
        $reason      = $this->request->param('remarks', '');

        try {
            OrderRepository::getInstance()->setClosed($orderCoding, OrderModel::STATUS_CANCEL, $reason);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        }

        return $this->json();
    }

    /**
     * 订单付款
     *
     * @return Json
     * @throws Exception
     */
    public function pay(): Json
    {
        if (!$this->request->isPost()) {
            return $this->json(4002, '请求错误');
        }

        $accountId   = $this->request->user['user_id'] ?? 0;
        $orderCoding = $this->request->param('order_coding', 0);

        try {
            $res = OrderRepository::getInstance()->pay($orderCoding, $accountId);
            return $this->json(0, 'success', $res);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        }
    }

    /**
     * 购物车数量
     *
     * @return Json
     * @throws Exception
     */
    public function shoppingCartCount(): Json
    {
        $accountId = $this->request->user['user_id'] ?? 0;
        $type      = $this->request->param('type/s', 'spu');

        try {
            $count = OrderRepository::getInstance()->shoppingCartCount($accountId, $type);
            return $this->json(0, 'success', ['count' => $count]);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        }
    }

    /**
     * 商品sku核验
     *
     */
    public function check(): Json
    {
        $orderCoding = input('order_coding/s', '');
        $id          = input('id/d', 0);
        $checkBy     = input('check_user/d', 0);
        $num         = input('num/d', 1);

        try {
            OrderRepository::getInstance()->check($orderCoding, $id, $num, $checkBy);
            // 核验后事件
            event('OrderSpuCheck', $orderCoding);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        } catch (Exception $e) {
            OrderRepository::log('订单商品核验失败', $e);
            return $this->json(5000, '订单商品核验失败');
        }
        return $this->json();
    }

    /**
     * 商品sku核验结果
     *
     */
    public function checkResult(): Json
    {
        $orderCoding = input('order_coding/s', '');
        $id          = input('id/d', 0);
        $notCheckNum = input('not_check_num/d', 0);

        try {
            $res = OrderRepository::getInstance()->checkResult($orderCoding, $id, $notCheckNum);
            return $this->json(0, 'success', ['result' => (int) $res]);
        } catch (RepositoryException $e) {
            return $this->json(4000, $e->getMessage());
        } catch (Exception $e) {
            OrderRepository::log('订单商品核验结果获取失败', $e);
            return $this->json(5000, '订单商品核验结果获取失败');
        }
    }

    /**
     * 获取拼团ID
     *
     * @return Json
     */
    public function getGroupId(): Json
    {
        $params      = $this->request->param();
        $orderCoding = $params['order_coding'] ?? '';

        $groupId = OrderRepository::getInstance()->groupId($orderCoding);

        return $this->json(0, 'success', ['group_id' => $groupId]);
    }


    //生成订单图片
    public function orderQrCode()
    {
        $id = input("id/d",0);
        $order = OrderModel::findById($id);
        if(empty($order)){
            return $this->json(4001,"订单不存在");
        }
        $orderCoding = $order->coding;
        CConfig::load('extra/addwechat', "addwechat");
        $addwechat  = config("addwechat");
        $qrImg      = public_path() . ($addwechat["wechat"] ?? '');
        $content     = replaceStoragePath($addwechat['content']??'');

        if(!is_file($qrImg)){
            return $this->json(4001,"生成订单二维码图片失败");
        }
        if(!is_writable(public_path()."/storage/")){
            return $this->json("上传文件夹需要写入权限");
        }
        if(!is_dir( public_path()."/storage/order_qr_code/")){
            mkdir(public_path()."/storage/order_qr_code");
        }

        $savePath = "/storage/order_qr_code/" . $orderCoding . ".png";
         ImageManagerStatic::canvas(800, 700, '#fff')
            ->insert(ImageManagerStatic::make($qrImg)->resize(500,500),"top-left",150,0)
            ->text("订单:".$orderCoding,400,600, function ($font){
                $font->file(public_path() . "/static/HYa3gj.ttf");
                $font->size(46);
                $font->align("center");
                $font->valign("center");
            })

//            ->insert(ImageManagerStatic::make($mpCode)->resize(380, 380), 'bottom-right', 560, 723)
//               ->encode('data-url');
            ->save(public_path() . $savePath);
        return $this->json(0, "success", ["path" => resourceJoin($savePath, $this->request->domain()), "content" => $content]);
    }



}