package com.fs.app.controller;

import cn.hutool.core.util.ObjectUtil;
import com.fs.app.annotation.Login;
import com.fs.common.annotation.RepeatSubmit;

import com.fs.common.core.domain.R;
import com.fs.common.exception.CustomException;
import com.fs.store.domain.*;
import com.fs.store.dto.FsStoreOrderComputeDTO;

import com.fs.store.param.*;
import com.fs.store.service.*;
import com.fs.store.vo.FsMyStoreOrderListQueryVO;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;


@Api("商城接口")
@RestController
@RequestMapping(value="/app/storeOrder")
public class StoreOrderController extends  AppBaseController {

    Logger logger= LoggerFactory.getLogger(getClass());

    @Autowired
    private IFsStoreOrderService orderService;
    @Autowired
    private IFsStoreAfterSalesService afterSalesService;

    @Autowired
    private IFsStorePaymentService fsStorePaymentService;


    @Login
    @ApiOperation("获取我的订单列表")
    @GetMapping("/getMyStoreOrderList")
        public R getMyStoreOrderList(FsMyStoreOrderQueryParam param){
        PageHelper.startPage(param.getPage(), param.getPageSize());
        param.setUserId(Long.parseLong(getUserId()));
        List<FsMyStoreOrderListQueryVO> list=orderService.selectFsMyStoreOrderListVO(param);
        PageInfo<FsMyStoreOrderListQueryVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("获取销售公司订单列表")
    @GetMapping("/getCompanyStoreOrderList")
    public R getCompanyStoreOrderList(FsMyStoreOrderQueryParam param){
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<FsMyStoreOrderListQueryVO> list=orderService.selectFsCompanyStoreOrderListVO(param);
        PageInfo<FsMyStoreOrderListQueryVO> listPageInfo=new PageInfo<>(list);
        return R.ok().put("data",listPageInfo);
    }

    @Login
    @ApiOperation("获取我的订单详情")
    @GetMapping("/getMyStoreOrderById")
    public R getMyStoreOrderById(@RequestParam(value = "orderId",required = false) Long orderId,
                                 @RequestParam(value = "orderCode",required = false) String orderCode){
        logger.info("获取我的订单详情, 订单ID: {}", orderId);
        if(ObjectUtil.isEmpty(orderId) && ObjectUtil.isEmpty(orderCode)){
            throw new CustomException("订单ID和订单号不能同时为空");
        }
        return orderService.getMyStoreOrderByIdOrOrderCode(orderId,orderCode);
    }

    @Login
    @ApiOperation("获取订单")
    @GetMapping("/getStoreOrderById")
    public R getStoreOrderById(@RequestParam("orderId") Long orderId){
        logger.info("开始处理获取订单请求, 订单ID: {}", orderId);
        return orderService.getStoreOrderById(orderId);
    }

    @Login
    @ApiOperation("获取订单-轮询获取信息")
    @GetMapping("/getStoreOrderByOrderIdTz")
    public R getStoreOrderByIdRemote(@RequestParam(value = "orderId",required = false) Long orderId,
                                     @RequestParam(value = "payCode",required = false) String payCode){
        logger.info("获取订单-轮询获取信息, 订单ID: {}, payCode: {}", orderId,payCode);
        return orderService.getStoreOrderByOrderIdTz(orderId,payCode);
    }


    @Login
    @ApiOperation("确认订单")
    @PostMapping("/confirm")
    public R confirm(@Validated @RequestBody FsStoreConfirmOrderParam param){
        logger.info("开始处理确认订单请求, 订单ID: {}", param);

        return orderService.confirmOrder(Long.parseLong(getUserId()),param);
    }
    @Login
    @ApiOperation("计算订单金额")
    @PostMapping("/computed")
    public R computed(@Validated @RequestBody FsStoreOrderComputedParam param){
        logger.info("开始处理计算订单金额请求, 参数: {}", param);

        FsStoreOrderComputeDTO dto=orderService.computedOrder(Long.parseLong(getUserId()),param);
        return R.ok().put("data",dto);
    }

    @Login
    @ApiOperation("创建订单")
    @PostMapping("/create")
    @RepeatSubmit(intervalTime = 3)
    public R create(@Validated @RequestBody FsStoreOrderCreateParam param){
        logger.info("开始处理创建订单请求, 参数: {}", param);

        return orderService.createOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("支付")
    @PostMapping("/pay")
    @RepeatSubmit(intervalTime = 10)
    public R pay(@Validated @RequestBody FsStoreOrderPayParam param)
    {
        logger.info("开始处理支付请求, 订单号: {}, 支付类型: {}", param.getOrderId(), param.getPayType());
        R result = null;
        try {
            result = orderService.pay(param);
        } catch (Throwable e) {
            logger.error("支付过程中发生异常, 订单号: {}", param.getOrderId(), e);
            throw e;
        } finally {
            if (result != null) {
                logger.info("支付请求处理完成, 订单号: {}, 返回结果: {}", param.getOrderId(), result);
            } else {
                logger.info("支付请求处理完成, 订单号: {}, 返回结果为空", param.getOrderId());
            }
        }
        return result;
    }


    @Login
    @ApiOperation("修改支付类型")
    @PostMapping("/editPayType")
    public R editPayType(@Validated @RequestBody FsStoreOrderPayParam param) {
        logger.info("开始处理修改支付类型请求, 参数: {}", param);

        return orderService.editPayType(param);
    }


    @Login
    @ApiOperation("支付尾款")
    @PostMapping("/payRemain")
    public R payRemain(@Validated @RequestBody FsStoreOrderPayParam param) {
        logger.info("开始处理支付尾款请求, 参数: {}", param);

        return orderService.payRemain(param);
    }


    @Login
    @ApiOperation("亲友支付")
    @PostMapping("/otherPayment")
    public R otherPayment(@Validated @RequestBody FsStoreOrderOtherPayParam param){

        logger.info("开始处理支付请求, 订单号: {}, 支付类型: 亲友支付", param.getOrderId());
        R result = null;
        try {
            result = orderService.otherPayment(param);
        } catch (Throwable e) {
            logger.error("支付过程中发生异常, 订单号: {}", param.getOrderId(), e);
            throw e;
        } finally {
            if (result != null) {
                logger.info("支付请求处理完成, 订单号: {}, 返回结果: {}", param.getOrderId(), result);
            } else {
                logger.info("支付请求处理完成, 订单号: {}, 返回结果为空", param.getOrderId());
            }
        }
        return result;
    }

    @Login
    @ApiOperation("亲友支付")
    @PostMapping("/otherPaymentRemain")
    public R otherPaymentRemain(@Validated @RequestBody FsStoreOrderOtherPayParam param){
        return orderService.otherPaymentRemain(param);
    }


    @Login
    @ApiOperation("取消订单")
    @PostMapping("/cancelOrder")
    public R cancelOrder( @Validated @RequestBody FsStoreOrderCancelParam param){
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if (ObjectUtil.isNull(order)) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() !=0) {
            throw new CustomException("非法操作");
        }
        List<FsStorePayment> fsStorePayments = fsStorePaymentService.selectFsStorePaymentByOrderIdNew(order.getId());
        if(CollectionUtils.isNotEmpty(fsStorePayments)){
            FsStorePayment fsStorePayment = fsStorePayments.get(0);
            if(fsStorePaymentService.queryTzbk(fsStorePayment)){
                return R.error("当前订单状态不为待支付，请刷新页面!");
            }
        }
        orderService.cancelOrder(param.getOrderId());
        return R.ok("操作成功");
    }
    @Login
    @ApiOperation("物流查询")
    @PostMapping("/getExpress")
    public R getExpress( @Validated @RequestBody FsStoreOrderExpressParam param){
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if (ObjectUtil.isNull(order)) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() <2) {
            throw new CustomException("未发货订单不能查询");
        }

        return orderService.getExpress(order);
    }


