package com.ruoyi.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.BladeRegion;
import com.ruoyi.system.mapper.BladeRegionMapper;
import com.ruoyi.system.service.IBladeRegionService;

/**
 * 行政区划Service业务层处理
 * 
 * @author dm
 * @date 2023-02-13
 */
@Service
@Transactional
public class BladeRegionServiceImpl implements IBladeRegionService {

	@Autowired
	private BladeRegionMapper bladeRegionMapper;

	@Autowired
	private RedisCache redisCache;

	private static final Logger logger = LoggerFactory.getLogger(BladeRegionServiceImpl.class);

	public static Boolean useLocalCache = true;

	private static ThreadLocal<Map<String, BladeRegion>> localVar = new ThreadLocal<Map<String, BladeRegion>>();

//	private static ThreadLocal<Map<String, Boolean>> localBooleanVar = new ThreadLocal<Map<String, Boolean>>();

	private static ThreadLocal<Map<String, Object>> localObjectVar = new ThreadLocal<Map<String, Object>>();

	private boolean isIgnoreBladeRegion(String name) {
		if (StringUtils.isBlank(name)) {
			return true;
		}
		if ("00".equals(name) || "0000".equals(name) || "00000".equals(name) || "000000".equals(name) || "非本区划".equals(name)) {
			return true;
		}
		return false;
	}

	@Override
	public BladeRegion selectByProvinceName(String name) {
		// TODO Auto-generated method stub
		if (isIgnoreBladeRegion(name)) {
			return null;
		}

		String key = "Region:selectByProvinceName:" + name;

		if (useLocalCache) {
			if (localVar.get() == null) {
				localVar.set(new HashMap<String, BladeRegion>());
			}
			BladeRegion bladeRegion = localVar.get().get(key);
			if (bladeRegion != null) {
				return bladeRegion;
			}
		}
		BladeRegion bladeRegion = null;
//		BladeRegion bladeRegion = redisCache.getCacheObject(key);
//		if (bladeRegion != null) {
//			return bladeRegion;
//		}

		BladeRegion qo = new BladeRegion();
		qo.setName(name);
		List<BladeRegion> list = selectList(qo);
		if (list != null && !list.isEmpty()) {
			bladeRegion = list.get(0);
			if (bladeRegion != null) {

				if (useLocalCache) {
					localVar.get().put(key, bladeRegion);
				}
//				redisCache.setCacheObject(key, bladeRegion);
			}

		} else {
			logger.warn("没有查询到行政区划数据,key:" + key);
		}
		return bladeRegion;
	}

	private String getStr(Map map, String key) {
		if (map == null || key == null || !map.containsKey(key)) {
			return "";
		}
		return map.get(key).toString().trim();
	}

//	public Boolean isNotThisArea(String cityCode, String areaCode, List<String> allCodeList,
//			Map<String, Boolean> alreadyMap) {
//		if (StringUtils.isBlank(areaCode)) {
//			return true;
//		}
//		Boolean rrr = alreadyMap.get(areaCode);
//		if (rrr != null) {
//			return rrr;
//		}
//
//		areaCode = areaCode.trim();
//		if (StringUtils.isNotBlank(cityCode) && !areaCode.startsWith(cityCode)) {
//			return true;
//		}
//
//		Boolean res = false;
////		String key = "Region:isNotThisArea:" + cityCode + ":areaCode:" + areaCode;
//
////		logger.info("判断非本区划:" + cityCode + "," + areaCode);
////		List<String>allCodeList=getAllArea();
//
////		logger.info("开始循环判断非本区划:" + cityCode + "," + areaCode);
//		if (!allCodeList.contains(areaCode)) {
//			res = true;
//		}
////		logger.info("判断非本区划完成:" + cityCode + "," + areaCode);
//
////		if (useLocalCache) {
////			localBooleanVar.get().put(key, res);
////		}
////		redisCache.setCacheObject(key, res);
//		return res;
//	}

