package com.sifang.modules.sunshine.SystemSetting.service;


import com.google.common.collect.Maps;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.customer.utils.CustomerEntryUtil;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.flowpath.dao.ExamineInfoDao;
import com.sifang.modules.flowpath.dao.SubpackageStandardPriceApplyDao;
import com.sifang.modules.flowpath.entity.ExamineInfo;
import com.sifang.modules.order.utils.excelExt.ExcelReader;
import com.sifang.modules.platform.utils.PlantformUtils;
import com.sifang.modules.sunshine.SystemSetting.dao.SubconractorSettlementSchemeDao;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmProjectSetting;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmSubconractorSettlementScheme;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmSubconractorSettlementSchemeApply;
import com.sifang.modules.sunshine.SystemSetting.form.AddSettlementScheme;
import com.sifang.modules.sunshine.SystemSetting.handler.ExcelImportSettleTheBasePriceHandler;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.common.utils.IdGen;
import com.sifang.modules.sys.util.LayuiPage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @date 2023/04/17 19:10
 */
@Service
public class SubconractorSettlementSchemeService extends BaseService {

    @Autowired
    private SubconractorSettlementSchemeDao schemeDao;

    @Autowired
    private ProjectInfoSettingService projectInfoSettingService;

    @Autowired
    private SubpackageStandardPriceApplyDao schemeApplyDao;

    @Autowired
    private ExamineInfoDao examineInfoDao;
//    public Record getByOne(String id) {
//        return schemeDao.getByOne(id);
//    }

    public CrmSubconractorSettlementScheme getById(String id) {
        return schemeDao.get(id);
    }

    /**
     * 方案数据
     *
     */
    public void getAllList(LayuiPage page, Map<String, String> map) {
        List<Record> list = schemeDao.getAllList(page, map);
        logger.info(">>>>>>>>>>>getAllList  list.count:{}",list.size());
        long count=schemeDao.queryDataCount(map);
        logger.info(">>>>>>>>>>>getAllList  count:{}",count);
        page.setData(list);
        page.setCount(count);
    }


    /**
     * 终止结算方案
     *
     * @param id
     */
    public Result stopSettleData(String id) {
        Date now = new Date();
        CrmSubconractorSettlementScheme data = schemeDao.get(id);
        if (!"1".equals(data.getStatus())) {//已作废
            return Result.fail("205", "");//已作废或终止记录不可重复操作
        }
        User user= UserUtils.getUser();
        data.setCancelTime(now);
        data.setEndTime(now);
        data.setCancelBy(user.getUserName());
        data.setStatus(CrmSubconractorSettlementScheme.STATUS_STOP);
        schemeDao.save(data);
        return Result.ok();
    }
    /**
     * 作废结算方案
     *
     * @param id
     */
    public Result delSettleData(String id) {
        Date now = new Date();
        CrmSubconractorSettlementScheme data = schemeDao.get(id);
        if ("3".equals(data.getStatus())||"0".equals(data.getStatus())) {//已作废
            return Result.fail("205", "");//已作废记录不可重复操作
        }
        User user= UserUtils.getUser();
        data.setCancelTime(now);
        data.setEndTime(now);
        data.setCancelBy(user.getUserName());
        data.setStatus(CrmSubconractorSettlementScheme.STATUS_CANCEL);
        schemeDao.save(data);
        return Result.ok();
    }

