package com.storlead.sales.controller.finance;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.storlead.framework.common.constant.CommonConstant;
import com.storlead.framework.common.result.Result;
import com.storlead.sales.pojo.entity.customer.CustomerEntity;
import com.storlead.sales.pojo.entity.customer.OrderFormEntity;
import com.storlead.sales.enums.ApproveStatusEnum;
import com.storlead.sales.enums.ReceivePlanStatusEnum;
import com.storlead.sales.enums.TaskStatusEnum;
import com.storlead.sales.pojo.dto.finance.OrderReceivePlanDTO;
import com.storlead.sales.pojo.dto.finance.OrderReceivePlanQueryDTO;
import com.storlead.sales.pojo.entity.finance.OrderReceivePlanDetailEntity;
import com.storlead.sales.pojo.entity.finance.OrderReceivePlanRecordEntity;
import com.storlead.sales.pojo.entity.finance.OrderReceiveRecordEntity;
import com.storlead.sales.pojo.vo.finance.OrderReceivePlanDetailVO;
import com.storlead.sales.pojo.vo.finance.OrderReceivePlanVO;
import com.storlead.sales.pojo.vo.finance.OrderReceiveRecordVO;
import com.storlead.sales.pojo.vo.finance.ReceivePlanDetailVO;
import com.storlead.sales.service.customer.CustomerService;
import com.storlead.sales.service.customer.OrderFormService;
import com.storlead.sales.service.finance.OrderReceivePlanDetailService;
import com.storlead.sales.service.finance.OrderReceivePlanRecordService;
import com.storlead.sales.service.finance.OrderReceiveRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
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.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @program: sp-sales-platform
 * @description:
 * @author: chenkq
 * @create: 2024-07-26 14:39
 */
@Api(tags = "财务: 回款计划")
@RestController
@RequestMapping("/finance/receive/plan")
public class OrderReceivePlanApiController {

    @Resource
    private OrderReceivePlanRecordService orderReceivePlanService;

    @Resource
    private OrderReceivePlanDetailService orderReceivePlanDetailService;

    @Resource
    private OrderReceiveRecordService orderReceiveRecordService;

    @Resource
    private OrderFormService orderFormService;

    @Resource
    private CustomerService customerService;

