package com.younike.system.task;

import com.younike.system.domain.Merchant;
import com.younike.system.domain.Order;
import com.younike.system.domain.PersonalMerchantSettle;
import com.younike.system.domain.TaskLog;
import com.younike.system.enums.PersonalSettleStatusEnum;
import com.younike.system.service.IMerchantService;
import com.younike.system.service.IOrderService;
import com.younike.system.service.IPersonalMerchantSettleService;
import com.younike.system.service.ITaskLogService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 个体户账单结算统计任务
 *
 * @author dail
 */
@Component("personalSettleTask")
@Log4j2
public class PersonalSettleTask {

    /**
     * 任务日志
     */
    @Autowired
    private ITaskLogService taskLogService;

    @Autowired
    private IOrderService orderService;

    @Autowired
    private IMerchantService merchantService;

    @Autowired
    private IPersonalMerchantSettleService personalMerchantSettleService;


    public void settle() {
        TaskLog taskLog = new TaskLog();
        taskLog.setTaskName("个体户账单结算信息统计");
        taskLog.setExecutionTime(LocalDateTime.now());

        try {
            LocalDate currentDate = LocalDate.now();
            LocalDate lastMonthCurrentDate = currentDate.minusMonths(1);
            LocalDate settleStartDate = lastMonthCurrentDate.with(TemporalAdjusters.firstDayOfMonth());
            LocalDate settleEndDate = lastMonthCurrentDate.with(TemporalAdjusters.lastDayOfMonth());
            log.info("个体户账单结算期间:" + settleStartDate + "~" + settleEndDate);
            // 查询所有「已完成」「已拒绝退款」订单，以商家进行分组
            Map<Long, List<Order>> personalSettledOrders = orderService.listPersonalMerchantSettleOrder(settleStartDate, settleEndDate);
            if (personalSettledOrders != null && personalSettledOrders.size() > 0) {
                Set<Long> merchantIds = personalSettledOrders.keySet();

                List<PersonalMerchantSettle> addSettleList = new ArrayList<>();
                List<PersonalMerchantSettle> updateSettleList = new ArrayList<>();
                List<Long> orderList =  new ArrayList<>();
                for (Map.Entry<Long, List<Order>> entry : personalSettledOrders.entrySet()) {
                    // 遍历各商家待结算订单
                    BigDecimal settleAmount = entry.getValue().stream().map(Order::getShopAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
                    // 查询商家信息
                    Merchant merchant = merchantService.selectMerchantByMerchantId(entry.getKey());
                    if (merchant == null) {
                        log.error("个体户账单结算统计错误 -- 待结算商家信息异常（缺失）" + entry.getKey().toString());
                    } else {
                        // 查询商家该月是否已存在未结算账单记录，若存在，则更新
                        String dateStr = String.valueOf(settleStartDate);
                        PersonalMerchantSettle byMerchantIdAndYearMonth = personalMerchantSettleService.getByMerchantIdAndYearMonth(entry.getKey(), dateStr.substring(0, dateStr.lastIndexOf("-")));
                        if (byMerchantIdAndYearMonth == null) {
                            PersonalMerchantSettle personalMerchantSettle = new PersonalMerchantSettle();
                            personalMerchantSettle.setMerchantId(entry.getKey());
                            personalMerchantSettle.setYearMonth(dateStr.substring(0, dateStr.lastIndexOf("-")));
                            personalMerchantSettle.setMerchantName(merchant.getMerchantName());
                            personalMerchantSettle.setMerchantIndex(merchant.getMerchantIndex());
                            personalMerchantSettle.setActualIncome(settleAmount);
                            personalMerchantSettle.setSettleStatus(PersonalSettleStatusEnum.PENDING_SETTLEMENT.getCode());
                            personalMerchantSettle.setCreateBy("1");
                            personalMerchantSettle.setUpdateBy("1");
                            addSettleList.add(personalMerchantSettle);
                        } else {
                            // 更新实际收入(元)
                            byMerchantIdAndYearMonth.setActualIncome(settleAmount);
                            updateSettleList.add(byMerchantIdAndYearMonth);
                        }
                    }
                }

                // 插入/更新个体户账单结算信息
                if (personalMerchantSettleService.saveBatch(addSettleList) != addSettleList.size()
                        || personalMerchantSettleService.updateBatchById(updateSettleList) != updateSettleList.size()) {
                    throw new RuntimeException("个体户账单结算统计失败 -- 批量插入结算记录失败");
                }
            } else {
                log.info("本次无可结算个体户订单");
            }
            taskLog.setTaskResult(1);
        } catch (Exception e) {
            taskLog.setTaskResult(0);
            taskLog.setErrorLog(e.getMessage());
        } finally {
            taskLogService.insertTaskLog(taskLog);
        }
    }

}
