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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.common.util.BeanUtilsCopy;
import com.gci.boot.common.util.DateUtils;
import com.gci.boot.common.vo.Result;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.modules.basedata.entity.TbCustomerArchives;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.service.ITbCustomerArchivesService;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.projects.service.IProjectsService;
import com.gci.boot.modules.system.service.impl.SysDictServiceImpl;
import com.gci.boot.modules.system.vo.DictModel;
import com.gci.boot.modules.vehicles.entity.TbRefuelChargeRecord;
import com.gci.boot.modules.vehicles.mapper.TbRefuelChargeRecordMapper;
import com.gci.boot.modules.vehicles.service.ITbRefuelChargeRecordService;
import com.gci.boot.modules.vehicles.vo.TbRefuelChargeRecordImportVo;
import com.gci.boot.modules.vehicles.vo.TbRefuelChargeRecordVo;
import com.gci.boot.modules.vehicles.vo.UpkeepImportVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 加油充电记录 服务实现类
 * </p>
 *
 * @author admin
 * @since 2023-11-30
 */
@Service
public class TbRefuelChargeRecordServiceImpl extends ServiceImpl<TbRefuelChargeRecordMapper, TbRefuelChargeRecord> implements ITbRefuelChargeRecordService {

	@Autowired
	private ITbVehicleService vehicleService;
	@Autowired
	private ITbCustomerArchivesService customerArchivesService;
	@Autowired
	private IProjectsService projectsService;
	@Autowired
	private SysDictServiceImpl sysDictService;
	@Value("${failExcel}")
	private String failExcel;
	
	@Override
	public void saveItem(TbRefuelChargeRecord item) {
		initImte(item);
		saveOrUpdate(item);
	}
	
	public int getByOilCard(String oilCard) {
		if(!StringUtils.hasLength(oilCard)) {
			return 0;
		}
		LambdaQueryWrapper<TbVehicle> query = new LambdaQueryWrapper<>();
		query.eq(TbVehicle::getOilCard, oilCard);
		return vehicleService.count(query);
	}
	
	public void initImte(TbRefuelChargeRecord item) {
		int has = getByOilCard(item.getOilCard());
		if(has>0) {
			item.setRefuelType("1");
		}else {
			item.setRefuelType("2");
		}
		if(!StringUtils.hasLength(item.getOrderNo())) {
			item.setOrderNo("RC"+DateUtils.formatDate(new Date(), DateUtils.HYPHENS_DATETIME4));
		}
		item.setPrice(null);
		if(item.getTotalPrice()!=null&&item.getAmount()!=null&&!item.getAmount().equals(BigDecimal.ZERO)) {
			item.setPrice(item.getTotalPrice().divide(item.getAmount(),2,BigDecimal.ROUND_HALF_UP));
		}
		TbCustomerArchives com = customerArchivesService.getByProjectId(item.getProjectId());
		if(com!=null) {
			item.setSysOrgCode(com.getSysOrgCode());
		}
		//开始结束时间年月日处理
		Calendar recordDateCalendar = Calendar.getInstance();
		recordDateCalendar.setTime(item.getRecordDate());
		if(Objects.nonNull(item.getStartTime())){
			Calendar startTimeCalendar = Calendar.getInstance();
			startTimeCalendar.setTime(item.getStartTime());
			startTimeCalendar.set(Calendar.YEAR, recordDateCalendar.get(Calendar.YEAR));
			startTimeCalendar.set(Calendar.MONTH, recordDateCalendar.get(Calendar.MONTH));
			startTimeCalendar.set(Calendar.DAY_OF_MONTH, recordDateCalendar.get(Calendar.DAY_OF_MONTH));
			item.setStartTime(startTimeCalendar.getTime());
		}
		if(Objects.nonNull(item.getEndTime())){
			Calendar endTimeCalendar = Calendar.getInstance();
			endTimeCalendar.setTime(item.getEndTime());
			endTimeCalendar.set(Calendar.YEAR, recordDateCalendar.get(Calendar.YEAR));
			endTimeCalendar.set(Calendar.MONTH, recordDateCalendar.get(Calendar.MONTH));
			endTimeCalendar.set(Calendar.DAY_OF_MONTH, recordDateCalendar.get(Calendar.DAY_OF_MONTH));
			item.setEndTime(endTimeCalendar.getTime());
		}

	}
	
	@Override
	public Result<?> saveItemBatch(List<TbRefuelChargeRecordImportVo> list) {
		List<TbVehicle> vlist = vehicleService.list();
		Map<String,TbVehicle> vmap = vlist.stream().collect(Collectors.toMap(TbVehicle::getPlateNumber,Function.identity()));
		//查用户所有权限车牌
		List<String> plateNumbers = projectsService.queryAllPlateNumberListOfUser();
		//记录失败的数据
		List<TbRefuelChargeRecordImportVo> failList = new ArrayList<>();
		//油品规格/充电类型
		List<DictModel> oilTypeList = sysDictService.queryDictItemsByCode("oil_type");
		Map<String, String> oilTypeMap = oilTypeList.stream().collect(Collectors.toMap(DictModel::getText, DictModel::getValue));
		for(int i = 0; i< list.size(); i++){
			int flag = 0;
			list.get(i).validate();
			if(CollectionUtil.isNotEmpty(list.get(i).getValidationErrors())){
				flag += 1;
			}
			if(!plateNumbers.contains(list.get(i).getPlateNumber())){
				flag += 1;
				list.get(i).putErrorMsg("当前用户没有该车牌号权限或车辆不存在");
			}
			if(StrUtil.isNotBlank(list.get(i).getStartTime()) || StrUtil.isNotBlank(list.get(i).getEndTime())){
				if(StrUtil.isBlank(list.get(i).getStartTime()) || StrUtil.isBlank(list.get(i).getEndTime())){
					flag += 1;
					list.get(i).putErrorMsg("开始时间、结束时间必须同时存在");
				}
			}
			if(flag == 0){
				try {
					//保存数据
					TbRefuelChargeRecord item = new TbRefuelChargeRecord();
					BeanUtil.copyProperties(list.get(i),item);
					item.setOilType(oilTypeMap.getOrDefault(item.getOilType(),null));

					TbVehicle ve = vmap.get(item.getPlateNumber());
					item.setVehicleId(ve.getId());
					item.setFrameNumber(ve.getFrameNumber());
					item.setVehicleModel(ve.getVehicleModel());
					item.setVehicleType(ve.getVehicleType());
					item.setFuelType(ve.getFuelType());
					item.setProjectId(ve.getProjectId());
					item.setSysOrgCode(ve.getSysOrgCode());
					item.setSourceType("3");
					this.saveItem(item);
				}catch (Exception e){
					e.printStackTrace();
					list.get(i).putErrorMsg(e.getMessage());
					failList.add(list.get(i));
				}
			}else{
				failList.add(list.get(i));
			}
		}
		//处理返回数据
		if (CollectionUtil.isNotEmpty(failList)) {
			JSONObject entries = new JSONObject();
			String fielName =  System.currentTimeMillis() + CommonConstant.REFUEL_CHARGE_RECORD_FAIL_EXCEL_NAME;
			//导出失败数据
			EasyExcel.write(failExcel + fielName, TbRefuelChargeRecordImportVo.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("导入异常数据").doWrite(failList);
			String errorMsg = "已导入"+ (list.size()-failList.size()) + "条;失败"+ failList.size() +"条;具体失败详情见失败导出信息表";

			entries.set("msg",errorMsg);
			entries.set("path",fielName);
			return Result.ok(entries);
		}else{
			return Result.ok();
		}
	}
	
}
