package com.qs.mp.web.controller.api.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.qs.mp.admin.domain.TicketBox;
import com.qs.mp.admin.domain.excel.UserTicketOrderExcel;
import com.qs.mp.admin.domain.excel.UserTicketOrderItemExcel;
import com.qs.mp.admin.domain.param.UserTicketOrderQueryParam;
import com.qs.mp.admin.domain.vo.UserTicketOrderDetailVO;
import com.qs.mp.admin.domain.vo.UserTicketOrderItemVO;
import com.qs.mp.admin.domain.vo.UserTicketOrderListVO;
import com.qs.mp.admin.service.ITicketBoxService;
import com.qs.mp.common.annotation.Log;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.page.TableDataInfo;
import com.qs.mp.common.enums.BusinessType;
import com.qs.mp.common.enums.PayOrderStatusEnum;
import com.qs.mp.common.enums.TicketPrizeTypeEnum;
import com.qs.mp.common.enums.UserTicketOrderStatusEnum;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.system.domain.SysUser;
import com.qs.mp.system.service.ISysUserService;
import com.qs.mp.user.domain.UserTicketOrder;
import com.qs.mp.user.domain.UserTicketOrderItem;
import com.qs.mp.user.domain.excel.DeliverOrderExcel;
import com.qs.mp.user.domain.vo.UserDeliverOrderItemVO;
import com.qs.mp.user.domain.vo.UserDeliverOrderVO;
import com.qs.mp.user.service.IUserTicketOrderItemService;
import com.qs.mp.user.service.IUserTicketOrderService;
import com.qs.mp.utils.ExcelUtil;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Cup
 * @date 2022/5/6
 */
@RestController
@RequestMapping("/api/v1/mp/admin/ticket/order")
@Api(tags = "用户盲票订单接口")
public class UserTicketOrderMgrController extends BaseApiController {


    @Autowired
    private IUserTicketOrderService userTicketOrderService;


    @Autowired
    private IUserTicketOrderItemService userTicketOrderItemService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ITicketBoxService ticketBoxService;

