package com.tourism.webadmin.app.website.controller;

import com.tourism.common.core.annotation.MyRequestBody;
import com.tourism.common.core.constant.ErrorCodeEnum;
import com.tourism.common.core.exception.MyRuntimeException;
import com.tourism.common.core.object.MyOrderParam;
import com.tourism.common.core.object.MyPageData;
import com.tourism.common.core.object.ResponseResult;
import com.tourism.common.core.object.TokenData;
import com.tourism.common.core.util.MyCommonUtil;
import com.tourism.common.core.util.MyDateUtil;
import com.tourism.common.core.util.MyModelUtil;
import com.tourism.common.core.util.MyPageUtil;
import com.tourism.common.core.validator.AddGroup;
import com.tourism.webadmin.app.website.dto.TourismBookProjectDto;
import com.tourism.webadmin.back.dto.TourOrderDto;
import com.tourism.webadmin.back.model.*;
import com.tourism.webadmin.back.model.constant.GroupPurchaseRebate;
import com.tourism.webadmin.back.model.constant.TourOrderState;
import com.tourism.webadmin.back.service.*;
import com.tourism.webadmin.back.vo.TourOrderPassenageVo;
import com.tourism.webadmin.back.vo.TourOrderVo;
import com.tourism.webadmin.back.vo.TourismProjectVo;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.groups.Default;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 个人订单控制器类。
 *
 * @author 吃饭睡觉
 * @date 2024-09-06
 */
@Tag(name = "我的订单管理接口")
@Slf4j
@RestController
@RequestMapping("/website/tourism/myOrder")
public class TourismOrderController {

    @Autowired
    private TourOrderService tourOrderService;
    @Autowired
    private TourOrderPassenageService tourOrderPassenageService;
    @Autowired
    private TourismProjectService tourismProjectService;
    @Autowired
    private TourismDatePriceService tourismDatePriceService;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private TourProjectGroupPurchaseService tourProjectGroupPurchaseService;
    @Autowired
    private TourProjectGroupPurchaseRebateService tourProjectGroupPurchaseRebateService;

    /**
     * 列出符合过滤条件个人订单列表。
     *
     * @param tourOrderDto 旅游订单Dto对象
     * @return 应答结果对象，包含查询结果集。
     */
    @GetMapping("/list")
    public ResponseResult<MyPageData<TourOrderVo>> list(TourOrderDto tourOrderDto) {
        TourOrder tourOder = new TourOrder();
        if (tourOrderDto.getOrderStatus() != null) {
            tourOder.setOrderStatus(tourOrderDto.getOrderStatus());
        }
        TokenData tokenData = TokenData.takeFromRequest();
        //由手机号查询订单改为由登录人--->创建人查询订单
//        tourOder.setCustomerMobile(tokenData.getLoginName());
        tourOder.setCreateUserId(tokenData.getUserId());
        MyOrderParam myOrderParam = new MyOrderParam();
        myOrderParam.add(new MyOrderParam.OrderInfo("createTime", false, null));
        String orderBy = MyOrderParam.buildOrderBy(myOrderParam, TourOrder.class);
//        List<TourOrder> tourOderList = tourOrderService.getTourOrderList(tourOder, orderBy);
        List<TourOrder> tourOderList = tourOrderService.getTourOrderListWithRelation(tourOder, orderBy);
        MyPageData<TourOrderVo> tourOderVoMyPageData = MyPageUtil.makeResponseData(tourOderList, TourOrderVo.class);

        List<TourOrderVo> dataList = tourOderVoMyPageData.getDataList();
        dataList.stream().forEach(item -> {
            if (item.getProjectId() != null) {
                TourismProject tourismProject = tourismProjectService.getById(item.getProjectId());
                TourismProjectVo tourismProjectVo = MyModelUtil.copyTo(tourismProject, TourismProjectVo.class);
                item.setTourismProjectVo(tourismProjectVo);
            }
        });
        return ResponseResult.success(tourOderVoMyPageData);
    }

