package com.sqx.modules.errand.controller.app;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.PageUtils;
import com.sqx.common.utils.Result;
import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.entity.queryRiderVo;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.errand.dto.OrderRiderDeliveryDTO;
import com.sqx.modules.errand.dto.RiderDeliveryDTO;
import com.sqx.modules.errand.dto.RiderTransferByOrderIdDTO;
import com.sqx.modules.errand.dto.RiderTransferOrderDTO;
import com.sqx.modules.errand.dto.RiderTransferOrdersDTO;
import com.sqx.modules.errand.dto.WaitForAcceptOrderQueryDTO;
import com.sqx.modules.errand.entity.ErrandAddress;
import com.sqx.modules.errand.entity.ErrandComplaint;
import com.sqx.modules.errand.entity.ErrandEvaluate;
import com.sqx.modules.errand.entity.ErrandRedPacket;
import com.sqx.modules.errand.entity.TbIndent;
import com.sqx.modules.errand.entity.TransferRecordEntity;
import com.sqx.modules.errand.service.ErrandComplaintService;
import com.sqx.modules.errand.service.TbIndentService;
import com.sqx.modules.errand.service.TransferRecordService;
import com.sqx.modules.errand.vo.queryOrderInfoVo;
import icu.xuyijie.secureapi.annotation.DecryptParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/app/tbindent")
@Api(value = "订单", tags = {"订单"})
@Slf4j
public class AppTbIndentController {
    @Autowired
    private TransferRecordService transferRecordService;
    @Autowired
    private TbIndentService tbIndentService;
    @Autowired
    private CommonInfoService commonInfoService;
    @Autowired
    private ErrandComplaintService errandComplaintService;

    @Login
    @PostMapping(value = "distance")
    @ApiOperation("根据经纬度计算两点之间距离")
    public Result distance(double ol, double od, double dl, double dd) {

        return tbIndentService.distance(ol, od, dl, dd);
    }

    @Login
    @ApiOperation("保存用户输入地址")
    @PostMapping(value = "addUserAddress")
    public Result addUserAddress(@RequestAttribute Long userId, @RequestBody ErrandAddress errandAddress) {

        return tbIndentService.addUserAddress(userId, errandAddress);
    }

    @Login
    @ApiOperation("编辑地址")
    @PostMapping(value = "updateAddress")
    public Result updateAddress(@RequestAttribute Long userId, @RequestBody ErrandAddress errandAddress) {

        return tbIndentService.updateAddress(userId, errandAddress);
    }

    @Login
    @ApiOperation("获取用户历史地址")
    @GetMapping(value = "findUserAddress")
    public Result findUserAddress(@RequestAttribute Long userId) {

        return tbIndentService.findUserAddress(userId);
    }

    @Login
    @ApiOperation("根据地址id获取地址信息")
    @GetMapping(value = "findAddressById")
    public Result findAddressById(@RequestAttribute Long userId, Integer addressId) {

        return tbIndentService.findAddressById(userId, addressId);
    }

    @Login
    @ApiOperation("设置默认地址")
    @GetMapping(value = "addDefaultAddress")
    private Result addDefaultAddress(@RequestAttribute Long userId, Integer addressId) {

        return tbIndentService.addDefaultAddress(userId, addressId);
    }

    @Login
    @ApiOperation("删除历史地址")
    @GetMapping(value = "delUserAddress")
    public Result delUserAddress(@RequestAttribute Long userId, Integer addressId) {

        return tbIndentService.delUserAddress(userId, addressId);
    }

    @Login
    @ApiOperation("获取订单起点附近5公里内所有骑手")
    @GetMapping(value = "find5KmRider")
    public Result find5KmRider(double lng, double lat) {

        return tbIndentService.find5KmRider(lng, lat);
    }

    @Login
    @ApiOperation("骑手上线时更新骑手坐标")
    @PostMapping(value = "updateCoordinate")
    public Result updateCoordinate(@RequestAttribute Long userId, double lng, double lat) {

        return tbIndentService.updateCoordinate(userId, lng, lat);
    }


