package com.czg.service.account.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.czg.account.dto.HandoverRecordDTO;
import com.czg.account.entity.HandoverRecord;
import com.czg.account.service.HandoverRecordService;
import com.czg.account.vo.HandoverCategoryListVo;
import com.czg.account.vo.HandoverProductListVo;
import com.czg.account.vo.HandoverTotalVo;
import com.czg.constants.SystemConstants;
import com.czg.order.service.OrderInfoRpcService;
import com.czg.sa.StpKit;
import com.czg.service.account.mapper.HandoverRecordMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 交班记录表
 *
 * @author Tankaikai tankaikai@aliyun.com
 * @since 1.0 2025-02-27
 */
@Service
public class HandoverRecordServiceImpl extends ServiceImpl<HandoverRecordMapper, HandoverRecord> implements HandoverRecordService {

    @DubboReference
    private OrderInfoRpcService orderInfoRpcService;

    private QueryWrapper buildQueryWrapper(HandoverRecordDTO param) {
        QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
        if (StrUtil.isNotEmpty(param.getBeginDate())) {
            queryWrapper.ge(HandoverRecord::getHandoverTime, param.getBeginDate() + " 00:00:00");
        }
        if (StrUtil.isNotEmpty(param.getEndDate())) {
            queryWrapper.le(HandoverRecord::getHandoverTime, param.getEndDate() + " 23:59:59");
        }
        Long shopId = StpKit.USER.getShopId(0L);
        queryWrapper.eq(HandoverRecord::getShopId, shopId);
        queryWrapper.isNotNull(HandoverRecord::getHandoverTime);
        queryWrapper.orderBy(HandoverRecord::getId, false);
        return queryWrapper;
    }


    @Override
    public Page<HandoverRecordDTO> getHandoverRecordPage(String beginDate, String endDate) {
        HandoverRecordDTO param = new HandoverRecordDTO();
        param.setBeginDate(beginDate);
        param.setEndDate(endDate);
        QueryWrapper queryWrapper = buildQueryWrapper(param);
        return super.pageAs(PageUtil.buildPage(), queryWrapper, HandoverRecordDTO.class);
    }

    @Override
    public List<HandoverProductListVo> getHandoverProductListById(Long id) {
        Long shopId = StpKit.USER.getShopId(0L);
        HandoverRecord data = super.getOne(query().eq(HandoverRecord::getId, id).eq(HandoverRecord::getShopId, shopId));
        if (data == null) {
            return List.of();
        }
        String productData = data.getProductData();
        if (StrUtil.isBlank(productData)) {
            return List.of();
        }
        return JSON.parseArray(productData, HandoverProductListVo.class);
    }

    @Override
    public HandoverTotalVo totalHandoverData() {
        Long shopId = StpKit.USER.getShopId(0L);
        LocalDateTime handoverTime = LocalDateTime.now();
        HandoverRecord record = super.getOne(query().eq(HandoverRecord::getShopId, shopId).isNull(HandoverRecord::getHandoverTime));
        HandoverTotalVo data = new HandoverTotalVo();
        if (record == null) {
            return data;
        }
        data.setId(record.getId());
        data.setShopId(record.getShopId());
        data.setShopName(record.getShopName());
        data.setAccountType(record.getAccountType());
        data.setStaffId(record.getStaffId());
        data.setStaffName(record.getStaffName());
        data.setLoginTime(record.getLoginTime());
        data.setHandoverTime(handoverTime);
        String loginTimeStr = LocalDateTimeUtil.formatNormal(record.getLoginTime());
        String handoverTimeStr = LocalDateTimeUtil.formatNormal(handoverTime);
        data.setCashAmount(sumCashAmount(shopId, loginTimeStr, handoverTimeStr));
        data.setRefundAmount(sumRefundAmount(shopId, loginTimeStr, handoverTimeStr));
        data.setHandAmount(sumHandAmount(shopId, loginTimeStr, handoverTimeStr));
        data.setOrderCount(countOrderNum(shopId, loginTimeStr, handoverTimeStr));
        data.setDetailList(getDetailList(shopId, loginTimeStr, handoverTimeStr));
        return data;
    }

    @Override
    public void initHandoverRecord(HandoverRecord entity) {
        List<HandoverRecord> list = super.list(query().eq(HandoverRecord::getShopId, entity.getShopId()).isNull(HandoverRecord::getHandoverTime));
        if (CollUtil.isNotEmpty(list)) {
            return;
        }
        entity.setLoginTime(LocalDateTime.now());
        super.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long handover() {
        Long shopId = StpKit.USER.getShopId(0L);
        HandoverTotalVo data = totalHandoverData();
        LocalDateTime loginTime = data.getLoginTime();
        LocalDateTime handoverTime = data.getHandoverTime();
        String loginTimeStr = LocalDateTimeUtil.formatNormal(loginTime);
        String handoverTimeStr = LocalDateTimeUtil.formatNormal(handoverTime);
        HandoverRecord entity = BeanUtil.copyProperties(data, HandoverRecord.class);
        entity.setWechatAmount(orderInfoRpcService.getHandoverWechatAmount(shopId, loginTimeStr, handoverTimeStr));
        entity.setAlipayAmount(orderInfoRpcService.getHandoverAlipayAmount(shopId, loginTimeStr, handoverTimeStr));
        entity.setVipPay(orderInfoRpcService.getHandoverVipPayAmount(shopId, loginTimeStr, handoverTimeStr));
        entity.setVipRecharge(orderInfoRpcService.getHandoverVipChargeAmount(shopId, loginTimeStr, handoverTimeStr));
        entity.setQuickInAmount(orderInfoRpcService.getHandoverQuickPayAmount(shopId, loginTimeStr, handoverTimeStr));
        entity.setCreditAmount(orderInfoRpcService.getHandoverCreditAmount(shopId, loginTimeStr, handoverTimeStr));
        List<HandoverCategoryListVo> categoryData = orderInfoRpcService.getHandoverCategoryList(shopId, loginTimeStr, handoverTimeStr);
        entity.setCategoryData(JSON.toJSONString(categoryData, JSONWriter.Feature.WriteMapNullValue));
        List<HandoverProductListVo> productData = data.getDetailList();
        entity.setProductData(JSON.toJSONString(productData, JSONWriter.Feature.WriteMapNullValue));
        super.updateById(entity);
        return entity.getId();
    }

    @Override
    public void printHandoverReceipt(Long handoverRecordId, Integer isPrint) {
        if (isPrint == SystemConstants.OneZero.ONE) {
            orderInfoRpcService.sendHandoverReceiptPrintMsgToMq(handoverRecordId);
        }
    }

    private BigDecimal sumCashAmount(Long shopId, String loginTime, String handoverTime) {
        return orderInfoRpcService.getHandoverCashAmount(shopId, loginTime, handoverTime);
    }

    private BigDecimal sumRefundAmount(Long shopId, String loginTime, String handoverTime) {
        return orderInfoRpcService.getHandoverRefundAmount(shopId, loginTime, handoverTime);
    }

    private BigDecimal sumHandAmount(Long shopId, String loginTime, String handoverTime) {
        return orderInfoRpcService.getHandoverTotalAmount(shopId, loginTime, handoverTime);
    }

    private int countOrderNum(Long shopId, String loginTime, String handoverTime) {
        return orderInfoRpcService.getHandoverOrderNum(shopId, loginTime, handoverTime);
    }

    private List<HandoverProductListVo> getDetailList(Long shopId, String loginTime, String handoverTime) {
        return orderInfoRpcService.getHandoverDetailList(shopId, loginTime, handoverTime);
    }
}