package nc.vo.pmpub.accessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import nccloud.commons.collections.CollectionUtils;
import org.apache.commons.beanutils.BeanUtils;

import nc.bs.framework.common.NCLocator;
import nc.itf.bd.config.mode.IBDMode;
import nc.itf.org.IOrgConstBasic;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ColumnListProcessor;
import nc.pubitf.bd.accessor.IAccessorVisibleUtil;
import nc.vo.bd.accessor.IBDData;
import nc.vo.bd.accessor.OrgUtil;
import nc.vo.bd.config.BDModeSelectedVO;
import nc.vo.pub.BusinessRuntimeException;
import nc.vo.trade.voutils.IFilter;
import nc.vo.trade.voutils.VOUtil;
import nc.vo.util.BDModeManager;
import nccloud.commons.lang.StringUtils;

public class ProjectAccessorVisibleUtil implements IAccessorVisibleUtil {

	private static ProjectAccessorVisibleUtil instance = new ProjectAccessorVisibleUtil();

	public static ProjectAccessorVisibleUtil getInstance() {
		return instance;
	}

	/**
	 * 更新缓存，并返回当前缓存数据
	 * 
	 * @author guofya
	 * @date 2019-1-4
	 * @param
	 * @return
	 */
	@Override
	@SuppressWarnings({ "unchecked" })
	public List<IBDData> filterDataByVisibleScope(List<IBDData> datas, String pk_org, String beanid) {
//		BDModeSelectedVO mode = BDModeManager.getInstance().getBDModeSelectedVOByMDClassID(beanid);
		
		IFilter f = new VisibleScopeFilter(pk_org);
		return VOUtil.filter(datas, f);
//		return f==null?datas:VOUtil.filter(datas, f);

	}

	public static class VisibleScopeFilter implements IFilter{
//		Set<String> pk_orgs = new HashSet<String>();
		String pk_org;

		public VisibleScopeFilter(String pk_org) {
//			this.pk_orgs.add(pk_org);
			this.pk_org = pk_org;
		}
		
//		public VisibleScopeFilter(String... pk_org) {
//			this.pk_orgs.addAll(new ArrayList<>(Arrays.asList(pk_org)));
//		}

		@SuppressWarnings("unchecked")
		@Override
		public boolean accept(Object o) {
			try {
				String pk_org = null;
				String pk = null;
				String pk_group;
				if (o instanceof IBDData) {
					pk_org = ((IBDData) o).getPk_org();
					pk = ((IBDData) o).getPk();
					pk_group = ((IBDData) o).getPk_group();
				} else {
					pk_org = BeanUtils.getProperty(o, "pk_org");
					pk = BeanUtils.getProperty(o, "pk_project");
					pk_group = BeanUtils.getProperty(o, "pk_group");
				}

				// 1、如果是全局级数据，都能看见
				if (IOrgConstBasic.GLOBEORG.equals(this.pk_org)) {
					if (IOrgConstBasic.GLOBEORG.equals(pk_org)) {
						return true;
					} else {
						return false;
					}
				}

				IUAPQueryBS service = NCLocator.getInstance().lookup(IUAPQueryBS.class);
				ArrayList<String> data = (ArrayList<String>) service.executeQuery(
						"select pk_org from bd_project_b where pk_project = '" + pk + "' and pk_org<>'~' ",
						new ColumnListProcessor());

				//如果是集团级数据，没有分配，则所有组织都能看见
				if (StringUtils.equals(pk_org, pk_group)) {
					//集团能看集团级数据
					if (StringUtils.equals(this.pk_org, pk_group)) {
						return true;
					}
					if (CollectionUtils.isEmpty(data)) {
						return true;
					} else {
						return data.contains(this.pk_org);
					}
				}
				//如果是组织级数据，则所属组织和分配组织可以看见
				else {
					if (StringUtils.equals(this.pk_org, pk_group)) {
						return false;
					}
					if (CollectionUtils.isEmpty(data)) {
						return StringUtils.equals(this.pk_org, pk_org);
					} else {
						return StringUtils.equals(this.pk_org, pk_org) || data.contains(this.pk_org);
					}
				}


				/*if (!StringUtils.equals(pk_org, pk_group)) {
					data.add(pk_org);
				}
//				Set<String> orgs = new HashSet<String>();
				if (CollectionUtils.isNotEmpty(data)) {
//					for (String obj : data) {
//						orgs.add(obj);
//					}
//					orgs.addAll(data);
//					orgs.addAll(pk_orgs);
//					return orgs.contains(pk_org);
					return data.contains(pk_org);
				}
				return pk_orgs.contains(pk_org);*/
			} catch (Exception e) {
				throw new BusinessRuntimeException("",e);
			}
		}
		
	}

	
	/**
	 * 得到一个从可见性角度和pk_org等效的、高级别的组织PK.在没有更高级别等效组织的情况下返回pk_org自身。 举例来说：
	 * 当可见性是“集团”时，给定一个公司的PK,那么此方法返回的其等效组织为此公司对应的集团。
	 * 也就说，在这种管控模式下，集团下的所有公司的可见范围和集团是相同的。
	 * 
	 * @param pk_org
	 * @return
	 */
	@Override
	public String getEquivalentPkOrg(String beanID, String pk_org) {
		BDModeSelectedVO mode = BDModeManager.getInstance().getBDModeSelectedVOByMDClassID(beanID);
		if (mode == null) {
			return pk_org;
		}
		Integer scope = mode.getVisiblescope();
		String result = pk_org;
		String pk_group = OrgUtil.getGroup(pk_org);
		switch (scope.intValue()) {
		case IBDMode.SCOPE_GLOBE:
			result = IOrgConstBasic.GLOBEORG;
			break;
		case IBDMode.SCOPE_GLOBE_GROUP:
			if (IOrgConstBasic.GLOBEORG.equals(pk_org)) {
				result = IOrgConstBasic.GLOBEORG;
			} else {
				result = pk_group;
			}
			break;
		case IBDMode.SCOPE_GLOBE_ORG:
			if (IOrgConstBasic.GLOBEORG.equals(pk_org) || StringUtils.equals(pk_org, pk_group)) {
				result = IOrgConstBasic.GLOBEORG;
			} else {
				result = pk_org;
			}
			break;
		case IBDMode.SCOPE_GLOBE_GROUP_ORG:
			result = pk_org;
			break;
		case IBDMode.SCOPE_GROUP:
			result = pk_group;
			break;
		case IBDMode.SCOPE_GROUP_ORG:
			result = pk_org;
			break;
		case IBDMode.SCOPE_ORG:
			result = pk_org;
			break;
		default:
			break;
		}
		return result;
	}

}