    @Login
    @ApiOperation("物流查询多运单号")
    @PostMapping("/getExpressMulti")
    public R getExpressMulti( @Validated @RequestBody FsStoreOrderExpressParam param){
        FsStoreOrder order=orderService.selectFsStoreOrderById(param.getOrderId());
        if (ObjectUtil.isNull(order)) {
            throw new CustomException("订单不存在");
        }
        if (order.getStatus() <2) {
            throw new CustomException("未发货订单不能查询");
        }
        return orderService.getExpressMulti(order);
    }


    @Login
    @ApiOperation("确认套餐订单")
    @PostMapping("/confirmPackageOrder")
    public R confirmPackageOrder(@Validated @RequestBody FsStoreConfirmPackageIdOrderParam param){
        return orderService.confirmPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("计算套餐订单")
    @PostMapping("/computedPackageOrder")
    public R computedPackageOrder(@Validated @RequestBody FsStoreComputedPackageIdOrderParam param){
        return orderService.computedPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("创建订单")
    @PostMapping("/createPackageOrder")
    @RepeatSubmit(intervalTime = 3)
    public R createPackageOrder(@Validated @RequestBody FsStorePackageOrderCreateParam param){
        return orderService.createPackageOrder(Long.parseLong(getUserId()),param);
    }

    @Login
    @ApiOperation("完成订单")
    @PostMapping("/finishOrder")
    public R finishOrder( @Validated @RequestBody FsStoreOrderFinishParam param){
        return orderService.finishOrder(param.getOrderId());
    }


    @Login
    @ApiOperation("获取订单总数")
    @GetMapping("/getOrderCount")
    public R getOrderCount(){
        Integer count0=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),0);
        Integer count1=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),1);
        Integer count2=orderService.selectFsStoreOrderCount(Long.parseLong(getUserId()),2);
        Integer afterSalesCount=afterSalesService.selectFsStoreAfterSalesCount(Long.parseLong(getUserId()),0);
        return R.ok().put("count0",count0).put("count1",count1).put("count2",count2).put("afterSalesCount",afterSalesCount);
    }

}
