package com.pj.project.tb_vehicle;

import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.pj.api.client.level_one_server.LevelOneServerInterface;
import com.pj.api.dto.OrderDto;
import com.pj.api.dto.VehicleDto;
import com.pj.common.core.exception.ServiceException;
import com.pj.enummj.AuditStatus;
import com.pj.enummj.DeleteStatus;
import com.pj.enummj.VehicleStatus;
import com.pj.project.tb_car_record.TbCarRecord;
import com.pj.project.tb_car_record.TbCarRecordMapper;
import com.pj.project.tb_driver.TbDriver;
import com.pj.project.tb_driver.TbDriverMapper;
import com.pj.project.tb_vehicle.param.MakeCarRecordParam;
import com.pj.project.tb_vehicle.vo.TbVehicleVo;
import com.pj.retry.SmsRetryService;
import com.pj.utils.so.SoMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.swing.filechooser.FileSystemView;

/**
 * Service: tb_vehicle -- 车辆
 * @author loovi
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TbVehicleService extends ServiceImpl<TbVehicleMapper, TbVehicle> implements IService<TbVehicle>{

	/** 底层 Mapper 对象 */
	@Autowired
	TbVehicleMapper tbVehicleMapper;

	@Autowired
	private MethodVehicleService methodVehicleService;

	@Autowired
	private TbDriverMapper tbDriverMapper;

	@Autowired
	private SmsRetryService smsRetryService;

	@Autowired
	private LevelOneServerInterface levelOneServerInterface;

	@Autowired
	private TbCarRecordMapper tbCarRecordMapper;

	/** 增 */
	void add(TbVehicle t){
		t.setCreateTime(new Date());
		save(t);
	}

	/** 删 */
	void delete(Long id){
		removeById(id);
	}

	/** 改 */
	void update(TbVehicle t){
		t.setUpdateTime(new Date());
		updateById(t);

	}

	/** 查 */
	TbVehicle getById(Long id){
		return super.getById(id);
	}

	/** 查集合 - 根据条件（参数为空时代表忽略指定条件） */
	List<TbVehicle> getList(SoMap so) {
		return tbVehicleMapper.getList(so);
	}

	/** 查 - 根据车牌号查车辆信息 */
	List<TbVehicle> getByVehiclePlate(String vehiclePlate) {

		List<TbVehicle> tbVehicle = tbVehicleMapper.selectList(new LambdaQueryWrapper<TbVehicle>()
				.like(TbVehicle::getVehiclePlate, vehiclePlate) //车牌号
				.eq(TbVehicle::getVehicleStatus, 1)//车辆状态:1=空闲
				.eq(TbVehicle::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode()));
		return tbVehicle;
	}

	/** 改 - 根据车辆Id修改车辆状态 */
	boolean updateStatusByVehicleId(TbVehicleVo vehicleVo) {

		LambdaUpdateWrapper<TbVehicle> wrapper = new LambdaUpdateWrapper<>();
		wrapper.set(TbVehicle::getVehicleStatus, vehicleVo.getVehicleStatus());
		wrapper.eq(TbVehicle::getId, vehicleVo.getId());

		return this.update(wrapper);
	}

	/** TODO: 向第三方系统发送车辆状态（预留发送接口） */
	void sendVehicleStatus(){

	}

	/**
	 * 商户确定车辆后执行通知司机
	 * @param makeCarRecordParam
	 * @return
	 * @throws Exception
	 */
	public boolean informDriver(MakeCarRecordParam makeCarRecordParam) throws Exception {
		//防止重复叫车
		Integer tbCarRecords = tbCarRecordMapper.selectCount
				(new LambdaQueryWrapper<TbCarRecord>()
						.eq(TbCarRecord::getOrderId, makeCarRecordParam.getOrderId())
						.eq(TbCarRecord::getEnterpriseId, makeCarRecordParam.getEnterpriseId())
						.ne(TbCarRecord::getDriverResult,2) // 非司机拒绝,大于1
						.eq(TbCarRecord::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode()));
		if(tbCarRecords != 0)throw new ServiceException("您当前订单已正在叫车中,请勿重复叫车~");
		//通过driverId查询司机表
		TbDriver tbDriver = tbDriverMapper.selectById(makeCarRecordParam.getDriverId());
		if(tbDriver == null)throw new ServiceException("司机信息有误!");
		//获取司机号码
		String phone = tbDriver.getPhone();
		//todo: 执行通知
//		boolean smsMsg = smsRetryService.sendSmsMsg(phone);
		//创建叫车记录
		TbCarRecord tbCarRecord = methodVehicleService.makeCarRecord(makeCarRecordParam);
		int insert = tbCarRecordMapper.insert(tbCarRecord);

		if(insert == 1){
			//修改一级订单表叫车状态
			OrderDto orderDto = levelOneServerInterface.getOrderDtoById(makeCarRecordParam.getOrderId());
			orderDto.setCallCarStatus(1); // 1=已叫车状态
			boolean b = levelOneServerInterface.updateOrderCallCarStatus(orderDto);
			if(!b)throw new ServiceException("一级市场订单表状态异常!");
		}
		return insert == 1;
	}

	/**
	 * 车辆出一级市
	 * 场，一级市场
	 * 交易完成
	 */
	public void vehicleMessageFromHT(){
		//todo: 8月27日 航通将车辆出一级市场信息发送过来时,一级市场订单已完成
		//1. 一级市场交易完成；边民需要付款给到外籍商户

		//1.1 创建[边民支付信息表],明确需要进行支付的边民数量,将每个主要支付的边民逐条保存到[便民支付信息表]内 ,边民在app内发起支付

		//2. 调用银行的sdk,银行将边民存放于第三方账户的钱划扣给外籍收购商户,并获取银行的返回结果

		//3. 获取银行返回的回执信息,修改[边民支付信息表]的支付状态(通常不存在支付失败的情况)

		//4. 判断边民的支付完成数量,更新我方订单状态

		//5. 如果该订单支付状态为[已完成],将划扣等信息同步至航通或将每个边民划扣信息逐条同步至航通???

		//6. todo: 调用系统message和短信,通知边民上架货物至二级市场???
	}



	/** 同步航通的车辆信息 */
	public boolean vehicleDto(VehicleDto vehicleDto){
		TbVehicle tbVehicle = new TbVehicle();
		List<TbVehicle> tbVehicles = tbVehicleMapper.selectList(new LambdaQueryWrapper<TbVehicle>().eq(TbVehicle::getPlatSeqNo, tbVehicle.getPlatSeqNo()));
		//根据集合大小判断新增
		if(tbVehicles.size() == 0){
			BeanUtils.copyProperties(vehicleDto,tbVehicle);
			//设置基本字段
			tbVehicle.setCreateName("航通"); // 创建单位
			tbVehicle.setCreateTime(new Date()); // 创建时间
			tbVehicle.setAuditStatus(AuditStatus.AUDIT_STATUS_ON.getCode()); // 审核状态,默认审核已通过
			tbVehicle.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode()); // 删除状态,默认可用
			tbVehicle.setVehicleStatus(VehicleStatus.VEHICLE_STATUS_ZERO.getCode()); // 车辆工作状态,默认空闲中
			//执行保存
			int insert = tbVehicleMapper.insert(tbVehicle);
			return insert == 1;
		}
		//修改