    @Login
    @GetMapping(value = "/findUserInfoById")
    @ApiOperation("获取登陆用户信息")
    public Result findUserInfoById(@RequestAttribute("userId") Long userId) {
        UserEntity userEntity = tbIndentService.findUserInfoById(userId);

        return Result.success().put("data", userEntity);
    }

    @Login
    @ApiOperation("新用户领取新人红包")
    @GetMapping(value = "getNewUserRedPacket")
    public Result getNewUserRedPacket(@RequestAttribute Long userId) {

        return tbIndentService.getNewUserRedPacket(userId);
    }

    @Login
    @GetMapping(value = "findAllRedPacket")
    @ApiOperation("获取该用户的所有红包")
    public Result findAllRedPacket(@RequestAttribute Long userId) {
        List<ErrandRedPacket> allRedPacket = tbIndentService.findAllRedPacket(userId);
        return Result.success().put("data", allRedPacket);
    }

    @Login
    @PostMapping(value = "findRedPacket")
    @ApiOperation("获取用户可用红包")
    public Result findRedPacket(@RequestAttribute Long userId, @RequestBody TbIndent indent) {
        List<ErrandRedPacket> redPackets = tbIndentService.findRedPacket(userId, indent);
        return Result.success().put("data", redPackets);
    }

    @Login
    @PostMapping(value = "basicsMoney")
    @ApiOperation("计算订单基础价格")
    public Result basicsMoney(@RequestBody TbIndent tbIndent) {

        return Result.success().put("data", tbIndentService.basicsMoney(tbIndent));
    }

    @Login
    @PostMapping(value = "addIndent")
    @ApiOperation("用户下单")
    public Result addIndentBuy(@RequestAttribute Long userId, @RequestBody TbIndent tbIndent) {
        tbIndent.setUserId(userId);
        return tbIndentService.addIndentBuy(tbIndent);
    }

    @Login
    @PostMapping(value = "findNewIndent")
    @ApiOperation("骑手查看可接订单")
    public Result findNewIndent(@RequestAttribute Long userId, @RequestBody TbIndent tbIndent) {
        String receivingPettern = tbIndent.getReceivingPettern();
        double riderlat = tbIndent.getRiderlat();
        double riderlng = tbIndent.getRiderlng();
        Integer page = tbIndent.getPage();
        Integer limit = tbIndent.getLimit();
        String indentType = tbIndent.getIndentType();
        String buyType = tbIndent.getBuyType();
        return tbIndentService.findNewIndent(userId, receivingPettern, page, limit, riderlng, riderlat, indentType, buyType);
    }

    @Login
    @PostMapping(value = "find-new-indent")
    @ApiOperation("骑手查看可接订单(新)")
    public Result findNewIndent(@Valid @RequestBody WaitForAcceptOrderQueryDTO queryDTO) {
        PageUtils newIndent = tbIndentService.findNewIndent(queryDTO);
        return Result.success().put("data", newIndent);
    }

    @Login
    @PostMapping(value = "find-new-indent-group-by-shop")
    @ApiOperation("骑手查看可接订单(按商家分组)")
    public Result findNewIndentGroupByShop(@Valid @RequestBody WaitForAcceptOrderQueryDTO queryDTO) {
        PageUtils newIndent = tbIndentService.findNewIndentGroupByShop(queryDTO);
        return Result.success().put("data", newIndent);
    }

    @Login
    @PostMapping(value = "indentReceiving")
    @ApiOperation("骑手接单")
    public Result indentReceiving(@RequestAttribute Long userId, String indentNumber) {

        return tbIndentService.indentReceiving(userId, indentNumber);
    }

    @Login
    @PostMapping(value = "riderBuyGoods")
    @ApiOperation("骑手修改订单状态")
    public Result riderBuyGoods(@RequestBody TbIndent tbIndent) {

        return tbIndentService.riderBuyGoods(tbIndent);
    }

    @Login
    @GetMapping(value = "findUserIndent")
    @ApiOperation("用户查看自己所有订单（全部、待付款、待接单、派送中（已接单未完成）、已完成）")
    public Result findUserIndent(@RequestAttribute Long userId, Integer page, Integer limit, String indentState) {

        return tbIndentService.findUserIndent(userId, page, limit, indentState);
    }