    /**
     * 根据项目id查找匹配的结算方案
     *
     * 电站匹配结算方案按照预审通过时间匹配生效时间内的结算方案。(新加)
     */
    public Map<String, String> calcPriceByProjectId(String projectId, Integer componentNum, BigDecimal capacity, String traderId, CustomerEntry entry) {
        //获取最近一次第一次进件审核通过时间，若无进件审核通过，那么取电站提交时间
        Date inComingTime = entry.getInComingTime();
        if(inComingTime==null){
            StringBuffer sb=new StringBuffer();
            sb.append("   SELECT  IFNULL( max(l.audit_time),e.create_time) AS inComingTime FROM `crm_customer_entry` e  ");
            sb.append("  LEFT JOIN `crm_yx_incoming_process` l ON e.id=l.entry_id AND l.type='2' AND l.audit_status='2' ");
            sb.append(" WHERE e.id=? ");
            inComingTime= Db.queryDate(sb.toString(),entry.getId());
            if(inComingTime!=null){
                entry.setInComingTime(inComingTime);
            }
        }
      /*  StringBuffer sql=new StringBuffer();
        sql.append("select actual_capacity from crm_customer_entry where e.id=?");
        Record actual_capacity = Db.findById(sql.toString(), entry.getId());*/

        Record scheme = schemeDao.findByProjectId(projectId, traderId,inComingTime);
        if (scheme == null) {
            throw new BusinessException("未找到产品关联的结算方案，请审核人员联系区域经理提交产品的结算基础价");
        }
        String type = scheme.getStr("type");
        //结算方案编号
        String number = scheme.getStr("number");
        BigDecimal amount = scheme.getBigDecimal("amount");
        Map<String,String> map = new HashMap<>();
        map.put("number",number);
        map.put("amount",amount.toPlainString());
        map.put("actual_capacity",capacity.toPlainString());
        //结算方式 1.按组件单瓦 2.按组件单块
        if ("1".equals(type)) {
            map.put("fbAmount",capacity.multiply(amount).toPlainString());
            return map;
        } else if ("2".equals(type)) {
            map.put("fbAmount",new BigDecimal(componentNum).multiply(amount).toPlainString());
            return map;
        }
        throw new BusinessException("未知结算方式");
    }
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importSettleTheBasePrice(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "import");
        ExcelImportSettleTheBasePriceHandler handler=new ExcelImportSettleTheBasePriceHandler();
        handler.setStartSheet(1);
        handler.setStartRow(2);
        int imgCount = 1;
        User user = UserUtils.getUser();
        String fileName = params.get("fileName");
        try {
//            new ExcelReader().readExcel(in, fileName, handler);
            try {
                new ExcelReader().readExcelPictures(in,fileName, handler,imgCount);
            }catch (Exception e){
                throw new BusinessException(e.getMessage());
            }
            List<CrmProjectSetting> project = projectInfoSettingService.getProjectSettingList();
            Map<String,String> projectMap = project.stream().collect(Collectors.toMap(CrmProjectSetting::getCode, CrmProjectSetting::getId));
            List<AddSettlementScheme> addSettlementSchemes = handler.getAddSettlementSchemes();
            Long maxVersion=schemeDao.getMaxVersion();
            for (AddSettlementScheme add : addSettlementSchemes) {
                maxVersion = maxVersion+1;
                add.setProjectIds(projectMap.get(add.getProjectIds()));
                CrmSubconractorSettlementSchemeApply saveSettlementSchemeApply = getCrmSubconractorSettlementSchemeApply(add,user);
                CrmSubconractorSettlementScheme subconractorSettlementScheme = getCrmSubconractorSettlementScheme(add,user);
                String number= CustomerEntryUtil.addZero2(maxVersion);
                subconractorSettlementScheme.setNumber(number);
                subconractorSettlementScheme.setApplyId(saveSettlementSchemeApply.getId());
                subconractorSettlementScheme.setVersion(maxVersion);
                ExamineInfo examineInfo = new ExamineInfo();
                examineInfo.setFormId(saveSettlementSchemeApply.getId());
                examineInfo.setDetail("初始化导入");
                examineInfo.setOperateTime(new Date());
                examineInfo.setOperateName(user.getUserName());
                examineInfo.setFormTypeId(FormUtils.SUBCONTRACTING_STANDARD_PRICE_APPLICATION);
                schemeApplyDao.save(saveSettlementSchemeApply);
                schemeDao.save(subconractorSettlementScheme);
                examineInfoDao.save(examineInfo);
            }
            retMap.put("pass", "y");
            retMap.put("successCount", addSettlementSchemes.size());
        }catch (Exception e){
            e.printStackTrace();
            logger.error(" 导入结算基础价异常,e:{}",e);
            throw new BusinessException(e.getMessage());
        }finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return retMap;
    }

    private CrmSubconractorSettlementSchemeApply getCrmSubconractorSettlementSchemeApply(AddSettlementScheme add, User user) {
        Date date=new Date();
        CrmSubconractorSettlementSchemeApply schemeApply = new CrmSubconractorSettlementSchemeApply();
        schemeApply.setId(IdGen.uuid());
        schemeApply.setStatus("3");
        schemeApply.setApplyNumber(PlantformUtils.getOrderNumber());
        schemeApply.setCreateBy(user.getId());
        schemeApply.setCreateName(user.getUserName());
        schemeApply.setCreateTime(date);
        schemeApply.setSubmitTime(date);
        schemeApply.setFinishTime(date);
        schemeApply.setDepartmentId(user.getDepartmentId());
        schemeApply.setDepartmentName(user.getDepartmentName());
        schemeApply.setExamineOpinion("初始化导入");
        schemeApply.setTaskName("初始化导入");
        return schemeApply;
    }

    private CrmSubconractorSettlementScheme getCrmSubconractorSettlementScheme(AddSettlementScheme add, User user) throws ParseException {
        CrmSubconractorSettlementScheme scheme = new CrmSubconractorSettlementScheme();
        scheme.setStatus(DateUtils.daysBetween(DateUtils.getDate(),DateUtils.formatDate(add.getCancelTime(),"yyyy-MM-dd"))<0?"2":"1");
        scheme.setName(add.getName());
        scheme.setType("按组件单瓦".equals(add.getType())?"1":"2");
        scheme.setAmount(new BigDecimal(add.getAmount()));
        scheme.setProjectIds(add.getProjectIds());
        scheme.setCreateTime(add.getCreateTime());
        scheme.setCancelTime(add.getCancelTime());
        scheme.setEndTime(add.getCancelTime());
        return scheme;
    }

    public Map<String, Object> checkImportSettleTheBasePrice(Map<String, String> params, InputStream in) {
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("operType", "check");
        ExcelImportSettleTheBasePriceHandler handler = new ExcelImportSettleTheBasePriceHandler();
        handler.setStartSheet(1);
        handler.setStartRow(1);
        try {
            new ExcelReader().check(in, params.get("extName"), handler);
            Map<String, Object> map = (Map<String, Object>) handler.getHandlerResult();
            String errorMsg = (String) map.get("TemplateError");
            if (!handler.isCheckFlag()) {
                handler.appendErrorDetail("<p>未填充数据</p>");
            }
            List<AddSettlementScheme> addSettlementSchemes = handler.getAddSettlementSchemes();
            Set<String> repeatSet = new HashSet<>();
            // 所有有效产品
            List<CrmProjectSetting> project = projectInfoSettingService.getProjectSettingList();
            Map<String,String> projectMap = project.stream().collect(Collectors.toMap(CrmProjectSetting::getCode, CrmProjectSetting::getId));
            //讲所有查询到的产品id放入set
            Set<String> nameSet = project.stream().map(CrmProjectSetting::getCode).collect(Collectors.toSet());
          /*  // 所有有效方案
            List<CrmSubconractorSettlementScheme> schemeList = schemeDao.getCrmSubconractorSettlementSchemeList();
            schemeList.forEach(scheme-> {
                Arrays.asList(scheme.getProjectIds().split(",")).forEach(projectId-> {
                    if (projectMap.containsKey(projectId)) {
                        sb.append( projectMap.get(projectId)+",");
                    }
                });
                sb.deleteCharAt(sb.length()-1);
                ;
                repeatSet.add(scheme.getName()+ (scheme.getCreateTime()!=null?DateUtils.formatDate(scheme.getCreateTime(),"yyyy-MM-dd"):scheme.getCreateTime())
                        +
                        (scheme.getCancelTime()!=null?DateUtils.formatDate(scheme.getCancelTime(),"yyyy-MM-dd"):scheme.getCancelTime())+sb.toString());
                sb.setLength(0);
            });*/
            int row = 0;
            for(AddSettlementScheme addScheme :addSettlementSchemes){
                row++;
                if(nameSet.add(addScheme.getProjectIds())){
                    handler.appendErrorDetail("此"+addScheme.getProjectIds()+"产品编号不存在");
                }
                // 这个是分数据库判断
                Long count =  schemeDao.getSchemeByRepeat(addScheme.getName(),addScheme.getCreateTime(),addScheme.getCancelTime(),projectMap.get(addScheme.getProjectIds()));
                if(count>0){
                    handler.appendErrorDetail("第" + (row + 1) + "行存在相同生效时间的结算方案");
                }
                // 这个是判断表格
                if(!repeatSet.add(addScheme.getName()+(addScheme.getCreateTime()!=null?DateUtils.formatDate(addScheme.getCreateTime(),"yyyy-MM-dd"):addScheme.getCreateTime())
                        +
                        (addScheme.getCancelTime()!=null?DateUtils.formatDate(addScheme.getCancelTime(),"yyyy-MM-dd"):addScheme.getCancelTime())+addScheme.getProjectIds())){
                    handler.appendErrorDetail("第" + (row + 1) + "行存在相同生效时间的结算方案");
                }
                if (DateUtils.daysBetween(DateUtils.formatDate(addScheme.getCreateTime(),"yyyy-MM-dd"),DateUtils.formatDate(addScheme.getCancelTime(),"yyyy-MM-dd"))<0){
                    handler.appendErrorDetail("<p>第" + (row + 1) + "行数据：生效结束时间不能小于生效开始时间" + "</p>");
                }
            }
            String errorDetail = handler.getErrorDetail();
            if (StringUtils.isNotBlank(errorMsg)) {
                resultMap.put("errorDetail", errorMsg);
                resultMap.put("errorMessage", "y");
            } else if (StringUtils.isNotBlank(errorDetail)) {
                resultMap.put("errorDetail", errorDetail);
                resultMap.put("errorMessage", "y");
            } else if ("overLimit".equalsIgnoreCase((String) map.get("overLimit"))) {
                resultMap.put("overLimit", "y");
            } else {
                resultMap.put("pass", "y");
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("errorDetail", "导入结算基础价出错~");
            resultMap.put("errorMessage", "y");
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultMap;
    }
}
