package com.gci.boot.modules.projects.service.impl;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.common.util.Lock;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.basedata.entity.TbCustomerArchives;
import com.gci.boot.modules.basedata.entity.TbInsuranceCompanyArchives;
import com.gci.boot.modules.basedata.entity.TbRepairShopArchives;
import com.gci.boot.modules.basedata.entity.TbVehicleSupplierArchives;
import com.gci.boot.modules.basedata.service.ITbCustomerArchivesService;
import com.gci.boot.modules.basedata.service.ITbInsuranceCompanyArchivesService;
import com.gci.boot.modules.basedata.service.ITbRepairShopArchivesService;
import com.gci.boot.modules.basedata.service.ITbVehicleSupplierArchivesService;
import com.gci.boot.modules.projects.entity.TbContract;
import com.gci.boot.modules.projects.entity.TbContractVehicle;
import com.gci.boot.modules.projects.entity.TbVehicleCheckDetail;
import com.gci.boot.modules.projects.mapper.TbContractMapper;
import com.gci.boot.modules.projects.service.ITbContractService;
import com.gci.boot.modules.projects.service.ITbContractVehicleService;
import com.gci.boot.modules.projects.service.ITbVehicleCheckDetailService;
import com.gci.boot.modules.vehicles.entity.TbInsurance;
import com.gci.boot.modules.vehicles.service.ITbInsuranceService;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 合同档案 服务实现类
 * </p>
 *
 * @author xushuhan
 * @since 2023-09-01
 */
@Slf4j
@Service
public class TbContractServiceImpl extends ServiceImpl<TbContractMapper, TbContract> implements ITbContractService {

	@Autowired
    private ITbCustomerArchivesService tbCustomerArchivesService;
	@Autowired
    private ITbInsuranceCompanyArchivesService tbInsuranceCompanyArchivesService;
	@Autowired
    private ITbRepairShopArchivesService tbRepairShopArchivesService;
	@Autowired
    private ITbVehicleSupplierArchivesService tbVehicleSupplierArchivesService;

	@Autowired
	private ITbContractVehicleService contractVehicleService;
	@Autowired
	private ITbVehicleCheckDetailService vehicleCheckDetailService;
	@Autowired
	private ITbInsuranceService insuranceService;

	@Autowired
	private ITbInsuranceCompanyArchivesService insuranceCompanyArchivesService;
	
    @Autowired
    private Lock lock;
    
    DecimalFormat df2 = new DecimalFormat("#.00");
    
    @Transactional
	@Override
	public void saveItem(TbContract item) {
    	if("1".equals(item.getContractType())||"4".equals(item.getContractType())) {
			item.setStatus("0");
		}
		checkItem(item);
		save(item);
		//处理车辆细项
		if(Objects.nonNull(item.getVehicleDetails()) && item.getVehicleDetails().size()>0){
			item.getVehicleDetails().stream().forEach(s->s.setContractId(item.getId()));
			contractVehicleService.saveItem(item.getVehicleDetails());
		}
    }
    
    @Transactional
    @Override
    public void updateItem(TbContract item) {
    	checkItem(item);
		updateById(item);
		//处理车辆细项--先删后存
		LambdaQueryWrapper<TbContractVehicle> delWrapper = new LambdaQueryWrapper<>();
		delWrapper.eq(TbContractVehicle::getContractId,item.getId());
		contractVehicleService.remove(delWrapper);
		if(Objects.nonNull(item.getVehicleDetails()) && item.getVehicleDetails().size()>0){
			item.getVehicleDetails().stream().forEach(s->s.setContractId(item.getId()));
			contractVehicleService.saveItem(item.getVehicleDetails());
		}
    }
    