    @PostMapping(value = "userIndentMessage")
    @ApiOperation("用户查看订单详情")
    public Result userIndentMessage(String indentNumber) {
        TbIndent indent = tbIndentService.userIndentMessage(indentNumber);
        return Result.success().put("data", indent);
    }

    @Login
    @PostMapping(value = "userCancleIndent")
    @ApiOperation("用户取消订单")
    public Result userCancleIndent(@RequestAttribute Long userId, String indentNumber) {

        return tbIndentService.userCancleIndent(userId, indentNumber);
    }

    @Login
    @GetMapping(value = "findRiderIndent")
    @ApiOperation("骑手查看自己所有订单")
    public Result findRiderIndent(@RequestAttribute Long userId, Integer page, Integer limit, String indentState, String keyword) {

        return tbIndentService.findRiderIndent(userId, page, limit, indentState, keyword);
    }

    @Login
    @GetMapping(value = "findRiderIndentByIds")
    @ApiOperation("骑手查看待转单订单")
    public Result findRiderIndentByIds(@RequestAttribute Long userId, Integer page, Integer limit, String indentIds) {
        if (StringUtils.isEmpty(indentIds)) {
            IPage<queryOrderInfoVo> pages = new Page<>();
            PageUtils pageUtils = new PageUtils(pages);
            return Result.success().put("data", pageUtils);
        }
        List<String> result = Arrays.asList(indentIds.split(","));
        return tbIndentService.findRiderIndentByIds(userId, page, limit, result);
    }

    @Login
    @PostMapping(value = "indentMessage")
    @ApiOperation("骑手查看订单详情")
    public Result indentMessage(String indentNumber, double ol, double od) {
        TbIndent tbIndent = tbIndentService.indentMessage(indentNumber, ol, od);
        return Result.success().put("data", tbIndent);
    }

    @PostMapping(value = "indentMessageByOrderId")
    @ApiOperation("骑手查看订单详情")
    public Result indentMessageByOrderId(Long orderId, double ol, double od) {
        TbIndent tbIndent = tbIndentService.indentMessageByOrderId(orderId, ol, od);
        return Result.success().put("data", tbIndent);
    }

    @Login
    @PostMapping(value = "riderCancleIndent")
    @ApiOperation("骑手取消订单")
    public Result riderCancleIndent(String indentNumber) {
        return tbIndentService.riderCancleIndent(indentNumber, 1);
    }

    //骑手已送达
    @Login
    @PostMapping(value = "riderDelivery")
    @ApiOperation("骑手已送达")
    public Result riderDelivery(@RequestAttribute Long userId, @Valid @RequestBody RiderDeliveryDTO riderDeliveryDTO) {

        return tbIndentService.riderDelivery(userId, riderDeliveryDTO);
    }

    @Login
    @PutMapping(value = "delivery-img/{indentNumber}")
    @ApiOperation("骑手上传送达照片")
    public Result riderUploadDeliveryImg(@RequestAttribute Long userId, @PathVariable @ApiParam("跑腿订单id") String indentNumber, @DecryptParam @ApiParam("图片地址") String imgs) {
        tbIndentService.riderUploadDeliveryImg(userId, indentNumber, imgs);
        return Result.success();
    }

    //用户确认已送达
    @Login
    @PostMapping(value = "userDelivery")
    @ApiOperation("用户确认已送达")
    public Result userDelivery(@RequestAttribute Long userId, String indentNumber) {

        return tbIndentService.userDelivery(userId, indentNumber);
    }

    @Login
    @PostMapping(value = "userEvaluate")
    @ApiOperation("用户评价（评价等级和内容）")
    public Result userEvaluate(@RequestAttribute Long userId, @RequestBody ErrandEvaluate errandEvaluate) {
        errandEvaluate.setUserId(userId);
        return tbIndentService.userEvaluate(errandEvaluate);
    }

    @ApiOperation("用户投诉订单")
    @PostMapping(value = "insertComplaint")
    public Result insertComplaint(@RequestBody ErrandComplaint errandComplaint) {

        return errandComplaintService.insertComplaint(errandComplaint);
    }

