package cn.hmsoft.frame.util;

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

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.data.model.FrameRegionArea;
import cn.hmsoft.frame.data.model.FrameRegionCity;
import cn.hmsoft.frame.data.model.FrameRegionProvince;
import cn.hmsoft.frame.exception.BusinessException;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.jdbc.entity.QueryOrder;

/********************************
 * 行政区域辅助类
 * 
 * @author: YeFeng
 * @date: 2015-11-17 21:48:19
 * @version: 1.1.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 * @Description:
 */
public abstract class FrameZoneUtil {

	private static Map<String, FrameRegionProvince> provinceMap = null;
	private static Map<String, FrameRegionArea> areaMap = null;
	private static Map<String, FrameRegionCity> cityMap = null;

	private static Map<String, List<FrameRegionArea>> provinceAreaMap = null;
	private static Map<String, List<FrameRegionCity>> areaCityMap = null;

	private static List<FrameRegionProvince> provinceArray = null;
	private static List<FrameRegionArea> areaArray = null;
	private static List<FrameRegionCity> cityArray = null;

	private static void loadArea(boolean refresh) {
		if (provinceMap == null || refresh) {
			synchronized (FrameZoneUtil.class) {
				// 省市县数组
				provinceArray = SpringHelper.AppGobalDao.all(FrameRegionProvince.class, new QueryOrder("province_id"));
				areaArray = SpringHelper.AppGobalDao.all(FrameRegionArea.class, new QueryOrder("area_id"));
				cityArray = SpringHelper.AppGobalDao.all(FrameRegionCity.class, new QueryOrder("city_id"));

				provinceMap = new LinkedHashMap<String, FrameRegionProvince>();
				areaMap = new LinkedHashMap<String, FrameRegionArea>();
				cityMap = new LinkedHashMap<String, FrameRegionCity>();

				provinceAreaMap = new LinkedHashMap<String, List<FrameRegionArea>>();
				areaCityMap = new LinkedHashMap<String, List<FrameRegionCity>>();

				for (FrameRegionProvince p : provinceArray) {
					// p.setAreaArray(new ArrayList<FrameRegionArea>());
					provinceMap.put(p.getProvince_id(), p);
					provinceAreaMap.put(p.getProvince_id(), new ArrayList<FrameRegionArea>());
				}
				for (FrameRegionArea a : areaArray) {
					areaMap.put(a.getArea_id(), a);
					if (!provinceAreaMap.containsKey(a.getProvince_id()))
						continue;
					FrameRegionArea fa = new FrameRegionArea();
					fa.setArea_id(a.getArea_id());
					fa.setArea_name(a.getArea_name());
					fa.setProvince_id(a.getProvince_id());
					provinceAreaMap.get(a.getProvince_id()).add(fa);
					areaCityMap.put(a.getArea_id(), new ArrayList<FrameRegionCity>());
				}
				for (FrameRegionCity c : cityArray) {
					cityMap.put(c.getCity_id(), c);
					if (!areaCityMap.containsKey(c.getArea_id()))
						continue;
					FrameRegionCity fc = new FrameRegionCity();
					fc.setArea_id(c.getArea_id());
					fc.setCity_id(c.getCity_id());
					fc.setCity_name(c.getCity_name());
					fc.setProvince_id(c.getProvince_id());
					areaCityMap.get(c.getArea_id()).add(fc);

				}

			}
		}
	}

	public static Map<String, FrameRegionProvince> getProvinceMap(boolean refresh) {
		loadArea(refresh);
		return provinceMap;
	}

	public static List<FrameRegionProvince> getProvinceArray(boolean refresh) {
		loadArea(refresh);
		return provinceArray;
	}

	public static List<FrameRegionArea> getAreaArray(boolean refresh) {
		loadArea(refresh);
		return areaArray;
	}

	public static Map<String, FrameRegionCity> getCityMap(boolean refresh) {
		loadArea(refresh);
		return cityMap;
	}

	public static List<FrameRegionCity> getCityArray(boolean refresh) {
		loadArea(refresh);
		return cityArray;
	}

	public static List<FrameRegionArea> getProvinceArea(String province_id, boolean refresh) {
		loadArea(refresh);
		return provinceAreaMap.get(province_id);
	}

	public static List<FrameRegionCity> getAreaCity(String area_id, boolean refresh) {
		loadArea(refresh);
		return areaCityMap.get(area_id);
	}

	public static boolean checkProvice(String provinceId) {
		loadArea(false);
		if (StringHelper.isEmpty(provinceId))
			throw new BusinessException("提交的省份信息为空，请检查");
		if (provinceMap.containsKey(provinceId))
			return true;
		else
			throw new BusinessException("提交的省份信息不在允许的范围内，请检查");
	}

	public static boolean checkArea(String areaId) {
		loadArea(false);
		if (StringHelper.isEmpty(areaId))
			throw new BusinessException("提交的地区信息为空，请检查");
		if (areaMap.containsKey(areaId))
			return true;
		else
			throw new BusinessException("提交的地区信息不在允许的范围内，请检查");
	}

	public static boolean checkCity(String cityId) {
		loadArea(false);
		if (StringHelper.isEmpty(cityId))
			throw new BusinessException("提交的县市信息为空，请检查");
		if (cityMap.containsKey(cityId))
			return true;
		else
			throw new BusinessException("提交的县市信息不在允许的范围内，请检查");
	}

	public static boolean checkAreaInProvince(String provinceId, String areaId) {
		loadArea(false);
		checkProvice(provinceId);
		checkArea(areaId);
		for (FrameRegionArea area : provinceAreaMap.get(provinceId)) {
			if (area.getArea_id().equals(areaId))
				return true;
		}
		throw new BusinessException("提交的地区不是提交省份的下属区域，请检查");
	}

	public static boolean checkCityInArea(String areaId, String cityId) {
		loadArea(false);
		checkArea(areaId);
		checkCity(cityId);
		for (FrameRegionCity city : areaCityMap.get(areaId)) {
			if (city.getCity_id().equals(cityId))
				return true;
		}
		throw new BusinessException("提交的县市不是提交地区的下属区域，请检查");
	}

	public static boolean check(String provinceId, String areaId, String cityId) {
		checkAreaInProvince(provinceId, areaId);
		checkCityInArea(areaId, cityId);
		return true;
	}

	public static String getProvinceName(String provinceId) {
		loadArea(false);
		if (provinceMap.containsKey(provinceId))
			return provinceMap.get(provinceId).getProvince_name();
		return "";
	}

	public static String getAreaName(String areaId) {
		loadArea(false);
		if (areaMap.containsKey(areaId))
			return areaMap.get(areaId).getArea_name();
		return "";
	}

	public static String getCityName(String cityId) {
		loadArea(false);
		if (cityMap.containsKey(cityId))
			return cityMap.get(cityId).getCity_name();
		return "";
	}

}