	//根据合同类型获取签约方列表
	@Override
	public List<TbContract> getSigningList(String contractType,String sysOrgCode) {
		List<TbContract> dataList = new ArrayList<>();
		if("1".equals(contractType)) {
			QueryWrapper<TbCustomerArchives> queryWrapper = new QueryWrapper<>();
			//queryWrapper.likeRight(StringUtils.hasLength(sysOrgCode),"sys_org_code", sysOrgCode);
			List<TbCustomerArchives> list = tbCustomerArchivesService.list(queryWrapper);
			for(TbCustomerArchives item:list) {
				TbContract con = new TbContract();
				con.setContractType(contractType);
				con.setId(item.getId());
				con.setName(item.getName());
				dataList.add(con);
			}
		}else if("2".equals(contractType)) {
			QueryWrapper<TbInsuranceCompanyArchives> queryWrapper = new QueryWrapper<>();
			//queryWrapper.likeRight(StringUtils.hasLength(sysOrgCode),"sys_org_code", sysOrgCode);
			List<TbInsuranceCompanyArchives> list = tbInsuranceCompanyArchivesService.list(queryWrapper);
			for(TbInsuranceCompanyArchives item:list) {
				TbContract con = new TbContract();
				con.setContractType(contractType);
				con.setId(item.getId());
				con.setName(item.getName());
				dataList.add(con);
			}
		}else if("3".equals(contractType)) {
			QueryWrapper<TbRepairShopArchives> queryWrapper = new QueryWrapper<>();
			//queryWrapper.likeRight(StringUtils.hasLength(sysOrgCode),"sys_org_code", sysOrgCode);
			List<TbRepairShopArchives> list = tbRepairShopArchivesService.list(queryWrapper);
			for(TbRepairShopArchives item:list) {
				TbContract con = new TbContract();
				con.setContractType(contractType);
				con.setId(item.getId());
				con.setName(item.getName());
				dataList.add(con);
			}
		}else if("4".equals(contractType)) {
			QueryWrapper<TbVehicleSupplierArchives> queryWrapper = new QueryWrapper<>();
			//queryWrapper.likeRight(StringUtils.hasLength(sysOrgCode),"sys_org_code", sysOrgCode);
			List<TbVehicleSupplierArchives> list = tbVehicleSupplierArchivesService.list(queryWrapper);
			for(TbVehicleSupplierArchives item:list) {
				TbContract con = new TbContract();
				con.setContractType(contractType);
				con.setId(item.getId());
				con.setName(item.getName());
				dataList.add(con);
			}
		}else {
			return null;
		}
		return dataList;
	}

	public void checkItem(TbContract item) {
		if(ObjectUtil.isAllNotEmpty(item.getStartTime(),item.getEndTime())){
			if(item.getStartTime().after(item.getEndTime())) {
				throw new GciBootException("生效时间不能大于失效时间");
			}
		}
		if(StringUtils.hasLength(item.getFileUrl())) {
			if(item.getFileUrl().split(",").length>10) {
				throw new GciBootException("上传合同档案不能超过10个！");
			}
		}else {
			//throw new GciBootException("请上传合同档案！");
		}
		if("1".equals(item.getContractType())) {
			if(!StringUtils.hasLength(item.getProjectId())) {
				throw new GciBootException("请选择项目");
			}
			LambdaQueryWrapper<TbContract> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.eq(TbContract::getProjectId, item.getProjectId());
			queryWrapper.ne(StringUtils.hasLength(item.getId()),TbContract::getId, item.getId());
			int count = count(queryWrapper);
			if(count>0) {
				throw new GciBootException("该项目的租户合同已存在");
			}
		}
	}
	
	//TODO 交接单状态判断(已提交)，合同id
	@Override
	public void updateStatus(String id) {
		LambdaQueryWrapper<TbContract> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(StringUtils.hasLength(id),TbContract::getId,id);
		queryWrapper.eq(TbContract::getStatus, "0");
		List<TbContract> list = list(queryWrapper);
		for(TbContract item:list) {
			//获取车辆明细
			vehicleCheckDetailService.initVehicleCheckDetail(item);
			int tatol = 0;
			Map<String,Integer> map = new HashMap<>();
			for(TbVehicleCheckDetail d:item.getVehicleList()) {
				if(StringUtils.hasLength(d.getPlateNumber())) {
					int count = map.getOrDefault(d.getVehicleModel(), 0);
					map.put(d.getVehicleModel(), count+1);
					tatol++;
				}
			}
			//1客户租赁合同、4车辆采购合同
			if("4".equals(item.getContractType())) {
				//交接单车辆大于采购合同车辆数
				if(tatol>=item.getVehicleCount()&&item.getVehicleCount()!=0) {
					item.setStatus("1");
					updateById(item);
				}
			}else if("1".equals(item.getContractType())) {
				boolean pass = true;
				//交接单车辆大于租赁合同车型明细车辆数
				List<TbContractVehicle> vehicleList = contractVehicleService.getByContractId(item.getId());
				if(vehicleList.size()==0) {
					pass = false;
				}
				for (TbContractVehicle type : vehicleList) {
					if(!map.containsKey(type.getVehicleModel())) {
						pass = false;
						break;
					}
					int count = map.get(type.getVehicleModel());
					if(count<type.getQuantity()) {
						pass = false;
						break;
					}
				}
				if(pass) {
					item.setStatus("1");
					updateById(item);
				}
			}
		}
	}
	

