package com.sa.ibiz.demo.ibizutil.domain;

import com.sa.ibiz.demo.ibizutil.annotation.Dict;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.*;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import java.io.Serializable;
import java.lang.reflect.Field;
import com.sa.ibiz.demo.ibizutil.annotation.PreField;

public class EntityBase
{
	@TableField(exist = false)
	public Map<String,Object> extensions=new HashMap<String,Object>();
	@TableField(exist = false)
	private BeanMap map;

	public Object get(String field) {
		field=field.toLowerCase();
		if(CacheFieldMap.getFieldMap(this.getClass().getName()).containsKey(field))
			return getMap().get(field);
		else
			return this.extensions.get(field);
	}

	public void set(String field,Object value) {
		field=field.toLowerCase();
		if(CacheFieldMap.getFieldMap(this.getClass().getName()).containsKey(field))
			this.getMap().put(field,value);
		else
			this.extensions.put(field,value);
	}

	private BeanMap getMap()
	{
		if(map==null)
			map=BeanMap.create(this);
		return  map;
	}

	public Serializable getDefaultPrimaryKey() {
		return IdWorker.get32UUID();
	}

	public void FillDict() {
		List<Field> fields =  CacheFieldMap.getFields(this.getClass().getName());
		for(Field field:fields){
			Object value=this.get(field.getName());
			if(ObjectUtils.isEmpty(value))
				continue;
			Dict dict=field.getAnnotation(Dict.class);
			if(!ObjectUtils.isEmpty(dict)) {
				String dictName=dict.dictName();
				String textField=dict.textField();
				if(StringUtils.isEmpty(textField))
					textField=field.getName()+"_dicttext";
				this.extensions.put(textField,CodeListBase.getCodeListText(dictName,this.get(field.getName()).toString()));
			}
		}
	}

    /**
    * 获取预置属性字段结合
    * @return
    */
    public Map <Field,PreField> SearchPreField(){
    List<Field> fields =  CacheFieldMap.getFields(this.getClass().getName());
        Map <Field,PreField> preFieldMap =new HashMap<>();
        for(Field field:fields){
			PreField prefield=field.getAnnotation(PreField.class);
				if(!ObjectUtils.isEmpty(prefield)) {
					preFieldMap.put(field,prefield);
				}
        	}
        	return preFieldMap;
        }

	public static class CacheFieldMap {
		private static Hashtable<String, Hashtable<String,Field>> cacheMap = new Hashtable<>();
        public static Hashtable<String,Field> getFieldMap(String className) {
			if(className.indexOf("_$")>0)
				className=className.substring(0, className.lastIndexOf("_$"));
			Class clazz = null;
			try {
				clazz = Class.forName(className);
			}
			catch (Exception ex) {
				return new Hashtable<String,Field>();
			}
			if(cacheMap.containsKey(className))
				return cacheMap.get(className);
			synchronized (CacheFieldMap.class) {
				Hashtable<String,Field> result = cacheMap.get(className);
				if (result == null) {
					result=new Hashtable<String,Field>();
					Field[] fields=clazz.getDeclaredFields();
					for(Field field:fields){
						result.put(field.getName(),field);
					}
					cacheMap.put(className, result);
				}
				return result;
			}
		}
		private static List<Field> getFields(String className) {
			if(className.indexOf("_$")>0)
				className=className.substring(0, className.lastIndexOf("_$"));
			Hashtable<String,Field> fieldmap=cacheMap.get(className);
			Iterator it = fieldmap.keySet().iterator();
			List<Field> list=new ArrayList<Field>();
			while(it.hasNext()) {
				Object key = it.next();
				if(fieldmap.get(key.toString())!=null)
					list.add(fieldmap.get(key.toString()));
			}
			return list;
		}
	}
}
