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

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.basedata.entity.TbVehicle;
import com.gci.boot.modules.basedata.mapper.TbVehicleMapper;
import com.gci.boot.modules.basedata.service.ITbVehicleService;
import com.gci.boot.modules.driver.entity.TbDriver;
import com.gci.boot.modules.driver.service.ITbDriverService;
import com.gci.boot.modules.driver.vo.DriverUserVo;
import com.gci.boot.modules.gis.entity.TbGisRunningbus;
import com.gci.boot.modules.gis.service.ITbGisRunningbusService;
import com.gci.boot.modules.projects.entity.ProjectUserRel;
import com.gci.boot.modules.projects.entity.Projects;
import com.gci.boot.modules.projects.mapper.ProjectUserRelMapper;
import com.gci.boot.modules.projects.mapper.ProjectsMapper;
import com.gci.boot.modules.projects.service.IProjectUserRelService;
import com.gci.boot.modules.projects.service.IProjectVehicleBindLogService;
import com.gci.boot.modules.projects.service.IProjectsService;
import com.gci.boot.modules.projects.vo.VehicleTypeVO;
import com.gci.boot.modules.system.entity.SysDepart;
import com.gci.boot.modules.system.entity.SysRole;
import com.gci.boot.modules.system.service.ISysDepartService;
import com.gci.boot.modules.system.service.ISysRoleService;
import com.gci.boot.modules.system.vo.LoginUser;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 项目基础信息表 服务实现类
 * </p>
 *
 * @author xushuhan
 * @since 2023-08-25
 */
@Service
public class ProjectsServiceImpl extends ServiceImpl<ProjectsMapper, Projects> implements IProjectsService {

	public  final String PROJECT_ID = "project_id";
	@Autowired
    private ITbVehicleService iTbVehicleService;

	@Autowired
	private IProjectVehicleBindLogService projectVehicleBindLogService;

	@Autowired
	private TbVehicleMapper tbVehicleMapper;

	@Autowired
	private ProjectsMapper projectsMapper;

	@Autowired
	private ISysDepartService sysDepartService;

	@Autowired
	private ISysRoleService sysRoleService;

	@Autowired
	private ITbDriverService tbDriverService;

	@Autowired
	private ProjectUserRelMapper projectUserRelMapper;

	@Autowired
	private IProjectUserRelService projectUserRelService;
	@Autowired
	private ITbGisRunningbusService gisRunningbusService;

	@Override
	@Transactional
	public void saveItem(Projects item,String createBy) {
		if (CommonConstant.INNER_PROJECT.equals(item.getId())) {
			item.setCustomerId(null);
		}
		checkItem(item);
		String busIds = item.getBusIds();
		String oldBusIds = "";
		boolean needLog = false,edit = false;
		// 说明是更新，否则为新增
		if (StringUtils.isNotEmpty(item.getId())) {
			edit = true;
			List<String> oldIds = getVehicleIdsByProjectId(item.getId());
			oldBusIds = oldIds.isEmpty() ? "" : String.join(",", oldIds);
		} else {
			if (StringUtils.isNotEmpty(busIds)) {
				needLog = true;
			}
		}
		item.setHisVehicleId(busIds);
		if (StringUtils.isNotEmpty(item.getId())) {
			updateById(item);
		}else{
			save(item);
		}
		// 清除项目 ID
		tbVehicleMapper.clearProductId(item.getId());
		if (StringUtils.isNotEmpty(busIds)) {
			List<String> busIdList = Arrays.asList(busIds.split(","));
			updateVehicleProjectId(busIdList, item.getId());
		}
		if (needLog) {
			List<String> plateNumbers = getPlateNumbersByVehicleIds(Arrays.asList(busIds.split(",")));
			projectVehicleBindLogService.addBatchLog(item.getId(), item.getProjectName(), plateNumbers, 1, 3, createBy);
		}
		if (edit && !oldBusIds.equals(busIds)) {
			List<String> oldBusIdList = new ArrayList<>();
			List<String> editBusIdList = new ArrayList<>();
			try {
				oldBusIdList = Arrays.asList(oldBusIds.split(","));
			} catch (Exception e) {
			}
			try {
				editBusIdList = Arrays.asList(busIds.split(","));
			} catch (Exception e) {
			}
			// 解绑的
			List<String> unbindVehicleIds = new ArrayList<>(oldBusIdList);
			unbindVehicleIds.removeAll(editBusIdList);

			if (!unbindVehicleIds.isEmpty()) {
				List<String> unbindPlateNumbers = getPlateNumbersByVehicleIds(unbindVehicleIds);
				projectVehicleBindLogService.addBatchLog(item.getId(), item.getProjectName(), unbindPlateNumbers, 2, 3, createBy);
			}
			// 新绑定的
			List<String> bindVehicleIds = new ArrayList<>(editBusIdList);
			bindVehicleIds.removeAll(oldBusIdList);

			if (!bindVehicleIds.isEmpty()) {
				List<String> bindPlateNumbers = getPlateNumbersByVehicleIds(bindVehicleIds);
				projectVehicleBindLogService.addBatchLog(item.getId(), item.getProjectName(), bindPlateNumbers, 1, 3, createBy);
			}

		}
		//保存项目和成员关系
		if(StringUtils.isNotEmpty(item.getId())){
			QueryWrapper<ProjectUserRel> delQueryWrapper = new QueryWrapper<>();
			delQueryWrapper.eq("project_id", item.getId());
			projectUserRelMapper.delete(delQueryWrapper);
		}

		if(StringUtils.isNotEmpty(item.getUserIds())){
			String[] arrUserId = item.getUserIds().split(",");
			if(ArrayUtils.isNotEmpty(arrUserId)){
				List<ProjectUserRel> listProjUserRel = new ArrayList<>();
				for(String userId: arrUserId){
					ProjectUserRel projectUser = new ProjectUserRel();
					projectUser.setProjectId(item.getId());
					projectUser.setUserId(userId);
					listProjUserRel.add(projectUser);
				}
				projectUserRelService.saveBatch(listProjUserRel);
			}
		}
	}