//		if(tbVehicles.size() != 1)throw new ServiceException("车辆状态异常。请联系管理员");
		BeanUtils.copyProperties(tbVehicles.get(0),tbVehicle);
		BeanUtils.copyProperties(vehicleDto,tbVehicle);
		int i = tbVehicleMapper.updateById(tbVehicle);
		return i == 1;
	}












	/**
	 * 导入
	 * @param file excel文件
	 * @return
	 * @throws IOException
	 */
	public String importData(MultipartFile file) throws IOException {
		System.out.println("\n开始执行文件上传....\n");

		//判空
		if(file.isEmpty()) return "文件为空,无法执行上传...";
		//获取文件上传数据
		HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
		//获取第一页sheet
		HSSFSheet sheet = wb.getSheetAt(0);
		//定义计数器
		int count = 0;
		//定义行对象
		HSSFRow row = null;
		//解析数据封装到集合
		count = methodVehicleService.importMethod(row, sheet, count);
		wb.close();
		System.out.println("\n文件上传完成,共上传 " + count + "条 " + "数据...\n");
		return "上传完成,共上传"  + count + "条"  + "数据。";
	}

	/**
	 * 导出 excel文件
	 * @param keyword
	 * @return
	 */
	public String outportExcel(String keyword,String filepath) throws IOException {
		System.out.println("\n开始执行文件导出....\n");
		//导出的文件的路径
		if(filepath == null){
			// 获取当前用户的桌面路径
			FileSystemView fileSystemView = FileSystemView.getFileSystemView();
			filepath = fileSystemView.getHomeDirectory().getPath();
		}
		filepath = filepath + "\\车辆信息数据表_" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".xlsx";
		//根据需求查询数据
		List<TbVehicle> selectedList = tbVehicleMapper.selectList(new LambdaQueryWrapper<TbVehicle>().eq(StringUtils.isNoneBlank(keyword), TbVehicle::getOwner, keyword));
		if(selectedList.size() == 0)return "没有可导出的数据。";
		//建立excel对象封装数据
		HSSFWorkbook workbook = new HSSFWorkbook();
		//创建excel表格右下角的sheet页名称
		HSSFSheet sheet = workbook.createSheet("1");
		//创建表头
		HSSFRow row = sheet.createRow(0);
		row.createCell(0).setCellValue("序号");
		row.createCell(1).setCellValue("车辆");
		row.createCell(2).setCellValue("所有人");
		row.createCell(3).setCellValue("车辆类型");
		row.createCell(4).setCellValue("类型父id");
		row.createCell(5).setCellValue("车辆尺寸");
		row.createCell(6).setCellValue("车辆品牌型号");
		row.createCell(7).setCellValue("核定载质量");
		row.createCell(8).setCellValue("车辆自重");
		row.createCell(9).setCellValue("审核状态");
		row.createCell(10).setCellValue("审核人");
		row.createCell(11).setCellValue("审核不通过原因");
		row.createCell(12).setCellValue("审核时间");

		row.createCell(13).setCellValue("创建时间");
		row.createCell(14).setCellValue("创建人编号");
		row.createCell(15).setCellValue("创建人名称");
		row.createCell(16).setCellValue("更新时间");
		row.createCell(17).setCellValue("更新人编号");
		row.createCell(18).setCellValue("更新人名称");
		row.createCell(19).setCellValue("删除状态");

		//定义计数器
		int count = 0;
		//遍历集合
		for (int i = 0; i < selectedList.size(); i++) {
			HSSFRow sheetRow = sheet.createRow(sheet.getLastRowNum() + 1);
			sheetRow.createCell(0).setCellValue(i + 1);
			sheetRow.createCell(1).setCellValue((selectedList.get(i).getVehiclePlate() + "").equals("null")? "": selectedList.get(i).getVehiclePlate() + "");
			sheetRow.createCell(2).setCellValue((selectedList.get(i).getOwner() + "").equals("null")? "": selectedList.get(i).getOwner() + "");
			sheetRow.createCell(3).setCellValue((selectedList.get(i).getVehicleType() + "").equals("null")? "": selectedList.get(i).getVehicleType() + "");
			sheetRow.createCell(4).setCellValue((selectedList.get(i).getParentId() + "").equals("null")? "": selectedList.get(i).getParentId() + "");
			sheetRow.createCell(5).setCellValue((selectedList.get(i).getVehicleSize() + "").equals("null")? "": selectedList.get(i).getVehicleSize() + "");
			sheetRow.createCell(6).setCellValue((selectedList.get(i).getVehicleModel() + "").equals("null")? "": selectedList.get(i).getVehicleModel() + "");
			sheetRow.createCell(7).setCellValue((selectedList.get(i).getVehicleLoad() + "").equals("null")? "": selectedList.get(i).getVehicleLoad() + "");
			sheetRow.createCell(8).setCellValue((selectedList.get(i).getVehicleWeight() + "" ).equals("null")? "": selectedList.get(i).getVehicleWeight() + "");
			sheetRow.createCell(9).setCellValue((selectedList.get(i).getAuditStatus() + "").equals("null")? "": selectedList.get(i).getAuditStatus() + "");
			sheetRow.createCell(10).setCellValue((selectedList.get(i).getAuditBy() + "").equals("null")? "": selectedList.get(i).getAuditBy() + "");
			sheetRow.createCell(11).setCellValue((selectedList.get(i).getNopassReason() + "").equals("null")? "": selectedList.get(i).getNopassReason() + "");
			sheetRow.createCell(12).setCellValue((selectedList.get(i).getAuditTime() + "").equals("null")? "": selectedList.get(i).getAuditTime() + "");
			//公共字段
			sheetRow.createCell(13).setCellValue((selectedList.get(i).getCreateTime() + "").equals("null")? "": selectedList.get(i).getCreateTime() + "");
			sheetRow.createCell(14).setCellValue((selectedList.get(i).getCreateBy() + "").equals("null")? "": selectedList.get(i).getCreateBy() + "");
			sheetRow.createCell(15).setCellValue((selectedList.get(i).getCreateName() + "").equals("null")? "": selectedList.get(i).getCreateName() + "");
			sheetRow.createCell(16).setCellValue((selectedList.get(i).getUpdateTime() + "").equals("null")? "": selectedList.get(i).getUpdateTime() + "");
			sheetRow.createCell(17).setCellValue((selectedList.get(i).getUpdateBy() + "").equals("null")? "": selectedList.get(i).getUpdateBy() + "");
			sheetRow.createCell(18).setCellValue((selectedList.get(i).getUpdateName() + "").equals("null")? "": selectedList.get(i).getUpdateName() + "");
			sheetRow.createCell(19).setCellValue((selectedList.get(i).getDeleteStatus() + "").equals("null")? "": selectedList.get(i).getDeleteStatus() + "");
			count += 1;
		}
		//建立输出流，输出文件
		FileOutputStream fos = new FileOutputStream(filepath);

		workbook.write(fos);
		fos.flush();
		//关闭输出流
		fos.close();
		workbook.close();
		System.out.println("\n数据导出完成!共导出 " + count + " 条数据。");
		return "数据导出完成!共导出 " + count + " 条数据。";
	}
}