    @PostMapping("/list")
    @PreAuthorize("@ss.hasPermi('order:userTicket:list')")
    @ApiOperation("用户盲票订单列表")
    @ApiResponses(
            @ApiResponse(code = 200, message = "成功", response = UserTicketOrderListVO.class)
    )
    public TableDataInfo list(@RequestBody UserTicketOrderQueryParam userTicketOrderQueryParam) {

        LambdaQueryWrapper<UserTicketOrder> userTicketOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getBoxTitle())) {
            userTicketOrderLambdaQueryWrapper.like(UserTicketOrder::getTitle, userTicketOrderQueryParam.getBoxTitle());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStatus())) {
            userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getStatus, userTicketOrderQueryParam.getStatus());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStartTime()) && Objects.nonNull(userTicketOrderQueryParam.getEndTime())) {
            userTicketOrderLambdaQueryWrapper.between(UserTicketOrder::getCreatedTime, userTicketOrderQueryParam.getStartTime(), userTicketOrderQueryParam.getEndTime());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getChannelId()) && userTicketOrderQueryParam.getChannelId() != 0) {
            userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getChannelId, userTicketOrderQueryParam.getChannelId());
        }
        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getPhone())) {
            SysUser sysUser = sysUserService.selectUserByPhoneNumber(userTicketOrderQueryParam.getPhone());
            if (sysUser != null) {
                userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getUserId, sysUser.getUserId());
            }
        }

        if (Objects.nonNull(userTicketOrderQueryParam.getBoxType())) {
            List<TicketBox> ticketBoxList = ticketBoxService.list(new LambdaQueryWrapper<TicketBox>().eq(TicketBox::getType, userTicketOrderQueryParam.getBoxType()));
            if (CollectionUtils.isNotEmpty(ticketBoxList)) {
                List<String> boxIds = ticketBoxList.stream().map(TicketBox::getBoxId).collect(Collectors.toList());
                userTicketOrderLambdaQueryWrapper.in(UserTicketOrder::getBoxId, boxIds);
            }
        }

        userTicketOrderLambdaQueryWrapper.orderByDesc(UserTicketOrder::getCreatedTime);

        startPage();
        List<UserTicketOrder> userTicketOrderList = userTicketOrderService.list(userTicketOrderLambdaQueryWrapper);


        if (CollectionUtils.isNotEmpty(userTicketOrderList)) {
            List<String> orderIds = userTicketOrderList.stream().map(UserTicketOrder::getOrderId).collect(Collectors.toList());
            QueryWrapper<UserTicketOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("t1.order_id",orderIds);
            queryWrapper.orderByDesc("t1.created_time");
            List<UserTicketOrderListVO> list = userTicketOrderService.listUserTicketOrder(queryWrapper);
            TableDataInfo dataTable = getDataTable(userTicketOrderList);
            dataTable.setRows(list);
            return dataTable;
        }
        return getDataTable(userTicketOrderList);
    }

    @PostMapping("/detail/{orderId}")
    @PreAuthorize("@ss.hasPermi('order:userTicket:query')")
    @ApiOperation("用户盲票订单详情")
    @ApiResponses(
            @ApiResponse(code = 200, message = "成功", response = UserTicketOrderDetailVO.class)
    )
    public AjaxResult detail(@PathVariable("orderId") String orderId) {

        return AjaxResult.success(userTicketOrderService.detail(orderId));
    }

    @Log(title = "用户订单导出", businessType = BusinessType.EXPORT)
    @PostMapping("export")
    @PreAuthorize("@ss.hasPermi('order:userTicket:export')")
    @ApiOperation("用户订单导出")
    public AjaxResult export(@RequestBody UserTicketOrderQueryParam userTicketOrderQueryParam) {

        // 导出时间范围限制校验
        Date startTime = userTicketOrderQueryParam.getStartTime();
        Date endTime = userTicketOrderQueryParam.getEndTime();
        if (startTime == null || endTime == null) {
            return AjaxResult.error("导出数据必须设置日期范围");
        }
        if (DateUtils.diff(startTime, endTime) > 30) {
            return AjaxResult.error("导出的数据不能超过31天");
        }



        LambdaQueryWrapper<UserTicketOrder> userTicketOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getBoxTitle())) {
            userTicketOrderLambdaQueryWrapper.like(UserTicketOrder::getTitle, userTicketOrderQueryParam.getBoxTitle());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStatus())) {
            userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getStatus, userTicketOrderQueryParam.getStatus());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStartTime()) && Objects.nonNull(userTicketOrderQueryParam.getEndTime())) {
            userTicketOrderLambdaQueryWrapper.between(UserTicketOrder::getCreatedTime, userTicketOrderQueryParam.getStartTime(), userTicketOrderQueryParam.getEndTime());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getChannelId()) && userTicketOrderQueryParam.getChannelId() != 0) {
            userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getChannelId, userTicketOrderQueryParam.getChannelId());
        }
        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getPhone())) {
            SysUser sysUser = sysUserService.selectUserByPhoneNumber(userTicketOrderQueryParam.getPhone());
            if (sysUser != null) {
                userTicketOrderLambdaQueryWrapper.eq(UserTicketOrder::getUserId, sysUser.getUserId());
            }
        }

        if (Objects.nonNull(userTicketOrderQueryParam.getBoxType())) {
            List<TicketBox> ticketBoxList = ticketBoxService.list(new LambdaQueryWrapper<TicketBox>().eq(TicketBox::getType, userTicketOrderQueryParam.getBoxType()));
            if (CollectionUtils.isNotEmpty(ticketBoxList)) {
                List<String> boxIds = ticketBoxList.stream().map(TicketBox::getBoxId).collect(Collectors.toList());
                userTicketOrderLambdaQueryWrapper.in(UserTicketOrder::getBoxId, boxIds);
            }
        }

        userTicketOrderLambdaQueryWrapper.orderByDesc(UserTicketOrder::getCreatedTime);

        int totalSize = userTicketOrderService.count(userTicketOrderLambdaQueryWrapper);
        if (totalSize == 0) {
            return AjaxResult.error("没有符合条件的用户订单");
        }

        int pageSize = 2000;
        List<UserTicketOrderListVO> userTicketOrderListVOList = new ArrayList<>();
        if (totalSize > pageSize) {
            int totalPage = totalSize % pageSize == 0 ? totalSize / pageSize : totalSize / pageSize + 1;
            for (int i = 0; i < totalPage; i++) {
                userTicketOrderLambdaQueryWrapper.last("limit " + (i * pageSize) + ", " + pageSize);
                List<UserTicketOrder> userTicketOrderList = userTicketOrderService.list(userTicketOrderLambdaQueryWrapper);
                if (CollectionUtils.isNotEmpty(userTicketOrderList)) {
                    List<String> orderIds = userTicketOrderList.stream().map(UserTicketOrder::getOrderId).collect(Collectors.toList());
                    QueryWrapper<UserTicketOrder> queryWrapper = new QueryWrapper<>();
                    queryWrapper.in("t1.order_id",orderIds);
                    queryWrapper.orderByDesc("t1.created_time");
                    List<UserTicketOrderListVO> list = userTicketOrderService.listUserTicketOrder(queryWrapper);
                    userTicketOrderListVOList.addAll(list);
                }
            }
        } else {
            List<UserTicketOrder> userTicketOrderList = userTicketOrderService.list(userTicketOrderLambdaQueryWrapper);
            if (CollectionUtils.isNotEmpty(userTicketOrderList)) {
                List<String> orderIds = userTicketOrderList.stream().map(UserTicketOrder::getOrderId).collect(Collectors.toList());
                QueryWrapper<UserTicketOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("t1.order_id", orderIds);
                queryWrapper.orderByDesc("t1.created_time");
                userTicketOrderListVOList = userTicketOrderService.listUserTicketOrder(queryWrapper);
            }
        }

        List<UserTicketOrderExcel> excelList = userTicketOrderListVOList.stream().map(userTicketOrderListVO -> {
            UserTicketOrderExcel userTicketOrderExcel = new UserTicketOrderExcel();
            BeanUtils.copyProperties(userTicketOrderListVO, userTicketOrderExcel);
            if (Objects.nonNull(userTicketOrderListVO.getSalePrice())) {
                userTicketOrderExcel.setSalePrice(new BigDecimal(userTicketOrderListVO.getSalePrice()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }
            if (Objects.nonNull(userTicketOrderListVO.getDiscountAmt())) {
                userTicketOrderExcel.setDiscountAmt(new BigDecimal(userTicketOrderListVO.getDiscountAmt()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }
            if (Objects.nonNull(userTicketOrderListVO.getPayAmt())) {
                userTicketOrderExcel.setPayAmt(new BigDecimal(userTicketOrderListVO.getPayAmt()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }

            if (Objects.nonNull(userTicketOrderListVO.getStatus())) {
                userTicketOrderExcel.setStatus(userTicketOrderListVO.getStatus().getDesc());
            }
            if (Objects.nonNull(userTicketOrderListVO.getBoxType())){
                userTicketOrderExcel.setBoxType(userTicketOrderListVO.getBoxType().getDesc());
            }
            return userTicketOrderExcel;
        }).collect(Collectors.toList());

        ExcelUtil<UserTicketOrderExcel> util = new ExcelUtil<>(UserTicketOrderExcel.class);
        return util.exportExcel(excelList, "盲票销售订单导出", false);
    }


    @Log(title = "销售订单盲票导出", businessType = BusinessType.EXPORT)
    @PostMapping("/ticket/export")
    @PreAuthorize("@ss.hasPermi('order:userTicket:ticketExport')")
    @ApiOperation("销售订单盲票导出")
    public AjaxResult ticketExport(@RequestBody UserTicketOrderQueryParam userTicketOrderQueryParam) {

        // 导出时间范围限制校验
        Date startTime = userTicketOrderQueryParam.getStartTime();
        Date endTime = userTicketOrderQueryParam.getEndTime();
        if (startTime == null || endTime == null) {
            return AjaxResult.error("导出数据必须设置日期范围");
        }
        if (DateUtils.diff(startTime, endTime) > 30) {
            return AjaxResult.error("导出的数据不能超过31天");
        }

        QueryWrapper<UserTicketOrderItem> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getBoxTitle())) {
            queryWrapper.like("t2.title", userTicketOrderQueryParam.getBoxTitle());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getBoxType())) {
            queryWrapper.eq("t2.resource", userTicketOrderQueryParam.getBoxType());
        }
        if (StringUtils.isNotBlank(userTicketOrderQueryParam.getPhone())) {
            queryWrapper.eq("t8.phonenumber", userTicketOrderQueryParam.getPhone());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStatus())) {
            queryWrapper.eq("t2.status", userTicketOrderQueryParam.getStatus());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getStartTime()) && Objects.nonNull(userTicketOrderQueryParam.getEndTime())) {
            queryWrapper.between("t1.created_time", userTicketOrderQueryParam.getStartTime(), userTicketOrderQueryParam.getEndTime());
        }
        if (Objects.nonNull(userTicketOrderQueryParam.getChannelId()) && userTicketOrderQueryParam.getChannelId() != 0) {
            queryWrapper.eq("t2.channel_id", userTicketOrderQueryParam.getChannelId());
        }
        queryWrapper.orderByDesc("t1.created_time");

        int totalSize = userTicketOrderItemService.countUserTicketOrderItem(queryWrapper);
        if (totalSize == 0) {
            return AjaxResult.error("没有符合条件的用户订单");
        }

        int pageSize = 2000;
        List<UserTicketOrderItemVO> userTicketOrderItemVOList = new ArrayList<>();
        if (totalSize > pageSize) {
            int totalPage = totalSize % pageSize == 0 ? totalSize / pageSize : totalSize / pageSize + 1;
            for (int i = 0; i < totalPage; i++) {
                queryWrapper.last("limit " + (i * pageSize) + ", " + pageSize);
                List<UserTicketOrderItemVO> list = userTicketOrderItemService.listUserTicketOrderItem(queryWrapper);
                if (CollectionUtils.isNotEmpty(list)) {
                    userTicketOrderItemVOList.addAll(list);
                }
            }
        } else {
            userTicketOrderItemVOList = userTicketOrderItemService.listUserTicketOrderItem(queryWrapper);
        }

        List<UserTicketOrderItemExcel> excelList = userTicketOrderItemVOList.stream().map(userTicketOrderItemVO -> {
            UserTicketOrderItemExcel userTicketOrderItemExcel = new UserTicketOrderItemExcel();
            BeanUtils.copyProperties(userTicketOrderItemVO, userTicketOrderItemExcel);
            if (Objects.nonNull(userTicketOrderItemVO.getSalePrice())) {
                userTicketOrderItemExcel.setSalePrice(new BigDecimal(userTicketOrderItemVO.getSalePrice()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP));
            }
            if (Objects.nonNull(userTicketOrderItemVO.getTicketType())) {
                userTicketOrderItemExcel.setTicketType(userTicketOrderItemVO.getTicketType().getDesc());
            }

            if (Objects.nonNull(userTicketOrderItemVO.getIsPre())) {
                if (userTicketOrderItemVO.getIsPre() == 1) {
                    userTicketOrderItemExcel.setIsPre("是");
                } else {
                    userTicketOrderItemExcel.setIsPre("否");
                }
            }

            if (Objects.nonNull(userTicketOrderItemVO.getTicketStatus())) {
                userTicketOrderItemExcel.setTicketStatus(userTicketOrderItemVO.getTicketStatus().getDesc());
            }

            if (Objects.nonNull(userTicketOrderItemVO.getOrderStatus())) {
                userTicketOrderItemExcel.setOrderStatus(userTicketOrderItemVO.getOrderStatus().getDesc());
            }

            // 如果为盲豆,拼接盲豆数量
            if (Objects.nonNull(userTicketOrderItemVO.getPrizeType()) && TicketPrizeTypeEnum.COIN.equals(userTicketOrderItemVO.getPrizeType())) {
                if (StringUtils.isNotBlank(userTicketOrderItemVO.getPrizeName()) && Objects.nonNull(userTicketOrderItemVO.getValue())) {
                    userTicketOrderItemExcel.setPrizeName(userTicketOrderItemVO.getPrizeName() + "x" + userTicketOrderItemVO.getValue());
                }
            }
            return userTicketOrderItemExcel;
        }).collect(Collectors.toList());

        ExcelUtil<UserTicketOrderItemExcel> util = new ExcelUtil<>(UserTicketOrderItemExcel.class);
        return util.exportExcel(excelList, "销售订单盲票导出", false);
    }



}
