package com.njzscloud.supervisory.money.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.util.SecurityUtil;
import com.njzscloud.supervisory.biz.pojo.result.SearchCompanyResult;
import com.njzscloud.supervisory.money.mapper.MoneyBillMapper;
import com.njzscloud.supervisory.money.pojo.entity.MoneyBillEntity;
import com.njzscloud.supervisory.money.pojo.result.MoneyBillResult;
import com.njzscloud.supervisory.order.utils.FileUtil;
import com.njzscloud.supervisory.sys.auth.mapper.AuthMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 对账单
 * @author ljw
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MoneyBillService extends ServiceImpl<MoneyBillMapper, MoneyBillEntity> {

    private final AuthMapper authMapper;

    /**
     * 新增
     */
    public void add(MoneyBillEntity moneyBillEntity) {
        this.save(moneyBillEntity);
    }

    /**
     * 修改
     */
    public void modify(MoneyBillEntity moneyBillEntity) {
        this.updateById(moneyBillEntity);
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeBatchByIds(ids);
    }

    /**
     * 详情
     */
    public MoneyBillEntity detail(Long id) {
        return this.getById(id);
    }

    /**
     * 分页查询
     */
    public PageResult<MoneyBillEntity> paging(PageParam pageParam, MoneyBillEntity moneyBillEntity) {
        Page<MoneyBillEntity> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        // List<Long> stationIds = orderInfoService.getStationIds();
        // if (!stationIds.isEmpty()) {
        //     moneyBillEntity.setStationId(null);
        // }
        IPage<MoneyBillEntity> result = baseMapper.selectMoneyBillWithNames(page, moneyBillEntity, null);
        return PageResult.of(result);
    }

    /**
     * 根据清运公司ID分页查询
     */
    public PageResult<MoneyBillEntity> selectPagingByStationId(PageParam pageParam, MoneyBillEntity moneyBillEntity) {
        Page<MoneyBillEntity> page = new Page<>(pageParam.getCurrent(), pageParam.getSize());
        Long userId = SecurityUtil.currentUserId();
        SearchCompanyResult company = authMapper.selectCompanyInfo(userId);
        IPage<MoneyBillEntity> result = new Page<>();
        if (null != company) {
            moneyBillEntity.setStationId(company.getId());
            result = baseMapper.selectMoneyBillWithNames(page, moneyBillEntity, null);
        }
        return PageResult.of(result);
    }

    /**
     * 重新生成账单
     */
    public void rebuildBill(Long id) {
        MoneyBillEntity entity = this.getById(id);
        // 创建查询条件
        MoneyBillResult queryCondition = new MoneyBillResult();
        // 转换为当天0点0分0秒
        LocalDateTime startTime = entity.getStartTime().atStartOfDay();
        // 转换为当天23点59分59秒
        LocalDateTime endTime = entity.getEndTime().atTime(23, 59, 59);
        queryCondition.setStartTime(startTime);
        queryCondition.setEndTime(endTime);
        queryCondition.setOriginExpenseItemId(entity.getGoodsId());
        queryCondition.setTransCompanyId(entity.getStationId());
        queryCondition.setOrderCategory(entity.getOrderCategory());
        // 执行查询
        List<MoneyBillResult> billResults = baseMapper.selectMoneyBillList(queryCondition);
        if (null != billResults && !billResults.isEmpty()) {
            // 1. 订单数量：通过orderId分组，条数就是订单数
            long orderCount = billResults.stream().
                    map(MoneyBillResult::getOrderId)
                    .distinct()
                    .count();
            entity.setOrderCount((int) orderCount);

            // 2. 总质量
            int totalWeight = billResults.stream()
                    .mapToInt(MoneyBillResult::getSettleWeight)
                    .sum();
            entity.setTotalWeight(totalWeight);

            // 3. 车数 = 订单数
            entity.setCarCount((int) orderCount);

            // 4. 优惠金额：discountMoney求和，可能是负数
            BigDecimal totalDiscountMoney = billResults.stream()
                    .map(MoneyBillResult::getDiscountMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            entity.setDiscountMoney(totalDiscountMoney);

            // 5. 账单金额：settleMoney求和，可能是负数
            BigDecimal totalSettleMoney = billResults.stream()
                    .map(MoneyBillResult::getSettleMoney)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            entity.setTotalMoney(totalSettleMoney);
        }
        this.updateById(entity);
    }

    public void export(HttpServletResponse response, MoneyBillEntity entity) throws IOException {
        List<MoneyBillEntity> list = baseMapper.selectMoneyBillWithNames(entity, null);
        List<Map<String, Object>> downList = new ArrayList<>();
        int i = 1;
        for (MoneyBillEntity result : list) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("序号", i);
            map.put("公司名称", result.getCompanyName());
            map.put("产品名称", result.getGoodsName());
            map.put("订单数", result.getOrderCount());
            map.put("总重量（t）", String.valueOf(result.getTotalWeight() == null ? null : BigDecimal.valueOf(result.getTotalWeight())
                    .divide(BigDecimal.valueOf(1000), 3, RoundingMode.HALF_UP)));
            map.put("总车数", result.getCarCount());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            map.put("开始日期", result.getStartTime() != null ? result.getStartTime().format(formatter) : "");
            map.put("结束日期", result.getEndTime() != null ? result.getEndTime().format(formatter) : "");
            map.put("优惠金额", result.getDiscountMoney());
            map.put("账单金额", result.getTotalMoney());
            downList.add(map);
            i++;
        }
        FileUtil.downloadExcel(downList, response, "对账单.xlsx");
    }
}