    /**
     * 列出符合过滤条件个人订单详情。
     *
     * @param orderId 订单id
     * @return 应答结果对象，包含查询结果集。
     */
    @GetMapping("/detail")
    public ResponseResult<TourOrderVo> detail(@RequestParam Long orderId) {
        TourOrder tourOder = new TourOrder();
        tourOder.setId(orderId);
        TokenData tokenData = TokenData.takeFromRequest();
//        tourOder.setCustomerMobile(tokenData.getLoginName());
        tourOder.setCreateUserId(tokenData.getUserId());
        TourOrder tourOder1 = tourOrderService.getOne(tourOder);
        if(tourOder1 == null){
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        TourOrderPassenage tourOrderPassenage = new TourOrderPassenage();
        tourOrderPassenage.setOrderId(orderId);
        List<TourOrderPassenage> tourOrderPassenageList = tourOrderPassenageService.getTourOrderPassenageListWithRelation(tourOrderPassenage, "");
        TourOrderVo tourOrderVo = MyModelUtil.copyTo(tourOder1, TourOrderVo.class);

        TourismProject tourismProject = new TourismProject();
        tourismProject.setId(Long.parseLong(tourOrderVo.getProjectId()));
        TourismProject tourismProject1 = tourismProjectService.getOne(tourismProject);
        TourismProjectVo tourismProjectVo = MyModelUtil.copyTo(tourismProject1, TourismProjectVo.class);
        tourOrderVo.setTourismProjectVo(tourismProjectVo);
        List<TourOrderPassenageVo> tourOrderPassenageVoList = MyModelUtil.copyCollectionTo(tourOrderPassenageList, TourOrderPassenageVo.class);
        tourOrderVo.setDetailList(tourOrderPassenageVoList);
        return ResponseResult.success(tourOrderVo);
    }

    /**
     * 新增项目订单接口。1预定成功，2已经预定
     *
     * @param tourBookInfoDto 新增对象
     * @return 应答结果对象，包含查询结果集。
     */
    @PostMapping("/add")
    public ResponseResult<TourProjectGroupPurchase> add(@RequestBody TourismBookProjectDto tourBookInfoDto) {
        // 如果有拼团，需要查询当前人数阶段价格、下阶段价格和距离到下个阶段的人数
        TourOrderDto tourOrderDto = new TourOrderDto();

//        RBucket<Object> bucket = redissonClient.getBucket(tourBookInfoDto.getString().concat(tourBookInfoDto.getCustomerMobile()));
//        if (bucket.get() != null) {
//            return ResponseResult.success(2);
//        }
        String errorMessage = MyCommonUtil.getModelValidationError(tourBookInfoDto, Default.class, AddGroup.class);
        if (errorMessage != null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        TourOrder tourOrder = MyModelUtil.copyTo(tourOrderDto, TourOrder.class);

        // 赋值
        tourOrder.setCustomerName(tourBookInfoDto.getCustomerName());
        tourOrder.setDepartureDate(tourBookInfoDto.getStartDate());
        tourOrder.setAdultNumber(tourBookInfoDto.getAdultNumber());
        tourOrder.setChildrenNumber(tourBookInfoDto.getChildrenNumber());
        tourOrder.setProjectId(tourBookInfoDto.getProjectId());
        tourOrder.setCustomerMobile(tourBookInfoDto.getCustomerMobile());
        tourOrder.setCustomerMobileStandby(tourBookInfoDto.getCustomerMobileStandby());
        tourOrder.setCustomerWechat(tourBookInfoDto.getCustomerWechat());
        tourOrder.setGroupPurchaseProgressId(tourBookInfoDto.getGroupId());

        TourismProject tourismProject = tourismProjectService.getById(tourOrder.getProjectId());
        if (tourismProject == null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        TourProjectGroupPurchase tourProjectGroupPurchase = null;
        // 判断拼团ID是否为空，如果不为空，根据拼团ID处理拼团信息
        if (tourBookInfoDto.getGroupId() != null) {
            tourProjectGroupPurchase = tourProjectGroupPurchaseService.handleGroupBuy(tourBookInfoDto, tourOrder);
            // 有新用户团购，就需要修改历史订单的价格信息
            tourOrderService.updateHistoryOrderPrice(tourOrder);
        }else {
            BigDecimal totalPrice;
            //根据出发日期，计算订单金额
            TourismDatePrice tourismDatePrice = new TourismDatePrice();
            tourismDatePrice.setProjectId(tourOrder.getProjectId().toString());
            tourismDatePrice.setOrderDate(tourOrder.getDepartureDate());
            List<TourismDatePrice> tourismDatePriceList = tourismDatePriceService.getTourismDatePriceList(tourismDatePrice, "");
            if (CollectionUtils.isNotEmpty(tourismDatePriceList)) {
                totalPrice = tourismDatePriceList.get(0).getAdultPrice().multiply(BigDecimal.valueOf(tourOrder.getAdultNumber() == null?0:tourOrder.getAdultNumber())).
                        add(tourismDatePriceList.get(0).getChildrenPrice().multiply(BigDecimal.valueOf(tourOrder.getChildrenNumber() == null?0:tourOrder.getChildrenNumber())));
//            tourOrderDto.setEndDate(DateUtils.addDays(tourismDatePrice.getOrderDate(),Integer.parseInt(tourismProject.getCountTimes())));
                tourOrder.setTotalAmount(totalPrice);
                tourOrder.setCurrency(tourismProject.getPriceUnit());
                tourOrder.setAdultPrice(tourismDatePriceList.get(0).getAdultPrice());
                tourOrder.setChildrenPrice(tourismDatePriceList.get(0).getChildrenPrice());
            } else {
                tourOrder.setTotalAmount(BigDecimal.ZERO);
            }
        }
        tourOrder.setProjectResume(tourismProject.getProjectTitle());
        tourOrder.setCountTimes(tourismProject.getCountTimes());
        tourOrder.setProjectTitle(tourismProject.getProjectTitle());
        tourOrder.setOrderDate(new Date());
        //订单状态(0,未确认;1,未完成;2,已完成)
        tourOrder.setOrderStatus(0);
        tourOrderService.saveNew(tourOrder);

        if(tourProjectGroupPurchase != null){
            // 为分享用户增加返利
            TourProjectGroupPurchaseRebate rebate = new TourProjectGroupPurchaseRebate();
            rebate.setUserId(tourBookInfoDto.getShareId());
            rebate.setGroupPurchaseProgressId(tourProjectGroupPurchase.getId());
            rebate.setOrderId(tourOrder.getId());
            rebate.setReasonRelationUserid(TokenData.takeFromRequest().getUserId());
            rebate.setPrice(new BigDecimal(100).multiply(BigDecimal.valueOf(tourBookInfoDto.getAdultNumber() + tourBookInfoDto.getChildrenNumber())));
            rebate.setReason(GroupPurchaseRebate.INVITE_USER);
            rebate.setPriceUnit(tourProjectGroupPurchase.getPriceUnit());
            tourProjectGroupPurchaseRebateService.saveNew(rebate);
        }
        return ResponseResult.success(tourProjectGroupPurchase);
    }

    /**
     * 项目订单列表删除项目订单 (0,未确认;允许删除)
     *
     * @param id 通过id进行删除
     * @return 应答结果对象，包含查询结果集。
     */
    @PostMapping("/delete")
    public ResponseResult<Void> delete(@MyRequestBody String id) {
        TourOrder tourOrder = tourOrderService.getById(Long.parseLong(id));

        // 判断是否是登录人创建的数据
        TokenData tokenData = TokenData.takeFromRequest();
        if(!tourOrder.getCreateUserId().equals(tokenData.getUserId())){
            return ResponseResult.error(ErrorCodeEnum.TOUR_ORDER_USER_ERROR);
        }
        // 非未确认状态订单不允许取消
        if(!tourOrder.getOrderStatus().equals(TourOrderState.CONFIRMED)){
            return ResponseResult.error(ErrorCodeEnum.NON_UNCONFIRMED_ORDERS_CANNOT_BE_CANCELLED);
        }
        // 判断是不是参与了团购
        if(tourOrder.getGroupPurchaseProgressId() != null){
            // 如果参与了团购
            // 超过拼团截止日期的不允许取消
            TourProjectGroupPurchase groupPurchase = tourProjectGroupPurchaseService.getById(tourOrder.getGroupPurchaseProgressId());
            Date newDate = MyDateUtil.addDays(groupPurchase.getEndTime(), 1);
            if (newDate.getTime() < System.currentTimeMillis()) {
                throw new MyRuntimeException(ErrorCodeEnum.GROUP_BUYING_HAS_EXPIRED_CANNOT_BE_CANCELLED.getErrorMessage());
            }
            // 已经成团的不允许取消
            if(groupPurchase.getSuccess() == 1){
                throw new MyRuntimeException(ErrorCodeEnum.ALREADY_FORMED_A_GROUP_CANNOT_BE_CANCELLED.getErrorMessage());
            }
            tourProjectGroupPurchaseService.cancelGroupBuy(groupPurchase, tourOrder);
            // 修改历史价格
            tourOrderService.updateHistoryOrderPrice(tourOrder);

            // 清空返利，增加返利流水记录
            TourProjectGroupPurchaseRebate rebateFilter = new TourProjectGroupPurchaseRebate();
            rebateFilter.setOrderId(Long.valueOf(id));
            TourProjectGroupPurchaseRebate one = tourProjectGroupPurchaseRebateService.getOne(rebateFilter);

            TourProjectGroupPurchaseRebate rebate = MyModelUtil.copyTo(one, TourProjectGroupPurchaseRebate.class);
            rebate.setId(null);
            rebate.setPrice(BigDecimal.ZERO.subtract(rebate.getPrice()));
            tourProjectGroupPurchaseRebateService.saveNew(rebate);
        }
        //判断id是否为有效id
        if(tourOrder == null){
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        tourOrder.setOrderStatus(TourOrderState.CANCELLED);
        tourOrderService.updateById(tourOrder);
        return ResponseResult.success();
    }
}