package com.huigou.topsun.quotation.application.impl;

import cn.hutool.core.bean.BeanUtil;
import com.huigou.cache.SystemCache;
import com.huigou.data.query.model.QueryDescriptor;
import com.huigou.topsun.product.domain.Product;
import com.huigou.topsun.product.repository.ProductRepository;
import com.huigou.topsun.quotation.application.QuotationItemApplication;
import com.huigou.topsun.quotation.domain.model.Quotation;
import com.huigou.topsun.quotation.application.QuotationApplication;
import com.huigou.topsun.quotation.domain.model.QuotationItem;
import com.huigou.topsun.quotation.domain.query.QuotationQueryRequest;
import com.huigou.topsun.quotation.repository.QuotationRepository;
import com.huigou.topsun.quotation.vo.QuotationItemVo;
import com.huigou.uasp.bmp.common.BizBillStatus;
import com.huigou.uasp.bpm.FlowBroker;
import com.huigou.util.ClassHelper;
import com.huigou.util.DateUtil;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import static org.activiti.engine.impl.util.CollectionUtil.map;

/**
* @author 16508
* @description 针对表【quotation(报价单)】的数据库操作Service实现
* @createDate 2023-11-28 13:59:10
*/
@Service("quotationApplication")
public class QuotationApplicationImpl extends FlowBroker implements QuotationApplication {
    @Resource
    private QuotationRepository quotationRepository;
    @Resource
    private QuotationItemApplication quotationItemApplication;
    @Resource
    private ProductRepository productRepository;

    @Override
    protected String saveBizAndApprovalData() {
        super.saveBizAndApprovalData();
        Quotation quotation = getBizEntity(Quotation.class);
        if (quotation.isNew()) {
            quotation.setStatusId(BizBillStatus.APPLYING.getId());
        } else {
            quotation = (Quotation) commonDomainService.loadAndFillinProperties(quotation);
        }
        quotation = this.saveQuotation(quotation);
        List<QuotationItem> quotationItems = this.getBizEntities(QuotationItem.class, "quotationItems");

        quotationItemApplication.saveQuotationItems(quotation.getId(),quotationItems);
        return quotation.getId();
    }



    @Override
    protected Map<String, Object> getProcessBizParams(String bizId) {
        // 返回业务数据给流程实例，
        return ClassHelper.toMap(quotationRepository.getOne(bizId));
    }

    /**
     * 设置任务名称
     */
    @Override
    protected void setTaskDescription(DelegateTask delegateTask) {
        String bizId = delegateTask.getExecution().getProcessBusinessKey();
        delegateTask.setDescription(this.getApprovalSubjectName(bizId));
    }

    /**
     * 获取任务标题
     *
     * @param bizId
     * @return
     */
    private String getApprovalSubjectName(String bizId) {
        Quotation quotation = this.findById(bizId);
        String subjectName = String.format("%s-%s(%s)"
                ,quotation.getQuotationNo()
                ,quotation.getPersonMemberName()
                ,DateUtil.getDateFormat(ClassHelper.convert(quotation.getFillinDate(), Date.class)));
        return subjectName;
    }