    @ApiOperation(value = "获取回款计划")
    @PostMapping( "/list_page")
    public Result<?> list(@RequestBody OrderReceivePlanQueryDTO dto) {

        IPage<OrderReceivePlanDetailEntity> page = new Page<>(dto.getPageIndex(),dto.getPageSize());
        LambdaQueryWrapper<OrderReceivePlanDetailEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(OrderReceivePlanDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        IPage<OrderReceivePlanDetailEntity> pageList = orderReceivePlanDetailService.page(page,queryWrapper);
        return Result.result(pageList);

    }

    @ApiOperation(value = "获取回款计划详情")
    @PostMapping( "/get_plan_detail")
    public Result<?> getPlanDetail(Long detailId) {

        if (Objects.isNull(detailId)) {
            return Result.error("参数错误");
        }
        OrderReceivePlanDetailEntity receiveDetail = orderReceivePlanDetailService.getById(detailId);
        if (Objects.isNull(receiveDetail)) {
            return Result.error("参数错误");
        }
        OrderReceivePlanVO planVO = new OrderReceivePlanVO();
        OrderReceivePlanDetailVO detailVo = new OrderReceivePlanDetailVO();
        BeanUtils.copyProperties(receiveDetail,detailVo);
        planVO.setDetail(detailVo);

        Long orderId =  receiveDetail.getOrderId();
        OrderFormEntity orderForm = orderFormService.getById(receiveDetail.getOrderId());
        if (Objects.isNull(orderForm)) {
            return Result.error("参数错误");
        }

        LambdaQueryWrapper<OrderReceivePlanRecordEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(OrderReceivePlanRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        queryWrapper.eq(OrderReceivePlanRecordEntity::getOrderId,orderId);
        queryWrapper.last("limit 1");
        OrderReceivePlanRecordEntity plan = orderReceivePlanService.getOne(queryWrapper);
        if (Objects.isNull(plan)) {
            return Result.error("参数错误!");
        }
        BeanUtils.copyProperties(plan,planVO);
        planVO.setOrderName(orderForm.getTitle());
        CustomerEntity customer = customerService.getById(orderForm.getCustomerId());
         if (Objects.isNull(customer)) {
             planVO.setCustomerName("");
        } else {
             planVO.setCustomerName(customer.getCustomerName());
        }

        LambdaQueryWrapper<OrderReceivePlanDetailEntity> detailWrapper = new LambdaQueryWrapper();
        detailWrapper.eq(OrderReceivePlanDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        detailWrapper.eq(OrderReceivePlanDetailEntity::getOrderId,orderId);
        detailWrapper.last("limit 1");
        List<OrderReceivePlanDetailEntity> planDetails = orderReceivePlanDetailService.list(detailWrapper);

        List<OrderReceivePlanDetailVO> receivePlanDetaills =new ArrayList<>();
        for (OrderReceivePlanDetailEntity detail : planDetails) {
            OrderReceivePlanDetailVO record = new OrderReceivePlanDetailVO();
            BeanUtils.copyProperties(detail,record);
            receivePlanDetaills.add(record);
        }

        planVO.setPlanDetails(receivePlanDetaills);

        LambdaQueryWrapper<OrderReceiveRecordEntity> reWrapper = new LambdaQueryWrapper();
        reWrapper.eq(OrderReceiveRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        reWrapper.eq(OrderReceiveRecordEntity::getPlanId,orderId);
        reWrapper.last("limit 1");
        List<OrderReceiveRecordEntity> details = orderReceiveRecordService.list(reWrapper);

        List<OrderReceiveRecordVO> receiveDetaills =new ArrayList<>();
        for (OrderReceiveRecordEntity detail : details) {
            OrderReceiveRecordVO record = new OrderReceiveRecordVO();
            BeanUtils.copyProperties(detail,record);
            receiveDetaills.add(record);
        }
        planVO.setReceiveDetails(receiveDetaills);

        return Result.result(planVO);
    }

    @ApiOperation(value = "创建回款计划")
    @PostMapping( "/generate_plan")
    public Result<?> generate_plan(@RequestBody OrderReceivePlanDTO dto) {
        if (Objects.isNull(dto)) {
            return Result.error("参数错误");
        }

        LocalDate firstReceiveDate = dto.getFirstReceiveDate();
        Integer receivePeriodTotal =dto.getReceivePeriodTotal();
        LocalDate receiveDate = firstReceiveDate;
        BigDecimal receiveAmount = dto.getPlanReceiveAmount();
        BigDecimal leaveOrderAmount = receiveAmount;
        BigDecimal periodAmount =  receiveAmount.divide(BigDecimal.valueOf(receivePeriodTotal),2, RoundingMode.HALF_UP);
        BigDecimal percentage = periodAmount.divide(receiveAmount, 2, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        BigDecimal receiveRatio =  percentage ;
        BigDecimal lastReceiveRatio = BigDecimal.valueOf(100) ;

        List<ReceivePlanDetailVO> planDetails = new ArrayList<>();
        for(int periodNum =1; periodNum <= receivePeriodTotal ;periodNum++) {
            ReceivePlanDetailVO record = new ReceivePlanDetailVO();
            if (Integer.valueOf(0).equals(dto.getIsCreate())) {
                // 创建
                if (periodNum > 1) {
                    if(Integer.valueOf(1).equals(dto.getReceiveIntervalUnit())) {
                        receiveDate = receiveDate.plusDays(dto.getReceiveInterval());
                    } else {
                        receiveDate = receiveDate.plusMonths(dto.getReceiveInterval());
                    }
                }
            }else  {
                // 修改
                if(Integer.valueOf(1).equals(dto.getReceiveIntervalUnit())) {
                    receiveDate = receiveDate.plusDays(dto.getReceiveInterval());
                } else {
                    receiveDate = receiveDate.plusMonths(dto.getReceiveInterval());
                }
            }

            if (Integer.valueOf(periodNum).equals(receivePeriodTotal)) {
                record.setPlanReceiveAmount(leaveOrderAmount);
                record.setReceiveRatio(lastReceiveRatio);
            } else {
                record.setPlanReceiveAmount(periodAmount);
                record.setReceiveRatio(receiveRatio);
            }
            record.setPeriodNum(periodNum);
            record.setPlanReceiveDate(receiveDate);
            planDetails.add(record);

            leaveOrderAmount = leaveOrderAmount.subtract(periodAmount);
            lastReceiveRatio = lastReceiveRatio.subtract(receiveRatio);
        }
        return Result.ok(planDetails);
    }

    @ApiOperation(value = "创建回款计划")
    @PostMapping( "/create_plan")
    public Result<?> createPlan(@RequestBody OrderReceivePlanDTO dto) {
        if (Objects.isNull(dto)) {
            return Result.error("参数错误");
        }
        OrderFormEntity  order = orderFormService.getById(dto.getOrderId());

        LambdaQueryWrapper<OrderReceivePlanRecordEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(OrderReceivePlanRecordEntity::getOrderId,dto.getOrderId());
        queryWrapper.eq(OrderReceivePlanRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        OrderReceivePlanRecordEntity planRecord = orderReceivePlanService.getOne(queryWrapper);

        if (Objects.nonNull(planRecord)) {
            return Result.error("该订单已有回款计划，请先删除");
        }

        List<OrderReceivePlanDetailEntity> planDetails = dto.getUpdateData();
        if (CollectionUtils.isEmpty(planDetails)) {
            return Result.error("请创建计划详情");
        }
        OrderReceivePlanRecordEntity plan = new OrderReceivePlanRecordEntity();
        plan.setOrderId(dto.getOrderId());
        plan.setOrderAmount(order.getTotalOrderAmt());
        plan.setReceiveAmount(order.getTotalOrderAmt());
        plan.setReceiveIntervalUnit(dto.getReceiveIntervalUnit());
        plan.setReceiveInterval(dto.getReceiveInterval());
        plan.setPeriodTotal(planDetails.size());

        double plReceiveAmount =  planDetails.stream().mapToDouble(e -> e.getPlanReceiveAmount().doubleValue()).sum();
        BigDecimal receiveAmount = new BigDecimal(String.valueOf(plReceiveAmount));
        if (receiveAmount.compareTo(order.getTotalOrderAmt()) < 0) {
            return Result.error("订单金额与计划回款金额不一致");
        }

        LocalDate firstReceiveDate = dto.getFirstReceiveDate();
        Integer receivePeriodTotal =dto.getReceivePeriodTotal();
        LocalDate lastReceiveDate = firstReceiveDate;
        BigDecimal periodAmount = order.getTotalOrderAmt().divide(BigDecimal.valueOf(receivePeriodTotal));
        BigDecimal leaveOrderAmount = BigDecimal.valueOf(0);

        for(int periodNum =1; periodNum <= planDetails.size() ;periodNum++) {
            OrderReceivePlanDetailEntity record = planDetails.get(periodNum-1);
            leaveOrderAmount = order.getTotalOrderAmt().multiply(periodAmount);
            if (periodNum > 1) {
                if(Integer.valueOf(1).equals(dto.getReceiveIntervalUnit())) {
                    lastReceiveDate = firstReceiveDate.plusDays(dto.getReceiveInterval() * periodNum);
                } else {
                    lastReceiveDate = firstReceiveDate.plusMonths(dto.getReceiveInterval() * periodNum);
                }
            }
            if (Integer.valueOf(periodNum).equals(dto.getReceivePeriodTotal())) {
                record.setPlanReceiveAmount(leaveOrderAmount);
            } else {
                record.setPlanReceiveAmount(periodAmount);
            }
            record.setPeriodNum(periodNum);
            record.setPeriodTotal(receivePeriodTotal);
            record.setPlanReceiveDate(lastReceiveDate);
            record.setOrderId(dto.getOrderId());
        }
        orderReceivePlanService.save(plan);
        orderReceivePlanDetailService.saveOrUpdateBatch(planDetails);


        return Result.ok();
    }

    @ApiOperation(value = "配置回款计划")
    @PostMapping( "/update_plan")
    public Result<?> updatPlan(@RequestBody OrderReceivePlanDTO dto) {
        if (Objects.isNull(dto)) {
            return Result.error("参数错误");
        }

        LambdaQueryWrapper<OrderReceivePlanRecordEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(OrderReceivePlanRecordEntity::getOrderId,dto.getOrderId());
        queryWrapper.eq(OrderReceivePlanRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        OrderReceivePlanRecordEntity plan = orderReceivePlanService.getOne(queryWrapper);

        List<OrderReceivePlanDetailEntity> planDetails = dto.getUpdateData();

        BigDecimal planReceiveAmount = BigDecimal.ZERO;
        List<OrderReceivePlanDetailEntity> updatels = new ArrayList<>();
        for (OrderReceivePlanDetailEntity planDetail : planDetails) {
            if (ReceivePlanStatusEnum.UNSTART.getCode().equals(planDetail.getReceiveStatus())
                    && (ApproveStatusEnum.NOT_SUBMIT_APPROVE.equals(planDetail.getApproveStatus())
                    || ApproveStatusEnum.APPROVE_NO_PASS.equals(planDetail.getApproveStatus()))) {
                updatels.add(planDetail);
            }
            if (CommonConstant.DEL_FLAG_0.equals(planDetail.getIsDelete())) {
                planReceiveAmount = planReceiveAmount.add(planDetail.getPlanReceiveAmount());
            }
        }

        if (CollectionUtils.isEmpty(updatels)) {
            orderReceivePlanDetailService.saveOrUpdateBatch(updatels);
        }

        if (planReceiveAmount.compareTo(plan.getReceiveAmount()) < 0) {
            return Result.error("回款金额需要与订单金额一致");
        }
        return Result.ok();
    }

    @ApiOperation(value = "删除回款计划")
    @PostMapping( "/delete_plan_detail")
    public Result<?> deletePlanDetail(@RequestBody OrderReceivePlanDTO dto) {
        if (Objects.isNull(dto)) {
            return Result.error("参数错误");
        }
        LambdaQueryWrapper<OrderReceivePlanRecordEntity> planWrapper = new LambdaQueryWrapper();
        planWrapper.eq(OrderReceivePlanRecordEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        planWrapper.eq(OrderReceivePlanRecordEntity::getOrderId, dto.getOrderId());
        planWrapper.last("limit 1");
        OrderReceivePlanRecordEntity  receivePlan = orderReceivePlanService.getOne(planWrapper);
        if (Objects.isNull(receivePlan)) {
            return Result.error("receivePlan");
        }
        LambdaQueryWrapper<OrderReceivePlanDetailEntity> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(OrderReceivePlanDetailEntity::getIsDelete, CommonConstant.DEL_FLAG_0);
        List<OrderReceivePlanDetailEntity> planDetails = orderReceivePlanDetailService.list(queryWrapper);

        if (CollectionUtils.isEmpty(planDetails)) {
            return Result.error("参数错误");
        }

        Boolean isCanCreate = true;
        for (OrderReceivePlanDetailEntity p : planDetails) {
            if (!TaskStatusEnum.UNSTART.getCode().equals(p.getReceiveStatus())); {
                isCanCreate = false;
            }
        }
        if (!isCanCreate) {
            return Result.error("该订单已有回款计划在进行中，无法删除!");
        }
        List<Long> ids = planDetails.stream().map(OrderReceivePlanDetailEntity::getId).collect(Collectors.toList());
        orderReceivePlanService.lgDelete(ids);
        if (Objects.nonNull(receivePlan)) {
            orderReceivePlanService.lgDelete(receivePlan.getId());
        }
        return Result.ok();
    }



//    @ApiOperation(value = "创建回款计划")
//    @PostMapping( "/create_plan")
//    public Result<?> list(@RequestBody OrderReceivePlanDTO dto) {
//        if (Objects.isNull(dto.getcustomerId())) {
//            return Result.error("参数错误");
//        }
//        if (Objects.isNull(dto.getOrderId())) {
//            return Result.error("参数错误");
//        }
//        OrderFormEntity order = orderFormService.getById(dto.getOrderId());
//        LocalDate firstReceiveDate = dto.getFirstReceiveDate();
//        Integer receivePeriodTotal =dto.getReceivePeriodTotal();
//        LocalDate lastReceiveDate = firstReceiveDate;
//        BigDecimal periodAmount =  order.getOrderAmount().divide(BigDecimal.valueOf(receivePeriodTotal));
//        BigDecimal leaveOrderAmount = BigDecimal.valueOf(0);
//        for(int periodNum =1; periodNum <= dto.getReceivePeriodTotal() ;periodNum++) {
//            OrderReceivePlanRecordEntity record = new OrderReceivePlanRecordEntity();
//            if (periodNum > 1) {
//                if(Integer.valueOf(1).equals(dto.getReceiveIntervalUnit())) {
//                    lastReceiveDate = firstReceiveDate.plusDays(dto.getReceiveInterval() * periodNum);
//                } else {
//                    lastReceiveDate = firstReceiveDate.plusMonths(dto.getReceiveInterval() * periodNum);
//                }
//            }
//            leaveOrderAmount = order.getOrderAmount().multiply(periodAmount);
//            if (Integer.valueOf(periodNum).equals(dto.getReceivePeriodTotal())) {
//                record.setPlanReceiveAmount(leaveOrderAmount);
//            } else {
//                record.setPlanReceiveAmount(periodAmount);
//            }
//            record.setPeriodNum(periodNum);
//            record.setPeriodTotal(receivePeriodTotal);
//            record.setPlanReceiveDate(lastReceiveDate);
//            record.setOrderId(dto.getOrderId());
//        }
//
//        return Result.ok();
//    }
}