	public void checkItem(Projects item) {
		if(item.getStartDate().after(item.getEndDate())) {
			throw new GciBootException("开始日期不能大于结束日期");
		}
		String name = item.getProjectName().trim();
		if(StringUtils.isEmpty(name)) {
			throw new GciBootException("项目名称不能为空");
		}
		QueryWrapper<Projects> queryWrapper = new QueryWrapper<>();
		queryWrapper.ne(StringUtils.isNotEmpty(item.getId()),"id", item.getId());
		queryWrapper.eq("project_name", name);
		int count = count(queryWrapper);
		if(count>0) {
			throw new GciBootException("项目名称不能重复");
		}
	}

	@Override
	public void initBusId(Projects item) {
		QueryWrapper<TbVehicle> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("project_id", item.getId());
		List<TbVehicle> list = tbVehicleMapper.selectList(queryWrapper);
		String busIds = null;
		for (TbVehicle tbVehicle : list) {
			if(busIds==null) {
				busIds = tbVehicle.getId();
			}else {
				busIds += ","+tbVehicle.getId();
			}
		}
		item.setBusIds(busIds);
	}

	@Override
	public void initUserId(Projects item) {
		QueryWrapper<ProjectUserRel> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("project_id", item.getId());
		List<ProjectUserRel> list = projectUserRelMapper.selectList(queryWrapper);
		String userIds = null;
		for (ProjectUserRel projectUserRel : list) {
			if(userIds==null) {
				userIds = projectUserRel.getUserId();
			}else {
				userIds += ","+projectUserRel.getUserId();
			}
		}
		item.setUserIds(userIds);
	}

	@Override
	@Transactional
	public void updateStatus(Projects item,String createBy) {
		if(CommonConstant.STATUS_1.equals(item.getStatus())) {
			QueryWrapper<TbVehicle> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq("project_id", item.getId());
			List<TbVehicle> list = tbVehicleMapper.selectList(queryWrapper);
			String busIds = list.stream().map(a->{return a.getId();}).collect(Collectors.joining(","));
			List<String> plateNumbers = list.stream().map(a->{return a.getPlateNumber();}).collect(Collectors.toList());
			item.setBusIds(busIds);
			if(StringUtils.isNotEmpty(item.getBusIds())) {
				item.setHisVehicleId(item.getBusIds());
			}
			item.setStatus(CommonConstant.STATUS_0);
			updateById(item);
			tbVehicleMapper.clearProductId(item.getId());
			if(!plateNumbers.isEmpty()){
				projectVehicleBindLogService.addBatchLog(item.getId(),item.getProjectName(),plateNumbers,2,3,createBy);
			}
		}else if(CommonConstant.STATUS_0.equals(item.getStatus())) {
			item.setStatus(CommonConstant.STATUS_1);
			updateById(item);
		}
	}