    //@Scheduled(cron = "0 */10 * * * ?")
	public void contractStatusTask() {
    	log.info("---------合同状态更新----------");
		String key = CommonConstant.CONTRACK_STATUS_TASK_LOCK;
        String value = lock.getUniqueNum();
        int n  = 0 ;
        try {
            n = lock.getLock(key, value);
            if(n > 0){
            	updateStatus(null);
            }
        }catch (Exception ex){
            log.error("合同状态更新出错, {}", ex);
        }finally {
            //释放锁
            if(n > 0){
                lock.delLock(key, value);
            }
        }
	}
	
	//4采购合同、1租赁合同获取交接车车辆详情数据
	@Override
	public void initVehicleCheckDetail(TbContract item) {
		vehicleCheckDetailService.initVehicleCheckDetail(item);
	}
	
	//初始化车辆价格、保险
	@Override
	public void initItem(TbContract item) {
		if(item.getVehicleList()==null||item.getVehicleList().size()<1) {
			return;
		}
		//1客户租赁合同、4车辆采购合同
		if("4".equals(item.getContractType())) {
			/*Double price = 0d;
			if(item.getVehicleCount()>0) {
				price = new Double(df2.format(item.getTotalPrice()/item.getVehicleCount()/10000));
			}*/
			Map<String,Double> pmap = new HashMap<>();
			if(item.getVehicleDetails()!=null) {
				for(TbContractVehicle d:item.getVehicleDetails()) {
					pmap.put(d.getVehicleModel(), d.getTotalPrice());
				}
			}
			for(TbVehicleCheckDetail d:item.getVehicleList()) {
				if(pmap.containsKey(d.getVehicleModel())) {
					d.setPrice(pmap.get(d.getVehicleModel()));
				}else {
					d.setPrice(0d);
				}
			}
		}else if("1".equals(item.getContractType())) {
			Map<String,TbContractVehicle> violationMap = item.getVehicleDetails().stream().collect(Collectors.toMap(TbContractVehicle::getVehicleModel,Function.identity()));
			
			List<String> vids = item.getVehicleList().stream().map(t->t.getVehicleId()).collect(Collectors.toList());
			Map<String, TbInsurance> insuranceMap = insuranceService.getLastInsurance(vids);
			
			List<TbInsuranceCompanyArchives> coms = insuranceCompanyArchivesService.list();
			Map<String,TbInsuranceCompanyArchives> comsMap = coms.stream().collect(Collectors.toMap(TbInsuranceCompanyArchives::getId,Function.identity()));
			
			for(TbVehicleCheckDetail d:item.getVehicleList()) {
				Double price = 0d;
				if(violationMap.containsKey(d.getVehicleModel())) {
					price = new Double(violationMap.get(d.getVehicleModel()).getTotalPrice());
				}
				d.setPrice(price);
				if(insuranceMap.containsKey(d.getVehicleId())) {
					String insuranceNo = "";
					TbInsurance in = insuranceMap.get(d.getVehicleId());
					if(in==null) {
						continue;
					}
					if("1".equals(in.getHasCommercialInsurance())) {
						insuranceNo = in.getCommercialInsuranceNo();
					}else {
						insuranceNo = in.getCompulsoryInsuranceNo();
					}
					d.setInsuranceNo(insuranceNo);
					if(comsMap.containsKey(in.getCompulsoryCompanyId())) {
						d.setInsuranceName(comsMap.get(in.getCompulsoryCompanyId()).getName());
					}
				}
			}
			
			
		}
	}
	
	@Override
	public Map<String, Double> getCarPrice(String contractId) {
		List<TbContractVehicle> list = contractVehicleService.getByContractId(contractId);
		Map<String,Double> pmap = new HashMap<>();
		for(TbContractVehicle d:list) {
			pmap.put(d.getVehicleModel(), d.getTotalPrice());
		}
		return pmap;
	}
	

}