	public List<String> getAllAreaCode() {
		String key = "Region:getAllArea";

		if (useLocalCache) {
			if (localObjectVar.get() == null) {
				localObjectVar.set(new HashMap<String, Object>());
			}
			Object obj = localObjectVar.get().get(key);
			if (obj != null) {
				logger.info("非本区划本地缓存命中");
				return (List<String>) obj;
			}
		}

		List<String> list = redisCache.getCacheObject(key);
		if (list != null && !list.isEmpty()) {
			if (useLocalCache) {
				localObjectVar.get().put(key, list);
			}
			logger.info("非本区划redis缓存命中");
			return list;
		}
		List<BladeRegion> brList = selectAllAreaList();
		List<String> codeList = new ArrayList<String>();
		for (BladeRegion br : brList) {
			codeList.add(br.getCode());
		}

		if (useLocalCache) {
			localObjectVar.get().put(key, codeList);
		}
		redisCache.setCacheObject(key, codeList);

		logger.info("非本区划缓存没有命中");
		return codeList;
	}

	public BladeRegion selectByCityShortName(String cityName, String provinceCode) {
		if (isIgnoreBladeRegion(cityName)) {
			return null;
		}
		if (StringUtils.isBlank(cityName) || StringUtils.isBlank(provinceCode)) {
			return null;
		}

		String key = "Region:selectByCityShortName:" + cityName + ":provinceCode:" + provinceCode;

		if (useLocalCache) {
			if (localVar.get() == null) {
				localVar.set(new HashMap<String, BladeRegion>());
			}
			BladeRegion bladeRegion = localVar.get().get(key);
			if (bladeRegion != null) {
				return bladeRegion;
			}
		}
		BladeRegion bladeRegion = null;
//		BladeRegion bladeRegion = redisCache.getCacheObject(key);
//		if (bladeRegion != null) {
//			return bladeRegion;
//		}

		BladeRegion qo = new BladeRegion();
		qo.setCityShortName(cityName);
		qo.setParentCode(provinceCode);
		List<BladeRegion> list = selectList(qo);
		if (list != null && !list.isEmpty()) {
			bladeRegion = list.get(0);
			if (bladeRegion != null) {
				if (useLocalCache) {
					localVar.get().put(key, bladeRegion);
				}
//				redisCache.setCacheObject(key, bladeRegion);
			}

		}else {
			logger.warn("没有查询到行政区划数据,key:" + key);
		}
		return bladeRegion;

	}

	/**
	 * 查询行政区划
	 * 
	 * @param code 行政区划主键
	 * @return 行政区划
	 */
//	@Override
//	public BladeRegion selectBladeRegionByCode(String code) {
//		return selectByCode(code);
////		String key = getReginCodeKey(code);
////
////		BladeRegion bladeRegion = redisCache.getCacheObject(key);
////
////		if (bladeRegion != null) {
//////			logger.debug("行政区划缓存命中,code:"+code);
////			return bladeRegion;
////		} else {
////			logger.debug("行政区划缓存没有命中,code:" + code);
////
////			bladeRegion = bladeRegionMapper.selectBladeRegionByCode(code);
////			if (bladeRegion != null) {
////				redisCache.setCacheObject(key, bladeRegion);
////			}
////		}
////
////		return bladeRegion;
//	}

	@Override
	public BladeRegion selectByCityName(String cityName, String provinceCode) {
		if (StringUtils.isBlank(cityName) || StringUtils.isBlank(provinceCode)) {
			return null;
		}

		if (isIgnoreBladeRegion(cityName)) {
			return null;
		}

		String key = "Region:selectByCityName:" + cityName + ":provinceCode:" + provinceCode;

		if (useLocalCache) {
			if (localVar.get() == null) {
				localVar.set(new HashMap<String, BladeRegion>());
			}
			BladeRegion bladeRegion = localVar.get().get(key);
			if (bladeRegion != null) {
				return bladeRegion;
			}
		}
		BladeRegion bladeRegion = null;
//		BladeRegion bladeRegion = redisCache.getCacheObject(key);
//		if (bladeRegion != null) {
//			return bladeRegion;
//		}

		BladeRegion qo = new BladeRegion();
		qo.setCityName(cityName);
		qo.setParentCode(provinceCode);
		List<BladeRegion> list = selectList(qo);
		if (list != null && !list.isEmpty()) {
			bladeRegion = list.get(0);
			if (bladeRegion != null) {
				if (useLocalCache) {
					localVar.get().put(key, bladeRegion);
				}
//				redisCache.setCacheObject(key, bladeRegion);
			}

		}else {
			logger.warn("没有查询到行政区划数据,key:" + key);
		}
		return bladeRegion;
	}

