package com.ghy.web.controller.order;

import com.ghy.common.core.controller.BaseController;
import com.ghy.common.core.domain.AjaxResult;
import com.ghy.common.enums.FinancialDetailType;
import com.ghy.common.enums.OrderStatus;
import com.ghy.common.enums.PayStatus;
import com.ghy.common.utils.StringUtils;
import com.ghy.customer.domain.Customer;
import com.ghy.customer.service.CustomerService;
import com.ghy.goods.domain.DeptGoodsCategory;
import com.ghy.goods.domain.Goods;
import com.ghy.goods.domain.GoodsStandard;
import com.ghy.goods.request.AppGoodsRequest;
import com.ghy.goods.service.DeptGoodsCategoryService;
import com.ghy.goods.service.GoodsService;
import com.ghy.goods.service.GoodsStandardService;
import com.ghy.order.domain.OrderDetail;
import com.ghy.order.domain.OrderGoods;
import com.ghy.order.domain.OrderMaster;
import com.ghy.order.request.AppOrderAssignRequest;
import com.ghy.order.request.AppOrderRequest;
import com.ghy.order.request.SysOrderAssignRequest;
import com.ghy.order.service.OrderDetailService;
import com.ghy.order.service.OrderGoodsService;
import com.ghy.order.service.OrderMasterService;
import com.ghy.payment.domain.FinancialDetail;
import com.ghy.payment.domain.FinancialMaster;
import com.ghy.payment.service.FinancialDetailService;
import com.ghy.payment.service.FinancialMasterService;
import com.ghy.web.pojo.vo.OrderStatisticsRequest;
import com.ghy.web.pojo.vo.OrderStatisticsResponse;
import com.ghy.worker.domain.Worker;
import com.ghy.worker.service.WorkerService;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author clunt
 * 下单接口
 */
