<?php

namespace Modules\Project\Http\Controllers\Api;

use Illuminate\Support\Facades\DB;
use Modules\Project\Entities\Coupon;
use Modules\Project\Entities\Order;
use Modules\Project\Http\Requests\OrderRequest;
use Modules\Project\Services\ExpressService;
use Modules\Project\Services\Order\Goods\GoodsCollection;
use Modules\Project\Services\OrderCouponService;
use Modules\Project\Services\OrderService;
use Modules\Project\Tranaformers\OrderTransformer;
use Modules\Project\Tranaformers\UserCouponTransformer;

class OrderController extends \Modules\Base\Http\Controllers\Api\ApiController
{
    public function __construct()
    {
        Order::addGlobalScope('user_deleted', function ($builder) {
            $builder->where('user_delete', 0);
        });
    }

    /**
     * 订单列表
     *
     * @OA\Get(
     *     tags={"订单"},
     *     summary="订单列表",
     *     path="/api/orders",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="status",
     *         in="query",
     *         description="status  unpaid(待付款) wait_delivery（待发货） wait_receiving(待收货)  complete(已完成)  canceled(已取消)",
     *         required=false,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功",
     *          @OA\MediaType(
     *             mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(
     *                      property="data",
     *                      type="array",
     *                      @OA\Items(),
     *                      description="列表"
     *                  ),
     *              )
     *          )
     *      )
     * )
     */
    public function index()
    {
        $user_id = \Auth()->id();

        $order = new Order();

        $order = $order->where('user_id', $user_id)->orderBy('id', 'desc');

        $order->when(request('status', false), function ($query, $status) {
            //1 待付款 2已取消 3已支付/待发货 4已经发货 5已收货 6已完成
            switch ($status) {
                case 'unpaid'://待付款
                    $query->whereIn('status', [Order::STATUS_DEFAULT]);
                    break;
                case 'wait_delivery'://待发货
                    $query->whereIn('status', [Order::STATUS_PAID]);
                    break;
                case 'wait_receiving'://待收货
                    $query->whereIn('status', [Order::STATUS_PAID,Order::STATUS_SHIPPED]);
                    break;
                case 'complete'://已完成
                    $query->whereIn('status', [Order::STATUS_CONFIRM,Order::STATUS_COMPLETE]);
                    break;
                case 'canceled'://已取消
                    $query->whereIn('status', [Order::STATUS_CANCEL]);
                    break;
            }
        });

        return $this->response->paginator($order->paginate(20), new OrderTransformer());
    }

    /**
     * 创建订单
     *
     * @OA\Post(
     *     tags={"订单"},
     *     summary="创建订单",
     *     path="/api/orders",
     *     description="
    //例如用户购买商品是 ：
    //1.id为1，规格是 红色 40 ，购买数量是10
    //2.id为3，规格是 黑色 ，购买数量是5
    //提交参数为：

    //商品1
    goods[0][id]:1
    goods[0][spec][0][group]:颜色
    goods[0][spec][0][spec_name]:红色
    goods[0][spec][1][group]:尺码
    goods[0][spec][1][spec_name]:40
    goods[0][qty]:10

    //商品2
    goods[1][id]:3
    goods[1][spec][0][name]:颜色
    goods[1][spec][0][value]:黑色
    goods[1][qty]:5",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\MediaType(
     *             mediaType="application/x-www-form-urlencoded",
     *             @OA\Schema(
     *                 type="object",
     *                 required={"goods"},
     *                 @OA\Property(
     *                     property="goods",
     *                     type="array",
     *                      @OA\Items(),
     *                 ),
     *             )
     *         )
     *     ),
     *     @OA\Response(
     *          response="201",
     *          description="成功"
     *      )
     * )
     */
    public function store(OrderRequest $request, OrderService $service)
    {
        $user_id = \Auth()->id();

        $order = [];

        DB::transaction(function () use ($request,$service,&$order,$user_id) {
            $order = $service->addOrder($user_id, $request->toArray());
        }, 10);

        return $this->response->item($order->model, new OrderTransformer())->setStatusCode(201);
    }

    /**
     * @return mixed
     *
     * @OA\Put(
     *     tags={"订单"},
     *     summary="关闭订单",
     *     path="/api/orders/{order_id}/cancel",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="path",
     *         description="订单id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *         )
     *     ),
     *     @OA\Response(
     *          response="204",
     *          description="成功"
     *      )
     * )
     */
    public function cancel($order_id, OrderService $service)
    {
        $user_id = \Auth()->id();

        $res = false;

        DB::transaction(function () use ($service,$user_id,$order_id,&$res) {
            $res = $service->userCancel($user_id, $order_id, '用户取消订单');
        }, 10);

        if ($res) {
        } else {
        }

        return $this->response->noContent()->setStatusCode(204);
    }

    /**
     * @return mixed
     *
     * @OA\Delete(
     *     tags={"订单"},
     *     summary="删除已取消订单",
     *     path="/api/orders/{order_id}",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="path",
     *         description="订单id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *         )
     *     ),
     *     @OA\Response(
     *          response="204",
     *          description="成功"
     *      )
     * )
     */
    public function destroy($order_id)
    {
        $user_id = \Auth()->id();

        $info = Order::findOrFail($order_id);

        if ($info->user_id == $user_id) {
            if (in_array($info->status, [Order::STATUS_DEFAULT,Order::STATUS_CANCEL,Order::STATUS_CONFIRM,Order::STATUS_COMPLETE])) {
                $info->user_delete = 1;

                $info->save();
            }
        }

        return $this->response->noContent()->setStatusCode(204);
    }