	@Override
	public BladeRegion selectByAreaName(String areaName, String cityCode) {
		if (StringUtils.isBlank(areaName) || StringUtils.isBlank(cityCode)) {
			return null;
		}

		if (isIgnoreBladeRegion(areaName)) {
			return null;
		}

		String key = "Region:selectByAreaName:" + areaName + ":cityCode:" + cityCode;
		if (useLocalCache) {
			if (localVar.get() == null) {
				localVar.set(new HashMap<String, BladeRegion>());
			}
			BladeRegion bladeRegion = localVar.get().get(key);
			if (bladeRegion != null) {
				return bladeRegion;
			}
		}
		BladeRegion bladeRegion = null;
//		BladeRegion bladeRegion = redisCache.getCacheObject(key);
//		if (bladeRegion != null) {
//			return bladeRegion;
//		}

		BladeRegion qo = new BladeRegion();
		qo.setName(areaName);
		qo.setParentCode(cityCode);
		List<BladeRegion> list = selectList(qo);
		if (list != null && !list.isEmpty()) {
			bladeRegion = list.get(0);
			if (bladeRegion != null) {
				if (useLocalCache) {
					localVar.get().put(key, bladeRegion);
				}
//				redisCache.setCacheObject(key, bladeRegion);
			}

		}else {
			logger.warn("没有查询到行政区划数据,key:" + key);
		}
		return bladeRegion;
	}

	@Override
	public List<BladeRegion> selectList(BladeRegion bladeRegion) {
		return bladeRegionMapper.selectList(bladeRegion);
	}

	public List<BladeRegion> selectAllAreaList() {
		return bladeRegionMapper.selectAllAreaList();
	}

	public List<BladeRegion> selectAllCityList() {
		return bladeRegionMapper.selectAllCityList();
	}

	public Map<String, BladeRegion> selectAll() {
		Map<String, BladeRegion> map = new HashMap<String, BladeRegion>();
		List<BladeRegion> list = bladeRegionMapper.selectAll();
		for (BladeRegion br : list) {
			map.put(br.getCode(), br);
		}
		return map;
	}

	private String getReginCodeKey(String code) {
		return "Region:selectBladeRegionByCode:" + code;
	}

	/**
	 * 查询行政区划列表
	 * 
	 * @param bladeRegion 行政区划
	 * @return 行政区划
	 */
	@Override
	public List<BladeRegion> selectBladeRegionList(BladeRegion bladeRegion) {
		return bladeRegionMapper.selectBladeRegionList(bladeRegion);
	}

	/**
	 * 新增行政区划
	 * 
	 * @param bladeRegion 行政区划
	 * @return 结果
	 */
	@Override
	public int insertBladeRegion(BladeRegion bladeRegion) {
		return bladeRegionMapper.insertBladeRegion(bladeRegion);
	}

	/**
	 * 修改行政区划
	 * 
	 * @param bladeRegion 行政区划
	 * @return 结果
	 */
	@Override
	public int updateBladeRegion(BladeRegion bladeRegion) {
		return bladeRegionMapper.updateBladeRegion(bladeRegion);
	}

	/**
	 * 批量删除行政区划
	 * 
	 * @param codes 需要删除的行政区划主键
	 * @return 结果
	 */
	@Override
	public int deleteBladeRegionByCodes(String[] codes) {
		return bladeRegionMapper.deleteBladeRegionByCodes(codes);
	}

	/**
	 * 删除行政区划信息
	 * 
	 * @param code 行政区划主键
	 * @return 结果
	 */
	@Override
	public int deleteBladeRegionByCode(String code) {
		return bladeRegionMapper.deleteBladeRegionByCode(code);
	}

	/**
	 * 批量---逻辑删除
	 *
	 * @param codes 需要删除的行政区划ID
	 * @return 结果
	 */
	@Override
	public int setDeleteByIds(String[] codes) {
		Long userId = SecurityUtils.getUserId();
		String userNickName = SecurityUtils.getUserNickName();
		return bladeRegionMapper.setDeleteByIds(codes, userId, userNickName);
	}

	/**
	 * 删除---逻辑删除
	 *
	 * @param code 行政区划ID
	 * @return 结果
	 */
	@Override
	public int setDeleteById(String code) {
		Long userId = SecurityUtils.getUserId();
		String userNickName = SecurityUtils.getUserNickName();
		return bladeRegionMapper.setDeleteById(code, userId, userNickName);
	}

}