    @Login
    @ApiOperation("用户查看所有投诉")
    @GetMapping(value = "selectComplaint")
    public Result selectComplaint(@RequestAttribute Long userId, Integer page, Integer limit) {

        return errandComplaintService.selectComplaint(userId, page, limit);
    }

    @Login
    @GetMapping(value = "findAllComplaint")
    @ApiOperation("骑手查看自己的所有被投诉")
    public Result findAllComplaint(@RequestAttribute Long userId, Integer illegalId, Integer complaintState, Integer page, Integer limit) {

        return errandComplaintService.findAllComplaint(userId, illegalId, complaintState, page, limit);
    }

    @Login
    @GetMapping(value = "findComplaint")
    @ApiOperation("骑手查看被投诉内容")
    public Result findComplaint(@RequestAttribute Long userId, Long complaintId) {

        return errandComplaintService.findComplaint(userId, complaintId);
    }

    @Login
    @PostMapping(value = "appealIndent")
    @ApiOperation("骑手提交申诉")
    public Result appealIndent(@RequestAttribute Long userId, @RequestBody ErrandComplaint errandComplaint) {

        return errandComplaintService.appealIndent(userId, errandComplaint);
    }

    @Autowired
    private UserService userService;


    @Login
    @ApiOperation("转单")
    @PostMapping("/transferOfOrder")
    public Result transferOfOrder(@RequestAttribute Long userId, @Valid RiderTransferOrderDTO transferOrderDTO) {
        log.info("测试是否进入转单");
        // 检查入参
        checkTransferOrderParam(transferOrderDTO);

        log.info("测试是否进入转单1");
        tbIndentService.transferOfOrder(userId, transferOrderDTO);
        log.info("测试是否进入转单2");
        return Result.success();
    }

    @Login
    @ApiOperation("批量转单")
    @PostMapping("/transferOfOrders")
    public Result transferOfOrders(@RequestAttribute Long userId, @RequestBody RiderTransferOrdersDTO transferOrderDTO) {
        if (userId.equals(transferOrderDTO.getRiderId())) {
            throw new SqxException("不能转单给自己！");
        }
        //查看被转单骑手是否符合条件
        queryRiderVo riderUser = tbIndentService.getNewRicherCheck(transferOrderDTO.getRiderId());
        if(riderUser == null){
            throw new SqxException("被转单骑手已失效");
        }

        //先查一遍订单 防止存在无效订单
        List<TbIndent> datas = tbIndentService.findIndentsByIds(transferOrderDTO.getIndentIds());
        for (TbIndent data : datas) {
            if (!data.getRiderUserId().equals(userId)) {
                throw new SqxException("不能操作非自己的订单");
            }

            if (!"3".equals(data.getIndentState()) && !"4".equals(data.getIndentState())) {
                throw new SqxException("订单状态发生变更，请刷新后重试！");
            }

            // 开始转单
            data.setRiderUserId(transferOrderDTO.getRiderId());
            data.setIsRider(1);
        }

        boolean transferOrders = tbIndentService.updateBatchById(datas);
        if(transferOrders){
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            List<TransferRecordEntity> trs = new ArrayList<>();
            for (TbIndent data : datas) {
                TransferRecordEntity tr = new TransferRecordEntity();
                tr.setUserId(riderUser.getUserId());
                tr.setUserName(riderUser.getUserName());
                tr.setUserPhone(riderUser.getPhone());
                tr.setOrderId(data.getOrderId());
                tr.setReceveTime(format);
                tr.setStationName(riderUser.getStationName());
                tr.setDeleteFlag(0);
                trs.add(tr);
                // 消息通知
                tbIndentService.noticeAfterTransfer(data,riderUser);
            }
            if(trs != null && trs.size() > 0){
                boolean result = transferRecordService.insertBatchPrintInfo(trs);
                if(!result){
                    log.info("转单记录新增失败："+ JSONUtil.toJsonStr(trs));
                }
            }
        }else{
            log.info("转单操作失败："+ JSONUtil.toJsonStr(datas));
        }

        return Result.success();
    }