	@Override
	public List<String> queryProjectListOfUser() {
		final List<String> result = new ArrayList<>();
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if(sysUser==null || org.apache.commons.lang3.StringUtils.isEmpty(sysUser.getId())){
			throw new RuntimeException("用户未登录");
		}
		List<SysDepart> departList = sysDepartService.getDepartByUserId(sysUser.getId());
		//flag标识是否是客户公司身份 1_普通部门,2_维修厂,3_客户公司
		int departCategory = 0;
		boolean flag = false;
		List<String> listDepart = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(departList)){
			for(SysDepart depart: departList){
				if(depart.getOrgCategory()==1){
					departCategory = 1;
					break;
				}else if(depart.getOrgCategory()==2){
					if(departCategory == 0){
						departCategory = 2;
					}
					return result;
				}else if(depart.getOrgCategory()==3){
					departCategory = 3;
					listDepart.add(depart.getOrgCode());
				}
			}
		}
		//按照部门类型依次处理：1、内部员工，2、客户人员（司机、客户管理员），3、其他人员
		if(departCategory == 1){
			List<ProjectUserRel> listProjectUserRel = projectUserRelMapper.selectList(new QueryWrapper<ProjectUserRel>().eq("user_id", sysUser.getId()));
			listProjectUserRel.stream().forEach(rel -> {
				result.add(rel.getProjectId());
			});
		}else if(departCategory == 3){
			TbDriver tbDiver = tbDriverService.getOne(new QueryWrapper<TbDriver>().eq("user_id", sysUser.getId()));
			if(tbDiver != null && tbDiver.getId() != null && org.apache.commons.lang3.StringUtils.isNotEmpty(tbDiver.getProjectId())){
				//处理司机的情况
				String[] projectIdStr = tbDiver.getProjectId().split(",");
				if(ArrayUtils.isNotEmpty(projectIdStr)){
					for(String projectIdDriver: projectIdStr){
						result.add(projectIdDriver);
					}
				}
			}else{
				//处理客户其他人员的情况
				List<Projects> projectsByDepartCodes = projectsMapper.getProjectsByDepartCodes(listDepart);
				projectsByDepartCodes.stream().forEach(proj -> {
					result.add(proj.getId());
				});
			}
		}
		return result;
	}

	@Override
	public List<Projects> listAll() {
		QueryWrapper<Projects> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("cancel_flag",0);
		return this.projectsMapper.selectList(queryWrapper);
	}

	/**
	 * 处理逻辑：有效看是否有普通部门，作为内部员工处理，其次判断客户公司和维修厂
	 * @return
	 */
	@Override
	public Integer judgeDepartCategory() {
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if(sysUser==null || org.apache.commons.lang3.StringUtils.isEmpty(sysUser.getId())){
			throw new RuntimeException("用户未登录");
		}
		List<SysDepart> departList = sysDepartService.getDepartByUserId(sysUser.getId());
		//判断用户身份： 1_普通部门,2_维修厂,3_司机，4_客户公司其他人员，5_超级管理员，0、其他身份
		int departCategory = 0;
		//获取角色，判断是否包含超级管理员
		List<SysRole> listRole = sysRoleService.getRoleByUserId(sysUser.getId());
		if(CollectionUtils.isEmpty(listRole)){
			//角色配置为空
			throw new RuntimeException("角色配置为空");
		}
		StringBuilder sbRole = new StringBuilder();
		listRole.forEach(lRole -> {
			sbRole.append(","+lRole.getRoleCode());
		});
		String strRole = sbRole.toString();
		if(strRole.contains("PM0000")){
			return 5;
		}

		List<String> listDepart = new ArrayList<>();
		if(CollectionUtils.isNotEmpty(departList)){
			for(SysDepart depart: departList){
				if(depart.getOrgCategory()==1){
					departCategory = 1;
					break;
				}else if(depart.getOrgCategory()==2){
					if(departCategory == 0){
						departCategory = 2;
					}
				}else if(depart.getOrgCategory()==3){
					TbDriver tbDiver = tbDriverService.getOne(new QueryWrapper<TbDriver>().eq("user_id", sysUser.getId()));
					if(tbDiver != null && tbDiver.getId() != null){
						//处理司机的情况
						departCategory = 3;
					}else{
						//公司的其他人员
						if(departCategory == 0 || departCategory == 2){
							departCategory = 4;
						}
					}
				}
			}
		}
		return departCategory;
	}

	@Override
	public String getVehicleTypeNumStr(String vehicleIdsStr) {
		if(StrUtil.isBlank(vehicleIdsStr)){
			return null;
		}
		List<String> vehicleIds = Arrays.asList(vehicleIdsStr.split(","));
		List<VehicleTypeVO> list = projectsMapper.queryVehicleTypeNum(vehicleIds);
		if(CollectionUtils.isNotEmpty(list)){
			String str = "";
			for (VehicleTypeVO vehicleTypeVO : list){
				str += vehicleTypeVO.getItemText() + ":" + vehicleTypeVO.getCount() + "辆";
				if(list.indexOf(vehicleTypeVO)!= list.size()-1){
					str += ",";
				}else{
					str += "。";
				}
			}
			return str;
		}
		return null;
	}

	@Override
	public IPage<Projects> getPage(IPage page, Wrapper wrapper) {
		IPage<Projects> pageList = projectsMapper.getPage(page, wrapper);
		return pageList;
	}

	@Override
	public List<Projects> getAllProjectsAuth() {
		List<Projects> list = projectsMapper.getAllProjectsAuth();
		return list;
	}

	@Override
	public List<String> queryAllProjectListOfUser() {
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if(sysUser==null || StringUtils.isEmpty(sysUser.getId())){
			return null;
		}
		//获取角色：为判断超级管理员准备
		List<SysRole> listRole = sysRoleService.getRoleByUserId(sysUser.getId());
		if(CollectionUtils.isEmpty(listRole)){
			return null;
		}
		StringBuilder sbRole = new StringBuilder();
		listRole.forEach(lRole -> {
			sbRole.append(","+lRole.getRoleCode());
		});
		String strRole = sbRole.toString();
		if(strRole.contains("PM0000")){
			List<Projects> allList = this.getAllProjectsAuth();
			if(CollectionUtils.isNotEmpty(allList)){
				return allList.stream().map(Projects::getId).collect(Collectors.toList());
			}else{
				return null;
			}
		}
		return this.queryProjectListOfUser();
	}

	@Override
	public List<TbVehicle> queryAllVehicleListOfUser() {
		//获取项目id
		List<String> projectIds = this.queryAllProjectListOfUser();
		if(Objects.isNull(projectIds)){
			projectIds = new ArrayList<>();
			projectIds.add("No Permission");
		}
		//获取车牌信息
		LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TbVehicle::getCancelFlag,0)
				.in(TbVehicle::getProjectId,projectIds);
		List<TbVehicle> vehicles = tbVehicleMapper.selectList(queryWrapper);
		return vehicles;
	}

	@Override
	public List<String> queryAllPlateNumberListOfUser() {
		//获取项目id
		List<String> projectIds = this.queryAllProjectListOfUser();
		if(CollectionUtils.isEmpty(projectIds)){
			projectIds = new ArrayList<>();
			projectIds.add("No Permission");
		}
		//获取车牌信息
		LambdaQueryWrapper<TbVehicle> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(TbVehicle::getCancelFlag,0)
				.in(TbVehicle::getProjectId,projectIds);
		List<TbVehicle> vehicles = tbVehicleMapper.selectList(queryWrapper);
		if(CollectionUtils.isNotEmpty(vehicles)){
			return vehicles.stream().map(TbVehicle::getPlateNumber).collect(Collectors.toList());
		}else{
			return new ArrayList<>();
		}
	}

	/**
	 * 获取车辆车牌号方法
	 * @param vehicleIds
	 * @return
	 */
	private List<String> getPlateNumbersByVehicleIds(List<String> vehicleIds) {
		QueryWrapper<TbVehicle> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("id", vehicleIds);
		List<TbVehicle> vehicles = tbVehicleMapper.selectList(queryWrapper);
		return vehicles.stream().map(TbVehicle::getPlateNumber).collect(Collectors.toList());
	}

	private List<String> getVehicleIdsByProjectId(String projectId) {
		QueryWrapper<TbVehicle> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(PROJECT_ID, projectId);
		List<TbVehicle> list = tbVehicleMapper.selectList(queryWrapper);
		return list.stream().map(TbVehicle::getId).collect(Collectors.toList());
	}


	/**
	 * 更新方法
	 * @param vehicleIds
	 * @param projectId
	 */
	private void updateVehicleProjectId(List<String> vehicleIds, String projectId) {
		QueryWrapper<TbVehicle> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("id", vehicleIds);
		queryWrapper.and(w -> w.eq(PROJECT_ID, CommonConstant.INNER_PROJECT).or().isNull(PROJECT_ID));
		TbVehicle bus = new TbVehicle();
		bus.setProjectId(projectId);
		tbVehicleMapper.update(bus, queryWrapper);
		//更新runningBus项目id
		CompletableFuture.runAsync(() -> {
			List<String> plateNumbers = this.getPlateNumbersByVehicleIds(vehicleIds);
			if(CollectionUtils.isNotEmpty(plateNumbers)){
				gisRunningbusService.update(new LambdaUpdateWrapper<TbGisRunningbus>().in(TbGisRunningbus::getPlateNumber,plateNumbers)
						.set(TbGisRunningbus::getProjectId,projectId));
			}
		});
	}

}
