package com.scm.contract.service.apply;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.scm.contract.dao.apply.LabelApplicationDetailDao;
import com.scm.contract.model.apply.DictionaryShippingMethod;
import com.scm.contract.model.apply.DictionaryTagType;
import com.scm.contract.model.apply.LabelApplication;
import com.scm.contract.model.apply.LabelApplicationDetail;
import com.scm.contract.model.print.DictionaryPrintStatus;
import com.scm.contract.model.print.Printing;
import com.scm.contract.model.print.ReprintCode;
import com.scm.contract.model.print.SerialNumberRange;
import com.scm.contract.service.print.DictionaryPrintStatusService;
import com.scm.contract.service.print.PrintCodeService;
import com.scm.contract.service.print.ReprintCodeService;
import com.scm.contract.tools.Tools;
import com.set.direwolf.core.mybatis.CrudService;
import com.set.direwolf.core.mybatis.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zuo
 * @date 2024/6/19 10:15
 */

@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class LabelApplicationDetailService extends CrudService<LabelApplicationDetailDao, LabelApplicationDetail, String> {

    @Autowired
    private LabelApplicationDetailDao detailDao;

    @Autowired
    private DictionaryTagTypeService tagTypeService;

    @Autowired
    private PrintCodeService printCodeService;

    @Autowired
    private DictionaryPrintStatusService printStatusService;

    @Autowired
    private LabelApplicationService labelApplicationService;

    @Autowired
    private DictionaryShippingMethodService methodService;

    @Autowired
    private ReprintCodeService reprintCodeService;

    public List<LabelApplicationDetail> getListByLabelApplicationId(String labelApplicationId) {
        List<LabelApplicationDetail> details = detailDao.getListByLabelApplicationId(labelApplicationId);
        setName(details);
        return details;
    }

    public List<LabelApplicationDetail> getListByLabelApplicationIds(List<String> labelApplicationIds) {
        List<LabelApplicationDetail> details = detailDao.getListByLabelApplicationIds(labelApplicationIds);
        setName(details);
        return details;
    }

    public LabelApplicationDetail getById(String id) {
        LabelApplicationDetail detail = detailDao.getById(id);
        setName(Collections.singletonList(detail));
        return detail;
    }

    public void setName(List<LabelApplicationDetail> details) {
        if (CollectionUtils.isNotEmpty(details)) {
            /**
             * 重打中的信息
             */
            List<ReprintCode> reprinting = reprintCodeService.getReprinting(1);
            Map<String, Boolean> detailReprintingMap = new HashMap<>();
            for (ReprintCode reprintCode : reprinting) {
                String detailId = reprintCode.getDetailId();
                detailReprintingMap.put(detailId,true);
            }

            Set<String> tagTypeIds = new HashSet<>();
            Set<String> detailIds = new HashSet<>();
            Set<String> printStatusIds = new HashSet<>();
            Set<String> deliveryMethodIds = new HashSet<>();
            for (LabelApplicationDetail detail : details) {
                String detailId = detail.getId();
                detail.setIsReprinting(detailReprintingMap.getOrDefault(detailId,false));
                tagTypeIds.add(detail.getTagTypeId());
                detailIds.add(detailId);
                Integer printStatus = detail.getPrintStatus();
                if (!Objects.isNull(printStatus)) {
                    printStatusIds.add(printStatus.toString());
                }
                String deliveryMethodId = detail.getDeliveryMethodId();
                if (StringUtils.isNotBlank(deliveryMethodId)) {
                    deliveryMethodIds.add(deliveryMethodId);
                }
            }
            Map<String, DictionaryTagType> tagTypeMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(tagTypeIds)){
                List<DictionaryTagType> tagTypes = tagTypeService.listByIds(new ArrayList<>(tagTypeIds));
                if (CollectionUtils.isNotEmpty(tagTypes)) {
                    for (DictionaryTagType tagType : tagTypes) {
                        tagTypeMap.put(tagType.getId(), tagType);
                    }
                }
            }


            Map<String, SerialNumberRange> serialNumberRangeMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(detailIds)){
                List<SerialNumberRange> serialNumberRanges = printCodeService.getSerialNumberRange(new ArrayList<>(detailIds));
                for (SerialNumberRange serialNumberRange : serialNumberRanges) {
                    serialNumberRangeMap.put(serialNumberRange.getId(), serialNumberRange);
                }
            }

            Map<Integer, DictionaryPrintStatus> printStatusesMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(printStatusIds)) {
                List<DictionaryPrintStatus> printStatuses = printStatusService.listByIds(new ArrayList<>(printStatusIds));
                for (DictionaryPrintStatus printStatus : printStatuses) {
                    printStatusesMap.put(printStatus.getId(), printStatus);
                }
            }

            //获取配送方式Map
            Map<String, DictionaryShippingMethod> methodMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(deliveryMethodIds)) {
                List<DictionaryShippingMethod> methodList = methodService.listByIds(new ArrayList<>(deliveryMethodIds));
                if (CollectionUtils.isNotEmpty(methodList)) {
                    for (DictionaryShippingMethod method : methodList) {
                        methodMap.put(method.getId(), method);
                    }
                }
            }

            for (LabelApplicationDetail detail : details) {
                Long number = detail.getNumber();
                Double unitPrice = detail.getUnitPrice();
                if (!Objects.isNull(number) && !Objects.isNull(unitPrice)) {
                    detail.setAmount(Tools.digitHalfEven(number * unitPrice, 2));
                }
                String tagTypeId = detail.getTagTypeId();
                DictionaryTagType tagType = tagTypeMap.getOrDefault(tagTypeId, new DictionaryTagType());
                detail.setTagTypeName(tagType.getName());

                String detailId = detail.getId();
                SerialNumberRange serialNumberRange = serialNumberRangeMap.get(detailId);
                if (!Objects.isNull(serialNumberRange)) {
                    List<String> list = new ArrayList<>();
                    list.add(serialNumberRange.getMin());
                    list.add(serialNumberRange.getMax());
                    detail.setSerialNumberRange(list);
                }

                Integer printStatus = detail.getPrintStatus();
                if (!Objects.isNull(printStatus)) {
                    DictionaryPrintStatus printStatus1 = printStatusesMap.getOrDefault(printStatus, new DictionaryPrintStatus());
                    detail.setPrintStatusName(printStatus1.getName());
                }

                //设置配送方式名称
                String deliveryMethodId = detail.getDeliveryMethodId();
                if (StringUtils.isNotBlank(deliveryMethodId)) {
                    DictionaryShippingMethod method = methodMap.getOrDefault(deliveryMethodId, new DictionaryShippingMethod());
                    detail.setDeliveryMethodName(method.getName());
                }
            }
        }
    }

    @Transactional
    public synchronized Boolean deleteListByLabelApplicationId(String labelApplicationId) {
        return detailDao.deleteListByLabelApplicationId(labelApplicationId);
    }

    @Transactional
    public synchronized Boolean saveList(List<LabelApplicationDetail> details) {
        for (LabelApplicationDetail detail : details) {
            String id = detail.getId();
            if (StringUtils.isBlank(id)) {
                detail.setId(IdWorker.getIdStr());
            }
            detail.setIsPrint(0);
        }
        return detailDao.saveList(details);
    }

    /**
     * 只能修改打印相关内容
     *
     * @param detailList
     * @return
     */
    @Transactional
    public synchronized Boolean updatePrintBash(List<LabelApplicationDetail> detailList) {
        return detailDao.updatePrintBash(detailList);
    }

    /**
     * 获取所有正在打印的从表信息(
     *
     * @return
     */
    public List<Printing> getPrinting() {
        List<Printing> printings = new ArrayList<>();
        List<LabelApplicationDetail> details = detailDao.getPrinting(1);
        for (LabelApplicationDetail detail : details) {
            printings.add(new Printing(detail));
        }
        List<ReprintCode> reprintCodes = reprintCodeService.getReprinting(1);
        for (ReprintCode reprintCode : reprintCodes) {
            printings.add(new Printing(reprintCode));
        }
        return printings;
    }

    public List<LabelApplicationDetail> listByDetailIds(List<String> ids) {
        return detailDao.listByDetailIds(ids);
    }

    public Page<LabelApplicationDetail> findPage(Page<LabelApplicationDetail> page, LabelApplicationDetail entity) {
        entity.setPage(page);
        page.setList(this.dao.findList(entity));
        List<LabelApplicationDetail> list = page.getList();
        if (CollectionUtils.isNotEmpty(list)){
            this.setName(list);
            List<String> ids = list.stream().map(LabelApplicationDetail::getLabelApplicationId).distinct().collect(Collectors.toList());
            List<LabelApplication> labelApplications = labelApplicationService.getListByIds(ids);
            labelApplicationService.setName(labelApplications, false);
            Map<String, String> map = new HashMap<>();
            for (LabelApplication labelApplication : labelApplications) {
                map.put(labelApplication.getId(), labelApplication.getProviderName());
            }
            for (LabelApplicationDetail detail : list) {
                String labelApplicationId = detail.getLabelApplicationId();
                detail.setProviderName(map.get(labelApplicationId));
            }
        }
        return page;
    }

    @Transactional
    public synchronized Boolean updateSendBash(List<LabelApplicationDetail> updateDetails) {
        return detailDao.updateSendBash(updateDetails);
    }
}