@Controller
@RequestMapping("/order")
public class OrderController extends BaseController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private DeptGoodsCategoryService deptGoodsCategoryService;

    @Autowired
    private WorkerService workerService;

    @Autowired
    private OrderMasterService orderMasterService;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderGoodsService orderGoodsService;

    @Autowired
    private FinancialMasterService financialMasterService;

    @Autowired
    private FinancialDetailService financialDetailService;

    @Autowired
    private GoodsStandardService goodsStandardService;

    /**
     * 可派单商品数量
     * */
    @PostMapping("/can/assign")
    @ResponseBody
    public AjaxResult canAssign(@RequestBody AppOrderAssignRequest request){
        try {
            // 找出原单的数量
            List<OrderGoods> orderGoodsList =  orderGoodsService.selectByOrderMasterId(request.getOrderMasterId());
            // 找出原单关联的细单的商品数量
            List<OrderDetail> orderDetailList = orderDetailService.selectByOrderMasterId(request.getOrderMasterId());
            for (OrderDetail orderDetail : orderDetailList){
                // 子单数量
                List<OrderGoods> orderDetailGoodsList = orderGoodsService.selectByOrderDetailId(orderDetail.getId());

                // 计算剩余未分配的商品数量
                for (OrderGoods detailGoods : orderDetailGoodsList) {
                    for(OrderGoods masterGoods : orderGoodsList){
                        if(Objects.equals(masterGoods.getGoodsStandardId(), detailGoods.getGoodsStandardId())){
                            masterGoods.setGoodsNum(masterGoods.getGoodsNum() - detailGoods.getGoodsNum());
                        }
                    }
                }
            }
            //计算新单的数量
            return AjaxResult.success(orderGoodsList);
        }catch (Exception e){
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 后台批量下单
     * */
    @PostMapping("/sys/order")
    @ResponseBody
    public AjaxResult sysOrder(@RequestBody SysOrderAssignRequest request){
        try {
            // 新增商品 -- 商品不关联师傅,状态为不展示在商城页面

            // 选择消费者(消费者类型为渠道商、不需要) --

            // 生成消费者下单地址

            // 生成主单

            // 生成财务单

            // 生成财务细单 -- 平台扣点、提成
            return AjaxResult.success("下单成功");
        }catch (Exception e){

            return AjaxResult.error("系统异常");
        }
    }


    @PostMapping("/assign")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult assign(@RequestBody AppOrderAssignRequest request) throws BaseAdaPayException {
        OrderMaster om = orderMasterService.selectById(request.getOrderMasterId());
        Assert.notNull(om, "订单不存在");
        FinancialMaster fm = financialMasterService.selectByOrderMasterId(om.getId());
        Assert.notNull(fm, "找不到对应的订单");
        // 派单师傅
        Worker assignWorker = workerService.selectById(om.getWorkerId());
        Assert.notNull(assignWorker, "找不到师傅信息");
        // 接单师傅
        Worker acceptWorker = workerService.selectById(request.getWorkerId());
        Assert.notNull(acceptWorker, "查询接单师傅信息失败");
        // 校验接单师傅和派单师傅是不是同一个Team
        if(!om.getWorkerId().equals(request.getWorkerId())){
            boolean checkInTeam = workerService.checkInTeam(assignWorker.getWorkerId(), acceptWorker.getWorkerId());
            Assert.isTrue(checkInTeam, "接单师傅不在本团队");
        }else {
            // 自己接单 -- 计算剩余金额
            BigDecimal realPay = fm.getPayMoney();
            for (FinancialDetail financialDetail : financialDetailService.selectByFinancialMasterId(fm.getId())) {
                realPay = realPay.subtract(financialDetail.getPayMoney());
            }
            request.setTotalPay(realPay);
        }

        // 判断是否全部派完
        if(request.getIsAll() == 1){
            om.setOrderStatus(OrderStatus.GOING.code());
            orderMasterService.updateOrderMaster(om);
        }

        // 创建子订单
        OrderDetail od = new OrderDetail();
        od.setDeptId(om.getDeptId());
        od.setCode(orderDetailService.createCode());
        od.setOrderMasterId(om.getId());
        od.setOrderMasterCode(om.getCode());
        od.setCustomerId(om.getCustomerId());
        od.setOrderType(om.getOrderType());
        od.setOrderStatus(OrderStatus.GOING.code());
        od.setWorkerId(request.getWorkerId());
        od.setRevTime(om.getRevTime());
        od.setExpectTimeStart(om.getExpectTimeStart());
        od.setExpectTimeEnd(om.getExpectTimeEnd());
//        od.setRemark(om.getRemark());
        orderDetailService.insertOrderDetail(od);

        // 批量生成订单商品
        request.getGoodsList().forEach(goods -> {
            // 查询规格信息
            GoodsStandard goodsStandard = goodsStandardService.selectById(goods.getGoodsStandardId());
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setGoodsStandardId(goods.getGoodsStandardId());
            orderGoods.setGoodsNum(goods.getNum());
            orderGoods.setGoodsName(goodsStandard.getGoodsStandardName());
            orderGoods.setOrderDetailId(od.getId());
            orderGoods.setServerGoodsNum(0);
            orderGoodsService.insertOrderGoods(orderGoods);
        });

        String leaderTeamMoney = assignWorker.getLeaderTeamMoney();
        String leaderTeamRate = assignWorker.getLeaderTeamRate();

        // 派单师傅的钱
        BigDecimal assignWorkerMoney = BigDecimal.ZERO;
        // 固定抽成
        if (StringUtils.isNotBlank(leaderTeamMoney)) {
            assignWorkerMoney = assignWorkerMoney.add(new BigDecimal(leaderTeamMoney));
        }
        // 比例抽成
        if (StringUtils.isNotBlank(leaderTeamRate)) {
            BigDecimal rate = new BigDecimal(leaderTeamRate);
            assignWorkerMoney = rate.multiply(request.getTotalPay()).add(assignWorkerMoney);
        }

        // 如果派单师傅的抽成金额>0 则为派单师傅生成子财务单
        if (BigDecimal.ZERO.compareTo(assignWorkerMoney) < 0) {
            FinancialDetail fd = new FinancialDetail(fm.getDeptId(), financialDetailService.createCode(), fm.getId(),
                    fm.getCode(), null, null, assignWorkerMoney, FinancialDetailType.WORKER_FEE.getCode(), assignWorker.getWorkerId(),
                    fm.getPayType(), fm.getPayStatus(), fm.getPayTime());
            financialDetailService.insertFinancialDetail(fd);
        }

        // 接单师傅的钱
        BigDecimal acceptWorkerMoney;

        // 减掉派单师傅的抽成
        acceptWorkerMoney = request.getTotalPay().subtract(assignWorkerMoney);
        Assert.isTrue(BigDecimal.ZERO.compareTo(acceptWorkerMoney) < 0, "订单计算出错 请联系管理员");

        //为接单师傅生成子财务单
        FinancialDetail fd = new FinancialDetail(fm.getDeptId(), financialDetailService.createCode(), fm.getId(),
                fm.getCode(), od.getId(), od.getCode(), acceptWorkerMoney, FinancialDetailType.ORDER_FEE.getCode(), acceptWorker.getWorkerId(),
                fm.getPayType(), fm.getPayStatus(), fm.getPayTime());
        financialDetailService.insertFinancialDetail(fd);

        // TODO 检查是否商品全部消耗完成，如果完成则还要给派单师傅生成一条财务细单，并更新orderMaster的状态。

        return AjaxResult.success();
    }

    @PostMapping("/server/app")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult appOrder(@RequestBody AppOrderRequest appOrderRequest) throws ParseException {
        // 校验用户信息
        Customer customer = customerService.selectByCustomerId(appOrderRequest.getCustomerId());
        if (StringUtils.isNull(customer)) {
            return AjaxResult.error("用户不存在!");
        }
        List<AppGoodsRequest> appGoodsList = appOrderRequest.getGoodsList();
        // 校验商品信息(库存)
        boolean flag = goodsService.checkStore(appGoodsList);
        if (!flag) {
            return AjaxResult.error("库存不足!");
        }
        // 计算商品费用
        BigDecimal totalPay = goodsService.calculate(appGoodsList);
        // 所有商品的ID
        Set<Long> goodsStandardIds = appGoodsList.stream().map(AppGoodsRequest::getGoodsStandardId).collect(Collectors.toSet());
        // 所有商品
        List<GoodsStandard> goodsList = goodsStandardService.selectByIds(goodsStandardIds);
        // 商品所属师傅
        Goods goods = goodsService.selectById(goodsList.get(0).getGoodsId());
        // 商户ID
        Long deptId = appOrderRequest.getDeptId();
        Assert.notNull(deptId, "deptId is null!");

        // 生成主单
        OrderMaster orderMaster = new OrderMaster();
        orderMaster.setDeptId(deptId);
        orderMaster.setCode(orderMasterService.createOrderCode());
        orderMaster.setOrderType(0);
        orderMaster.setPayType(appOrderRequest.getPayType());
        orderMaster.setOrderStatus(OrderStatus.RECEIVE.code());
        orderMaster.setCustomerId(appOrderRequest.getCustomerId());
        orderMaster.setAddressId(appOrderRequest.getAddressId());
        orderMaster.setPayStatus(PayStatus.WAIT_PAY.getCode());
        orderMaster.setCreateTime(new Date());
        orderMaster.setWorkerId(goods.getWorkerId());
        orderMaster.setGoodsId(appOrderRequest.getGoodsId());
//        orderMaster.setRevTime(DateUtils.parseDate(appOrderRequest.getServerTime(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMaster.setRemark(appOrderRequest.getRemark());
        orderMaster.setExpectTimeStart(DateUtils.parseDate(appOrderRequest.getExpectTimeStart(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMaster.setExpectTimeEnd(DateUtils.parseDate(appOrderRequest.getExpectTimeEnd(), com.ghy.common.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
        orderMasterService.insertOrderMaster(orderMaster);
        Assert.notNull(orderMaster.getId(), "OrderMaster.id is null!");

        // TODO 优惠金额不知道咋算 暂时先给0
        BigDecimal discountMoney = BigDecimal.ZERO;
        BigDecimal payMoney = totalPay.subtract(discountMoney);

        // 当实付金额payType<=0时 使payType=BigDecimal.ZERO
        payMoney = BigDecimal.ZERO.max(payMoney);

        // 生成财务主单
        FinancialMaster financialMaster = new FinancialMaster(financialMasterService.createCode(), deptId,
                orderMaster.getId(), orderMaster.getCode(), totalPay, discountMoney, payMoney);
        financialMasterService.insertFinancialMaster(financialMaster);
        Assert.notNull(financialMaster.getId(), "FinancialMaster.id is null!");

        //生成财务子单
        createFinancialDetail(goodsList.get(0).getDeptGoodsCategoryId(), deptId, customer, payMoney, financialMaster);

        // 生成商品订单
        Map<Long, GoodsStandard> goodsMap = goodsList.stream().filter(Objects::nonNull)
                .collect(Collectors.toMap(GoodsStandard::getGoodsStandardId, x -> x));
        for (AppGoodsRequest appGoods : appGoodsList) {
            GoodsStandard goodsStandard = goodsMap.get(appGoods.getGoodsStandardId());
            OrderGoods orderGoods = new OrderGoods(orderMaster.getId(), goodsStandard.getGoodsStandardId(),
                    goodsStandard.getGoodsStandardName(), appGoods.getNum(), 0);
            orderGoodsService.insertOrderGoods(orderGoods);
        }

        return AjaxResult.success(orderMaster);
    }

    /**
     * 生成财务子单
     *
     * @param deptGoodsCategoryId 商品类目id
     * @param deptId              商户ID
     * @param customer            消费者
     * @param payMoney            实付金额
     * @param financialMaster     财务主单
     */
    private void createFinancialDetail(Long deptGoodsCategoryId, Long deptId, Customer customer, BigDecimal payMoney, FinancialMaster financialMaster) {
        // 是否为0元购 是的话下面就不用多级分销了
        if (BigDecimal.ZERO.compareTo(payMoney) == 0) {
            return;
        }

        /* 1 平台服务服务费 */
        DeptGoodsCategory deptGoodsCategory = deptGoodsCategoryService.get(deptGoodsCategoryId);
        BigDecimal deptRate = new BigDecimal(deptGoodsCategory.getDeptRate());
        BigDecimal deptMoney = deptGoodsCategory.getDeptMoney();

        BigDecimal deptTotal = payMoney.multiply(deptRate).add(deptMoney);

        FinancialDetail deptDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptTotal, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(deptDetail);

        /* 2 截留扣点 */
        BigDecimal retainRate = new BigDecimal(deptGoodsCategory.getRetainRate());
        BigDecimal retainMoney = deptGoodsCategory.getRetainMoney();

        BigDecimal retainTotal = payMoney.multiply(retainRate).add(retainMoney);

        FinancialDetail retainDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), retainTotal, FinancialDetailType.PLATFORM_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(retainDetail);

        /* 3 分销扣点 */
        BigDecimal deptPlaceTotal = BigDecimal.ZERO;

        Long customerPlaceId = customer.getCustomerPlace();
        BigDecimal onePlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getOneRate()));
        BigDecimal twoPlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getTwoRate()));
        BigDecimal threePlaceMoney = payMoney.multiply(new BigDecimal(deptGoodsCategory.getThreeRate()));

        // 一级分销
        if (customerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), onePlaceMoney, FinancialDetailType.PLACE_FEE.getCode(), customerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);
        } else {
            deptPlaceTotal = deptPlaceTotal.add(onePlaceMoney);
        }

        // 二级分销
        Long parentCustomerPlaceId = customer.getParentCustomerPlace();
        if (parentCustomerPlaceId != null) {
            FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                    financialMaster.getId(), financialMaster.getCode(), twoPlaceMoney, FinancialDetailType.PLACE_FEE.getCode(), parentCustomerPlaceId);
            financialDetailService.insertFinancialDetail(financialDetail);
        } else {
            deptPlaceTotal = deptPlaceTotal.add(twoPlaceMoney);
        }

        // 平台分销
        deptPlaceTotal = deptPlaceTotal.add(threePlaceMoney);
        FinancialDetail financialDetail = new FinancialDetail(deptId, financialDetailService.createCode(),
                financialMaster.getId(), financialMaster.getCode(), deptPlaceTotal, FinancialDetailType.PLACE_FEE.getCode(), null);
        financialDetailService.insertFinancialDetail(financialDetail);
    }

    /**
     * 订单统计
     * */
    @PostMapping("/app/statistics")
    @ResponseBody
    public AjaxResult orderStatistics(@RequestBody OrderStatisticsRequest request) {
        OrderStatisticsResponse response = new OrderStatisticsResponse();

        try {
            OrderMaster orderMaster = new OrderMaster();
            orderMaster.setOrderStatus(OrderStatus.RECEIVE.code());
            orderMaster.setWorkerId(request.getWorkerId());
            // 统计新订单的单量
            response.setNewOrderNum(orderMasterService.countOrderMasterList(orderMaster));
            // 统计未排的单量
            orderMaster.setOrderStatus(OrderStatus.PLAIN.code());
            response.setPlanOrderNum(orderMasterService.countOrderMasterList(orderMaster));
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(ExceptionUtils.getStackTrace(e));
            return AjaxResult.error(e.getMessage());
        }

        return AjaxResult.success(response);
    }

}