    @ApiOperation("获取骑手工作时间段及时效信息")
    @GetMapping("work-time")
    public Result getWorkTime() {
        String workingHoursOfRider = commonInfoService.findOne(422).getValue();
        String timeOfRider = commonInfoService.findOne(423).getValue();

        Map<String, String> data = new HashMap<>();
        data.put("workingHoursOfRider", workingHoursOfRider);
        data.put("timeOfRider", timeOfRider);

        return Result.success().put("data", data);
    }

    @GetMapping("get-by-code/{code}")
    @ApiOperation("根据收单码查询订单")
    public Result getByCode(@PathVariable String code) {
        TbIndent indent = tbIndentService.getByOrderId(code);
        return Result.success().put("data", indent);
    }

    @Login
    @PutMapping(value = "receive/{code}")
    @ApiOperation("根据扫码或收单码接单")
    public Result receiveOrder(@RequestAttribute Long userId, @PathVariable String code) {
        return tbIndentService.orderIndentReceiving(userId, code);
    }

    @Login
    @PostMapping(value = "finish-order")
    @ApiOperation("骑手完成订单")
    public Result riderFinishOrder(@RequestAttribute Long userId, @Valid @RequestBody OrderRiderDeliveryDTO orderRiderDeliveryDTO) {
        return tbIndentService.orderRiderDelivery(userId, orderRiderDeliveryDTO);
    }

    //region 2024-09-12 A-jax 添加接口
    //region 1、根据订单id查询跑腿订单的信息；
    // TODO 以下三个接口待删除
    @Login
    @GetMapping("selectTbIndentPage")
    @ApiOperation("扫码或收单码查询跑腿订单列表（带分页")
    public Result selectMemberPage(@RequestAttribute Long userId, Integer page, Integer limit, String acquireCode) {
        if (StrUtil.isBlank(acquireCode)) {
            throw new SqxException("请输入正确的扫码或收单码");
        }
        //如果只有一条数据就看看数据是否能被当前骑手接
        PageUtils datas = tbIndentService.selectIndentPage(page, limit, acquireCode, userId);
        return Result.success().put("data", datas);
    }
    //endregion

    //region 2、根据订单id抢单（跑腿订单） 以及取货按钮功能；
    @Login
    @PostMapping(value = "orderIndentReceiving")
    @ApiOperation("骑手根据扫码或收单码接单")
    public Result orderIndentReceiving(@RequestAttribute Long userId, String acquireCode) {
        return tbIndentService.orderIndentReceiving(userId, acquireCode);
    }
    //endregion

    //region 3、根据订单id完成跑腿订单。
    @Login
    @PostMapping(value = "orderRiderDelivery")
    @ApiOperation("骑手根据扫码或收单码完成订单")
    public Result orderRiderDelivery(@RequestAttribute Long userId, @Valid @RequestBody OrderRiderDeliveryDTO orderRiderDeliveryDTO) {
        return tbIndentService.orderRiderDelivery(userId, orderRiderDeliveryDTO);
    }
    //endregion

    //region 转单
    @Login
    @ApiOperation("根据订单ID进行转单操作")
    @PostMapping("transferByOrderId")
    public Result transferByOrderId(@RequestAttribute Long userId, @Valid RiderTransferByOrderIdDTO transferByOrderIdDTO) {
        // 检查入参
        checkTransferByOrderIdParam(transferByOrderIdDTO);

        tbIndentService.transferByOrderId(userId, transferByOrderIdDTO);

        return Result.success();
    }

    private void checkTransferByOrderIdParam(RiderTransferByOrderIdDTO transferOrderDTO) {
        if (StringUtils.isBlank(transferOrderDTO.getPhone()) && StringUtils.isBlank(transferOrderDTO.getRealName())) {
            throw new SqxException("待分配骑手手机号和待分配骑手真实姓名不能同时为空");
        }
    }

    private void checkTransferOrderParam(RiderTransferOrderDTO transferOrderDTO) {
        if (StringUtils.isBlank(transferOrderDTO.getPhone()) && StringUtils.isBlank(transferOrderDTO.getRealName())) {
            throw new SqxException("待分配骑手手机号和待分配骑手真实姓名不能同时为空");
        }
    }
    //endregion
    //endregion
}