    /**
     * @return mixed
     *
     * @OA\Put(
     *     tags={"订单"},
     *     summary="确认订单",
     *     path="/api/orders/{order_id}/confirm",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="path",
     *         description="订单id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *         )
     *     ),
     *     @OA\Response(
     *          response="204",
     *          description="成功"
     *      )
     * )
     */
    public function confirm($order_id)
    {
        $user_id = \Auth()->id();

        $res = false;

        $service = new OrderService(Order::findOrFail($order_id));

        DB::transaction(function () use ($service,$user_id,&$res) {
            $res = $service->complete([], ['remark' => '用户确认订单']);
        }, 10);

        if ($res) {
        } else {
        }

        return $this->response->noContent()->setStatusCode(204);
    }

    /**
     * @return mixed
     *
     * @OA\Get(
     *     tags={"订单"},
     *     summary="订单详情",
     *     path="/api/orders/{order_id}",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="path",
     *         description="订单id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功",
     *          @OA\MediaType(
     *             mediaType="application/json",
     *              @OA\Schema(type="object",
     *                  @OA\Property(property="data", type="object", ref="#/components/schemas/Order")
     *              )
     *          )
     *      )
     * )
     */
    public function detail($order_id)
    {
        $user_id = \Auth()->id();

        $order = Order::where('id', $order_id)->where('user_id', $user_id)->get()->first();

        return $this->response->item($order, new OrderTransformer());
    }

    /**
     * @param OrderRequest $request
     * @param OrderService $service
     *
     * @throws \ErrorException
     *
     * @return mixed
     *
     *
     * @OA\Post(
     *     tags={"订单"},
     *     summary="预提交订单",
     *     path="/api/orders/preview",
     *     description="
     请求结构同提交订单。
    接口返回：
    freight: 0.00,//运费
    goods_price: 4100,//商品价格
    discount_amount: 1189.00,//优惠金额
    payable_amount: 2911.00,//实际需付
    qty: 11,//总商品数量
     ",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="goods",
     *         in="query",
     *         description="goods",
     *         required=true,
     *         @OA\Schema(
     *             type="array",
     *             @OA\Items(),
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="address_id",
     *         in="query",
     *         description="address_id",
     *         required=true,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="coupon_id",
     *         in="query",
     *         description="优惠券id",
     *         required=false,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Parameter(
     *         name="remarks",
     *         in="query",
     *         description="备注",
     *         required=false,
     *         @OA\Schema(
     *             type="string"
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功"
     *      )
     * )
     */
    public function preview(OrderRequest $request, OrderService $service)
    {
        $res = [];

        $data = $request->toArray();

        $goods = $data['goods'];

        $s_goods_collect = new GoodsCollection();

        if (isset($data['coupon_id'])) {
            $s_goods_collect->setCoupon($data['coupon_id']);
        }

        if (isset($data['address_id'])) {
            $s_goods_collect->setAddress($data['address_id']);
        }

        $s_goods_collect->pushGoodsList($goods);

        $res['freight'] = $s_goods_collect->freight();

        $res['goods_price'] = $s_goods_collect->goods_price();

        $res['discount_amount'] = $s_goods_collect->discount_amount();

        $res['payable_amount'] = $s_goods_collect->payable_amount();

        $res['qty'] = $s_goods_collect->qty();

        $res['goods'] = $s_goods_collect->goods(function ($row) {
            return [
                'qty' => $row->qty(),
                'spec' => $row->spec(),
                'goods_price' => $row->selling_price(),
                'title' => $row->model()->title,
                'cover_picture' => $row->model()->cover_picture,
                'id' => $row->model()->id,
            ];
        });

        $res['can_use_coupons'] = $this->userCanUseCoupon($s_goods_collect);

        $res['coupon_id'] = $s_goods_collect->coupon_id;

        $res['address_id'] = $s_goods_collect->address_id;

        return $this->response->array(['data' => $res]);
    }

    private function userCanUseCoupon($s_goods_collect)
    {
        $user = \Auth()->user();

        $query = $user->coupons();

        $coupons = $query->available()->get();

        $canUseCoupon = $coupons->filter(function ($item) use ($s_goods_collect) {
            try {
                $order_coupon = new OrderCouponService($item);

                $order_coupon->setUID('');

                $order_coupon->setTotal($s_goods_collect->goods_price());

                if ($order_coupon->canUseCoupon()) {
                    return true;
                } else {
                    return false;
                }
            } catch (\Exception $e) {
                return false;
            }
        });

        return $canUseCoupon->map(function ($item) {
            return (new UserCouponTransformer())->transform($item);
        });
    }

    /**
     * 订单物流信息
     *
     * @OA\Get(
     *     tags={"订单"},
     *     summary="订单物流",
     *     path="/api/orders/{order_id}/logistics",
     *     security={
     *         {"jwt_auth": {}}
     *     },
     *     @OA\Parameter(
     *         name="order_id",
     *         in="path",
     *         description="订单id",
     *         required=true,
     *         @OA\Schema(
     *             type="integer",
     *         )
     *     ),
     *     @OA\Response(
     *          response="200",
     *          description="成功",
     *          @OA\MediaType(
     *             mediaType="application/json",
     *              @OA\Schema(
     *                  type="object",
     *                  @OA\Property(
     *                      property="data",
     *                      type="array",
     *                      @OA\Items(),
     *                      description="物流信息"
     *                  ),
     *              )
     *          )
     *      )
     * )
     */
    public function logistics($order_id)
    {
        $info = Order::findOrFail($order_id);

        if ($info->express_id) {
            $res = ExpressService::query($info->express->code, $info->tracking_no);
            $res['name'] = $info->express->name;
            $res['telephone'] = $info->express->telephone;
            $res['logo'] = $info->express->Base64Logo;
        } else {
            $res = [];
        }

        return $this->response->array(['data' => $res]);
    }
}
