package com.yeejoin.amos.boot.biz.common.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.typroject.tyboot.core.foundation.enumeration.UserType;
import org.typroject.tyboot.core.restful.doc.TycloudOperation;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.dao.mapper.DataDictionaryMapper;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.Menu;
import com.yeejoin.amos.boot.biz.common.utils.MenuFrom;
import com.yeejoin.amos.boot.biz.common.utils.NameUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 数据字典
 *
 * @author tb
 * @date 2021-06-07
 */
@RestController
@Api(tags = "数据字典Api")
@RequestMapping(value = "/data-dictionary")
public class DataDictionaryController extends BaseController {

	@Autowired
	DataDictionaryServiceImpl iDataDictionaryService;
	@Autowired
	RedisUtils redisUtils;

	@Value("${redis.cache.failure.time}")
	private long time;

	@Autowired
	DataDictionaryMapper dataDictionaryMapper;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 新增数据字典
	 *
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "新增数据字典", notes = "新增数据字典")
	public boolean saveDataDictionary(HttpServletRequest request, @RequestBody DataDictionary dataDictionary) {
		return iDataDictionaryService.save(dataDictionary);
	}

	/**
	 * 根据id删除
	 *
	 * @param id
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
	@ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
	public boolean deleteById(HttpServletRequest request, @PathVariable Long id) {
		return iDataDictionaryService.removeById(id);
	}

	/**
	 * 修改数据字典
	 *
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/updateById", method = RequestMethod.PUT)
	@ApiOperation(httpMethod = "PUT", value = "修改数据字典", notes = "修改数据字典")
	public boolean updateByIdDataDictionary(HttpServletRequest request, @RequestBody DataDictionary dataDictionary) {
		return iDataDictionaryService.updateById(dataDictionary);
	}

	/**
	 * 根据id查询
	 *
	 * @param id
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
	public DataDictionary selectById(HttpServletRequest request, @PathVariable Long id) {
		return iDataDictionaryService.getById(id);
	}

	/**
	 * 根据id查询
	 *
	 * @param code
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/code", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据code查询", notes = "根据code查询")
	public DataDictionary selectByCode(HttpServletRequest request, @RequestParam("code") String code,
			@RequestParam("type") String type) {

		return iDataDictionaryService.getByCode(code, type);
	}

	/**
	 * 列表分页查询
	 *
	 * @return
	 */
	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
	public IPage<DataDictionary> listPage(String pageNum, String pageSize, DataDictionary dataDictionary) {

		Page<DataDictionary> pageBean;
		QueryWrapper<DataDictionary> dataDictionaryQueryWrapper = new QueryWrapper<>();
		Class<? extends DataDictionary> aClass = dataDictionary.getClass();
		Arrays.stream(aClass.getDeclaredFields()).forEach(field -> {
			try {
				field.setAccessible(true);
				Object o = field.get(dataDictionary);
				if (o != null) {
					Class<?> type = field.getType();
					String name = NameUtils.camel2Underline(field.getName());
					if (type.equals(Integer.class)) {
						Integer fileValue = (Integer) field.get(dataDictionary);
						dataDictionaryQueryWrapper.eq(name, fileValue);
					} else if (type.equals(Long.class)) {
						Long fileValue = (Long) field.get(dataDictionary);
						dataDictionaryQueryWrapper.eq(name, fileValue);
					} else if (type.equals(String.class)) {
						String fileValue = (String) field.get(dataDictionary);
						dataDictionaryQueryWrapper.eq(name, fileValue);
					} else {
						String fileValue = (String) field.get(dataDictionary);
						dataDictionaryQueryWrapper.eq(name, fileValue);
					}
				}
			} catch (Exception e) {
				throw new RuntimeException("系统异常");
			}
		});
		IPage<DataDictionary> page;
		if (StringUtils.isBlank(pageNum) || StringUtils.isBlank(pageSize)) {
			pageBean = new Page<>(0, Long.MAX_VALUE);
		} else {
			pageBean = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
		}
		page = iDataDictionaryService.page(pageBean, dataDictionaryQueryWrapper);
		return page;
	}

	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/gwmcDataDictionary/{type}", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据字典类型查询字典", notes = "根据字典类型查询字典")
	public ResponseModel<Object> gwmcDataDictionary(@PathVariable String type) throws Exception {
		// 数据字典生成树方法 原先通过getCode做主键 现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code by
		// kongfm 2021-09-08
		// 数据字典还原 by kongfm 2021-09-09
		QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("type", type);
		queryWrapper.orderByAsc("sort_num");

		if (redisUtils.hasKey(RedisKey.DATA_DICTIONARY_CODE + type)) {
			Object obj = redisUtils.get(RedisKey.DATA_DICTIONARY_CODE + type);
			return ResponseHelper.buildResponse(obj);
		} else {
			Collection<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
			List<Menu> menus = TreeParser.getTree(null, list, DataDictionary.class.getName(), "getCode", 0, "getName",
					"getParent", null);
			redisUtils.set(RedisKey.DATA_DICTIONARY_CODE + type, JSON.toJSON(menus), time);
			return ResponseHelper.buildResponse(menus);
		}
	}

	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/dataDictionary", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据字典类型查询字典2", notes = "根据字典类型查询字典2")
	public ResponseModel<Object> getDictionary(@RequestParam String type) throws Exception {
// 数据字典生成树方法 原先通过getCode做主键  现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code  by kongfm 2021-09-08
		// 数据字典还原 by kongfm 2021-09-09
		QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("type", type);
		queryWrapper.orderByAsc("sort_num");

		if (redisUtils.hasKey(RedisKey.DATA_DICTIONARY_CODE + type)) {
			Object obj = redisUtils.get(RedisKey.DATA_DICTIONARY_CODE + type);
			return ResponseHelper.buildResponse(obj);
		} else {
			Collection<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
			List<Menu> menus = TreeParser.getTree(null, list, DataDictionary.class.getName(), "getCode", 0, "getName",
					"getParent", null);
			redisUtils.set(RedisKey.DATA_DICTIONARY_CODE + type, JSON.toJSON(menus), time);
			return ResponseHelper.buildResponse(menus);
		}
	}

	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/gwmcDataDictionary/FireChemical/{type}", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据字典类型查询危险品字典", notes = "根据字典类型查询危险品字典")
	public ResponseModel<Object> gwmcDataDictionaryFireChemical(@PathVariable String type) throws Exception {
// 数据字典生成树方法 原先通过getCode做主键  现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code  by kongfm 2021-09-08
		// 数据字典还原 by kongfm 2021-09-09
		QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("type", type);
		queryWrapper.orderByAsc("sort_num");

		if (redisUtils.hasKey(RedisKey.DATA_DICTIONARY_CODE + type)) {
			Object obj = redisUtils.get(RedisKey.DATA_DICTIONARY_CODE + type);
			return ResponseHelper.buildResponse(obj);
		} else {
			Collection<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
			List<MenuFrom> menus = TreeParser.getTreexin(null, list, DataDictionary.class.getName(), "getCode", 0,
					"getName", "getParent", null);
			MenuFrom Me = new MenuFrom("-1", "-1", "-1", "危化品库", "危化品库", "危化品库", "-1", null);
			Me.setIsLeaf(false);
			Me.setChildren(menus);
			redisUtils.set(RedisKey.DATA_DICTIONARY_CODE + type, JSON.toJSON(Me), time);
			return ResponseHelper.buildResponse(Me);
		}
	}

	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/form/list", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据表态类型多个code查询表单数据项", notes = "根据表态类型多个code查询表单数据项")
	public ResponseModel<Object> selectFormdListItem(HttpServletRequest request, String types) {
		HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
		try {
			String[] typest = types.split(",");
			for (String type : typest) {
				QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("type", type);
				queryWrapper.orderByAsc("sort_num");
				if (redisUtils.hasKey(RedisKey.DATA_DICTIONARY_CODE_XIN + type)) {
					Object obj = redisUtils.get(RedisKey.DATA_DICTIONARY_CODE_XIN + type);
					objectObjectHashMap.put(type, obj);
				} else {
					Collection<DataDictionary> list = iDataDictionaryService.list(queryWrapper);
					List<MenuFrom> menus = null;
					// 数据字典生成树方法 原先通过getCode做主键 现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code by
					// kongfm 2021-09-08
					// 数据字典还原 by kongfm 2021-09-09
					menus = TreeParser.getTreexin(null, list, DataDictionary.class.getName(), "getCode", 0, "getName",
							"getParent", null);
					redisUtils.set(RedisKey.DATA_DICTIONARY_CODE_XIN + type, JSON.toJSON(menus), time);
					objectObjectHashMap.put(type, menus);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("系统异常！");
		}
		return ResponseHelper.buildResponse(objectObjectHashMap);
	}

	@TycloudOperation(needAuth = true, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/dataDictionaryTree", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据字典类型查询字典树", notes = "根据字典类型查询字典树")
	public ResponseModel<Object> getDictionaryTree(@RequestParam String type, @RequestParam String rootName)
			throws Exception {

		QueryWrapper<DataDictionary> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("type", type);
		queryWrapper.orderByAsc("sort_num");
		Collection<DataDictionary> list = null;
		List<Menu> menus = null;
		if ("YJLDDW".equals(type)) {
			list = dataDictionaryMapper.getNoInLinkUnit();
			// 数据字典生成树方法 原先通过getCode做主键 现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code by
			// kongfm 2021-09-08
			// 数据字典还原 by kongfm 2021-09-09
			menus = TreeParser.getTree(null, list, DataDictionary.class.getName(), "getCode", 0, "getName", "getParent",
					null);
		} else {
			list = iDataDictionaryService.list(queryWrapper);
			// 数据字典生成树方法 原先通过getCode做主键 现修改为 getSequenceNbr 后期数据字典parent字段保存id 而不要保存code by
			// kongfm 2021-09-08
			// 数据字典还原 by kongfm 2021-09-09
			menus = TreeParser.getTree(null, list, DataDictionary.class.getName(), "getCode", 0, "getName", "getParent",
					null);
		}
		// 创建根节点
		Menu menu = new Menu(-1L, rootName, -1L, menus, 0);
		List<Menu> menuList = new ArrayList<>();
		// 挂在主节点
		menuList.add(menu);
		return ResponseHelper.buildResponse(menuList);
	}

	@TycloudOperation(needAuth = false, ApiLevel = UserType.AGENCY)
	@RequestMapping(value = "/cleanRedis", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "清楚redis缓存", notes = "清楚redis缓存")
	public ResponseModel<Object> cleanRedis(@RequestParam String type) throws Exception {
		type = type.toLowerCase();
		if ("all".equals(type)) {
			RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
			redisConnection.flushAll();
			redisConnection.close();
		} else if (RedisKey.FORM_CODE.startsWith(type)) {
			redisUtils.del(RedisKey.FORM_CODE);
		} else if (RedisKey.DATA_DICTIONARY_CODE.startsWith(type)) {
			redisUtils.del(RedisKey.DATA_DICTIONARY_CODE);
		} else if (RedisKey.DATA_DICTIONARY_CODE_XIN.startsWith(type)) {
			redisUtils.del(RedisKey.DATA_DICTIONARY_CODE_XIN);
		} else if (RedisKey.FIREFIGHTERS_ID.startsWith(type)) {
			redisUtils.del(RedisKey.FIREFIGHTERS_ID);
		} else if (RedisKey.FIREFIGHTERS_LIST_ID.startsWith(type)) {
			redisUtils.del(RedisKey.FIREFIGHTERS_LIST_ID);
		} else if (RedisKey.EDUCATION_POST_EXPERIENCE_FIREFIGHTERS_ID.startsWith(type)) {
			redisUtils.del(RedisKey.EDUCATION_POST_EXPERIENCE_FIREFIGHTERS_ID);
		} else if (RedisKey.CONTRACT_ID.startsWith(type)) {
			redisUtils.del(RedisKey.CONTRACT_ID);
		} else if (RedisKey.THOUGHT_ID.startsWith(type)) {
			redisUtils.del(RedisKey.THOUGHT_ID);
		} else if (RedisKey.ALERTCALLED_ID.startsWith(type)) {
			redisUtils.del(RedisKey.ALERTCALLED_ID);
		} else if (RedisKey.TZS_ALERTCALLED_ID.startsWith(type)) {
			redisUtils.del(RedisKey.TZS_ALERTCALLED_ID);
		}
		return ResponseHelper.buildResponse(type);
	}

}