    @Override
    protected void onEnd(DelegateExecution delegateExecution) {
        super.onEnd(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        BizBillStatus status = approvePassed() ? BizBillStatus.COMPLETED : BizBillStatus.ABORTED;
        Quotation quotation = quotationRepository.findOne(bizId);
        quotation.setStatusId(status.getId());
        quotationRepository.save(quotation);
    }

    @Override
    protected void onAbortProcessInstance(DelegateExecution delegateExecution) {
        super.onAbortProcessInstance(delegateExecution);
        String bizId = delegateExecution.getProcessBusinessKey();
        Quotation quotation = quotationRepository.findOne(bizId);
        quotation.setStatusId(BizBillStatus.ABORTED.getId());
        quotationRepository.save(quotation);
    }

    /**
     * @param delegateTask
     * @param destActivityId 回退到的目标节点id
     */
    @Override
    protected void onBack(DelegateTask delegateTask, String destActivityId) {
        super.onBack(delegateTask, destActivityId);
        if ("Apply".equalsIgnoreCase(destActivityId)) {
            String bizId = delegateTask.getExecution().getProcessBusinessKey();
            Quotation quotation = quotationRepository.findOne(bizId);
            quotation.setStatusId(BizBillStatus.APPLYING.getId());
            quotationRepository.save(quotation);
        }
    }

    @Override
    public Quotation findById(String id) {
        return quotationRepository.findOne(id);
    }

    @Override
    public Quotation saveQuotation(Quotation quotation) {
        quotation = quotationRepository.save(quotation);
        quotation.setQuotationId(quotation.getId());
        quotationRepository.save(quotation);
        return quotation;
    }

    @Override
    public Map<String, Object> slicedQuotationList(QuotationQueryRequest queryRequest) {
        QueryDescriptor queryDescriptor = this.sqlExecutorDao.getQuery(QUERY_XML_FILE_PATH, "slicedQuotationList");
        return this.sqlExecutorDao.executeSlicedQuery(queryDescriptor,queryRequest);
    }

    @Override
    public Map<String, Object> loadPrintData(String quotationId) {
        Quotation quotation = quotationRepository.findOne(quotationId);
        Map<String, Object> map = ClassHelper.beanToMap(quotation);
        List<QuotationItem> itemList = quotationItemApplication.findQuotationItemByQuotationId(quotationId);
        List<QuotationItemVo> quotationItemVoList = itemList
                .stream()
                .map(quotationItem -> {
                    QuotationItemVo quotationItemVo = new QuotationItemVo();
                    BeanUtil.copyProperties(quotationItem, quotationItemVo);

                    //Product product = productRepository.findOne(quotationItem.getProductId());
                    //quotationItemVo.setProductUnit(product.getProductUnit());
                    return quotationItemVo;
                })
                .collect(Collectors.toList());
        map.put("gridData",quotationItemVoList);
        String templateUrl = "";
        if ("factory".equals(quotation.getQuotationType())){//工厂客户
            templateUrl = "/print/topsun/factoryQuotation.ftl";
            getBSNFactoryMessage(map);
        }else {//品牌客户
            templateUrl = "/print/topsun/brandQuotation.ftl";
            getBSNBrandMessage(map);
        }
        map.put("url",templateUrl);
        return map;
    }

    public Map<String,Object> getBSNFactoryMessage(Map<String,Object> map){
        String companyName = SystemCache.getParameter("bsn.factory.companyName", String.class);
        String companyNameEn = SystemCache.getParameter("bsn.factory.companyName.en", String.class);
        String address = SystemCache.getParameter("bsn.factory.address", String.class);
        String email = SystemCache.getParameter("bsn.factory.email", String.class);
        String fax = SystemCache.getParameter("bsn.factory.fax", String.class);
        String tel = SystemCache.getParameter("bsn.factory.tel", String.class);
        map.put("companyName",companyName);
        map.put("companyNameEn",companyNameEn);
        map.put("address",address);
        map.put("email",email);
        map.put("fax",fax);
        map.put("tel",tel);
        return map;
    }

    public Map<String,Object> getBSNBrandMessage(Map<String,Object> map){
        String companyName = SystemCache.getParameter("bsn.brand.companyName", String.class);
        String companyNameEn = SystemCache.getParameter("bsn.brand.companyName.en", String.class);
        String address = SystemCache.getParameter("bsn.brand.address", String.class);
        String email = SystemCache.getParameter("bsn.brand.email", String.class);
        String fax = SystemCache.getParameter("bsn.brand.fax", String.class);
        String tel = SystemCache.getParameter("bsn.brand.tel", String.class);
        String term1 = SystemCache.getParameter("bsn.brand.term1", String.class);
        String term2 = SystemCache.getParameter("bsn.brand.term2", String.class);
        String term3 = SystemCache.getParameter("bsn.brand.term3", String.class);
        String term4 = SystemCache.getParameter("bsn.brand.term4", String.class);
        String term5 = SystemCache.getParameter("bsn.brand.term5", String.class);
        map.put("companyName",companyName);
        map.put("companyNameEn",companyNameEn);
        map.put("address",address);
        map.put("email",email);
        map.put("fax",fax);
        map.put("tel",tel);
        map.put("term1",term1);
        map.put("term2",term2);
        map.put("term3",term3);
        map.put("term4",term4);
        map.put("term5",term5);
        map.put("Attn","Mitzi Cavour");
        map.put("From","Paul Rao");
        map.put("Re","BSN offer to Cariuma for Polybag&Label");
        map.put("bsn","BSN (Baoshen) is glad to make the following quotation and look forward to working with Cariuma.");
        return map;
    }
}




