package cn.api;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.common.annotation.Log;
import cn.common.enums.BizOpType;
import cn.common.enums.ResultCode;
import cn.common.exception.BusinessException;
import cn.common.page.response.Result;
import cn.constant.CommonConst;
import cn.constant.SqlConst;
import cn.orm.sqltoy.model.Page;
import cn.service.util.UnifyFieldsUtil;
import cn.util.core.IsKit;
import cn.util.core.TypeKit;
import cn.util.string.NamingKit;
import cn.util.uuid.UUIDKit;
import cn.facade.abs.IService;

/**针对单个表通用请求处理*/
@RestController
@RequestMapping("/api")
public class CrudCtrl extends IService {
	/**
	 * 纯数字 25位
	 **/
	@GetMapping("/genUUID25_num")
	@Log(title = "通用方法-返回25位纯数UUID-genDigitUUID25", businessType = BizOpType.SELECT)
	public Result<?> genUUID25_num() {
		return Result.ok(UUIDKit.encodingUUID());
	}

	/**
	 * 依预先写好的SQL语句和删除条件paramMap进行删除。
	 * whereMap:{ id: ids.join(",")}(id值格式类似："1,2,3,4,5")
	 */
	@DeleteMapping("/delBySQL/{sqlId}")
	@Log(title = "库表操作-预写SQL语句删除-delBySQL", businessType = BizOpType.DELETE)
	public Result<?> delBySQL(@PathVariable String sqlId, @RequestBody Map<String, Object> whereMap) {
		return Result.ok(daoService.executeSql(sqlId, whereMap) > 0);
	}
	@PostMapping("/insertBySql/{sqlId}")
	@Log(title = "库表操作-新增记录-insertBySql", businessType = BizOpType.INSERT)
	public Result<?> insertBySql(@PathVariable String sqlId, @RequestBody Map<String, Object> paramMap) {
		return Result.ok(daoService.executeSql(sqlId, paramMap) > 0);
	}
	/**
	 * 单表: 插入一条记录
	 */
	@PostMapping("/insert/{tableName}")
	@Log(title = "库表操作-新增记录-insert", businessType = BizOpType.INSERT)
	public Result<?> insert(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		try {
			return Result.ok(daoService.insert(tableName, paramMap));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_INSERT.getMsg());
		}
	}
		/**
	 * 单表: 更新一条记录
	 */
	@PutMapping("/update/{tableName}")
	@Log(title = "库表操作-更新记录-update", businessType = BizOpType.UPDATE)
	public Result<?> update(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		try {
			return Result.ok(daoService.update(tableName, paramMap));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_UPDATE.getMsg());
		}
	}

	/**
	 * 单表: 更新某些字段setParam,功能能同updateBatch(单一主键)
	 * 更新条件：keyParam: *表示所有记录
	 */
	@PutMapping("/updateBatch_where/{tableName}/{keyParam}")
	@Log(title = "库表操作-批量更新字段-updateBatch_where", businessType = BizOpType.UPDATE)
	public Result<?> updateBatch_where(@PathVariable String tableName,//表名
									   @PathVariable String keyParam,//条件字段：主键|取值
									   @RequestBody Map<String, Object> setParam)//要更新的字段及对应值
	{
		try {
			return Result.ok(daoService.updateBatch_where(tableName, keyParam, setParam));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_UPDATE.getMsg());
		}
	}

	/**单表： 清空表中所有记录**/
	@DeleteMapping("/removeAll/{tableName}")
	@Log(title = "库表操作-清空所有记录-removeAll", businessType = BizOpType.CLEAN)
	public Result<?> removeAll(@PathVariable String tableName) {
		boolean result;
		try {
			result = daoService.removeAll(tableName);
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_CLEAR.getMsg());
		}
		return Result.ok(result);
	}



	/**
	 * 单表：默认主键
	 **/
	@DeleteMapping("/delBatch/{tableName}")
	@Log(title = "库表操作-批量删除记录-delBatch", businessType = BizOpType.DELETE)
	public Result<?> delBatch(@PathVariable String tableName, @RequestBody List<String> idList) {
		try {
			return Result.ok(daoService.delBatch(tableName, idList));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_DELETE.getMsg());
		}
	}

	/**删除页面所选定所有记录 单一主键(类型数字型)*/
	@DeleteMapping("/delBatch_num/{tableName}/{id}")
	@Log(title = "库表操作-删除所选记录-delBatch_num", businessType = BizOpType.DELETE)
	public Result<?> delBatch_num(@PathVariable String tableName, @PathVariable Object[] id) {
		return Result.ok(daoService.delByIds(tableName, CommonConst.DEFAULT_PRIMARY_KEY, id));
	}

	/**
	 * 单库：删除给定一条记录 自定义删除条件whereMap
	 */
	@DeleteMapping("/delById/{tableName}")
	@Log(title = "库表操作-删除给定一条记录-delById", businessType = BizOpType.DELETE)
	public Result<?> delById(@PathVariable String tableName, @RequestBody Map<String, Object> whereMap) {
		try {
			return Result.ok(daoService.delById(tableName, whereMap));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_DELETE.getMsg());
		}
	}

	/**
	 * 多表：删除给定记录 自定义删除条件whereMap，参数不含有：[]
	 */
	@DeleteMapping("/delBatch_where/{tableName}")
	@Log(title = "多表操作-删除给定记录-delBatch_where", businessType = BizOpType.DELETE)
	public Result<?> delBatch_where(@PathVariable String tableName, @RequestBody Map<String, Object> whereMap) {
		Boolean result;
		try {
			result = daoService.delBatch_where(tableName, whereMap);
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_RUN.getMsg());
		}
		return Result.ok(result);
	}

	/**
	 * 依据给定条件，先删除再插入多条记录
	 * jsonArray：data 插入数据；jsonArray：where删除条件
	 */
	@PostMapping("/delInsert/{tableName}")
	@Log(title = "库表操作-先删除再插入-delInsert", businessType = BizOpType.DELETEINSERT)
	public Result<?> delInsert(@PathVariable String tableName,
							   @RequestBody Map<String, Object> jsonArray) {
		try {
			return Result.ok(daoService.delInsert(tableName, jsonArray));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_RUN.getMsg());
		}
	}

	@GetMapping("/getMap/{tableName}")
	@Log(title = "库表操作-获取满足条件的一条记录-getMap", businessType = BizOpType.SELECT)
	public Result<?> getMap(@PathVariable String tableName, @RequestParam Map<String, Object> paramMap) {
		return Result.ok(daoService.getMap(tableName, paramMap));
	}

	/**
	 * 处理预先写好的SQL语句的Rest请求 依处理预先写好的SQL语句的Rest请求据查询条件paramMap进行查询,
	 * 最多有一条记录满足要求
	 */
	@GetMapping("/getMapBySql/{sqlId}")
	@Log(title = "预写SQL语句-查询-getMapBySql", businessType = BizOpType.SELECT)
	public Result<?> getMapBySQL(@PathVariable String sqlId, @RequestParam Map<String, Object> paramMap) {
		Map<String, Object> resultMap = daoService.getMapBySql(sqlId, paramMap);
		if (IsKit.isNullOrEmpty(resultMap)) {
			return Result.warnMsg(ResultCode.DATA_NOT_EXIST.getMsg());
		}
		return Result.ok(resultMap);
	}
	@GetMapping("/getListBySql_count/{sqlId}")
	@Log(title = "预写SQL语句-分页查询-getListBySql", businessType = BizOpType.SELECT)
	public Result<?> getListBySql_count(@PathVariable String sqlId, @RequestParam Map<String, Object> paramMap)
	{
		System.out.println("totalListtotalList:"+sqlId);
		Page<?> page = daoService.getPage(paramMap);
		Page<?> pageResult = daoService.findPageBySql(page, sqlId, paramMap, Map.class);
		if (IsKit.isNullOrEmpty(pageResult)) {
			return Result.warnMsg(ResultCode.DATA_NOEXIST.getMsg());
		}
		List<Map> totalList = daoService.findBySql(sqlId, paramMap, Map.class);
		List<Map<String, Object>> resultList = TypeKit.cast(pageResult.getRows());
		System.out.println("totalList:"+totalList);
		return Result.ok_ePlus(TypeKit.toLong(totalList),resultList);
	}
	/**
	 * 处理预先写好的SQL语句的Rest请求,分页返回
	 * 依据查询条件paramMap进行分页查询
	 */
	@GetMapping("/getListBySql/{sqlId}")
	@Log(title = "预写SQL语句-分页查询-getListBySql", businessType = BizOpType.SELECT)
	public Result<?> getListBySql(@PathVariable String sqlId, @RequestParam Map<String, Object> paramMap) {
		Page<?> page = daoService.getPage(paramMap);
		Page<?> pageResult = daoService.findPageBySql(page, sqlId, paramMap, Map.class);
		if (IsKit.isNullOrEmpty(pageResult)) {
			return Result.warnMsg(ResultCode.DATA_NOEXIST.getMsg());
		}
		List<Map<String, Object>> resultList = TypeKit.cast(pageResult.getRows());
		return Result.ok_ePlus(pageResult.getRecordCount(), resultList);
	}

	/**
	 * 单表: 获取满足条件的记录，分页返回
	 */
	@GetMapping("/getListByPage/{tableName}")
	@Log(title = "库表操作-分页获取记录-getListByPage", businessType = BizOpType.SELECT)
	public Result<?> getListByPage(@PathVariable String tableName, @RequestParam Map<String, Object> whereMap) {
		try {
			Page<?> pageResult = daoService.getPage(tableName, whereMap);
			if (IsKit.isNullOrEmpty(pageResult)) {
				return Result.warnMsg(ResultCode.SQL_RUN.getMsg());
			}
			List<Map<String, Object>> resultList = TypeKit.cast(pageResult.getRows());
			return Result.ok_ePlus(pageResult.getRecordCount(), resultList);
		} catch (Exception e) {
			return Result.warnMsg(ResultCode.SQL_RUN.getMsg());
		}
	}

	/**
	 * 不是为el-table准备数据
	 */
	@GetMapping("/getList/{tableName}")
	@Log(title = "库表操作-获取全部记录-getList", businessType = BizOpType.SELECT)
	public Result<?> getList(@PathVariable String tableName, @RequestParam Map<String, Object> paramMap) {
		return Result.ok(daoService.getList(tableName, paramMap));
	}

	/**
	 * 根据页面传来的数据库表和对应给定key字段进行查询
	 * （key是用逗号分割的多个字段）不排除重复字段
	 **/
	@GetMapping("/getKeySet/{tableName}/{KeySet}")
	@Log(title = "库表操作-获取某些字段-getKeySet", businessType = BizOpType.SELECT)
	public Result<?> getKeySet(@PathVariable String tableName, @PathVariable String KeySet) {
		return Result.ok(daoService.getList(tableName, KeySet));
	}


	/**
	 * 根据页面传来的数据库表和对应给定key字段进行查询
	 * （key是用逗号分割的多个字段）不排除重复字段
	 * 页面给出查询条件表达式where
	 **/
	@GetMapping("/getKeySet_where/{tableName}/{KeySet}/{where}")
	@Log(title = "库表操作-查询KV对-getKeySet_where", businessType = BizOpType.SELECT)
	public Result<?> getKeySet_where(@PathVariable String tableName,
									 @PathVariable String KeySet, @PathVariable String where) {
		List<Map<String, Object>> data = daoService.getList(tableName, KeySet, where);
		data = NamingKit.underlineToCaml(data);
		return Result.ok(data);
	}

	/**
	 * 根据页面传来的数据库表和对应给定key字段进行查询
	 * （key是用逗号分割的多个字段）排除重复字段rfield
	 **/
	@GetMapping("/getKeySet_unique/{tableName}/{KeySet}/{rField}")
	@Log(title = "系统管理-角色管理-新增角色", businessType = BizOpType.INSERT)
	public Result<?> queryKeyPair_u(@PathVariable String tableName,
									@PathVariable String KeySet, @PathVariable String rField) {
		List<Map<String, Object>> data = daoService.getList(tableName, KeySet, rField, "");
		data = NamingKit.underlineToCaml(data);
		return Result.ok(data);
	}

	/**
	 * 根据页面传来的数据库表和对应给定key字段进行查询
	 * （key是用逗号分割的多个字段）排除重复字段rfield；页面给出查询条件表达式where
	 * where=*全检；否则由页面给出查询条件。
	 **/
	@GetMapping("/getKeySet_uw/{tableName}/{KeySet}/{rField}/{where}")
	@Log(title = "库表操作-查询KV对-queryKeyPair_uw", businessType = BizOpType.SELECT)
	public Result<?> queryKeyPair_uw(@PathVariable String tableName,
									 @PathVariable String KeySet, @PathVariable String rField,
									 @PathVariable String where) {
		List<Map<String, Object>> data;
		if (SqlConst.STAR.equals(where)) {//全部检索
			data = daoService.getList(tableName, KeySet, rField, "");
		} else {
			data = daoService.getList(tableName, KeySet, rField, where);
		}
		data = NamingKit.underlineToCaml(data);
		return Result.ok(data);
	}

	/**
	 * 单库：检查是否存在同样的记录
	 */
	@PostMapping("/common/dupCheck/{tableName}")
	@Log(title = "通用方法-检查是否存在同样的记录-dupCheck", businessType = BizOpType.SELECT)
	public Result<?> dupCheck(@PathVariable String tableName, @RequestBody Map<String, Object> whereMap) {
		Boolean result = daoService.ifExistRecord(tableName, whereMap);
		//存在记录
		if (result) {
			return Result.warnMsg(ResultCode.DATA_EXIST.getMsg());
		}
		return Result.ok(false);
	}

	/**
	 * 产生验证码
	 */
	@GetMapping("/common/genVerifyCode/{pageNum}")
	@Log(title = "通用方法-生成验证码-genVerifyCode", businessType = BizOpType.SELECT)
	public Result<?> genVerifyCode(@PathVariable String pageNum) {
		int digitNum = 4;
		if (!"null".equals(pageNum)) {
			digitNum = TypeKit.objToInt(pageNum);
		}
		return Result.ok(UUIDKit.genCharNum(digitNum));
	}

	/**
	 * 更新某些字段paramMap: 单一默认主键
	 */
	@PutMapping("/updateBatch/{tableName}/{id}")
	@Log(title = "库表操作-批量更新字段-updateBatch", businessType = BizOpType.UPDATE)
	public Result<?> updateBatch(@PathVariable String tableName,
								 @PathVariable String[] id,//默认主键uuid
								 //要更新的字段及对应值
								 @RequestBody Map<String, Object> paramMap) {
		Boolean result;
		try {
			result = daoService.updateBatch(tableName, Arrays.asList(id), paramMap);
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_UPDATE.getMsg());
		}
		return Result.ok(result);
	}

	/**
	 * paramMap要更新的字段及对应.单一默认主键
	 * 需要吗？能否用updateBatch替换待验证？
	 */
	@PutMapping("/updateBatchById/{tableName}/{id}")
	@Log(title = "库表操作-更新同表的若干字段-updateBatchById", businessType = BizOpType.SELECT)
	public Result<?> updateBatchById(@PathVariable String tableName,//表名
									 @PathVariable String[] id,//默认主键Long[] id
									 @RequestBody Map<String, Object> paramMap) {
		//String uuidStr = TypeUtil.numArrayToStr(id);
		Boolean result;
		try {
			result = daoService.updateBatch(tableName, Arrays.asList(id), paramMap);//uuidStr
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_UPDATE.getMsg());
		}
		return Result.ok(result);
	}


	/**
	 * 自动产生主键值
	 */
	@PostMapping("/insertAndGenIndex/{tableName}")
	@Log(title = "库表操作-新增记录-insertAndGenIndex", businessType = BizOpType.INSERT)
	public Result<?> insertAndGenIndex(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		//可以依据规则产生UUID
		paramMap.put(CommonConst.DEFAULT_PRIMARY_KEY, UUIDKit.encodingUUID());
		Boolean result;
		try {
			result = daoService.insert(tableName, paramMap);
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_INSERT.getMsg());
		}
		return Result.ok(result);
	}

	/**
	 * 自动对所有默认项赋值
	 */
	@PostMapping("/insert_E/{tableName}")
	@Log(title = "库表操作-新增记录-insert_E", businessType = BizOpType.INSERT)
	public Result<?> insert_E(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		//可以依据规则产生UUID
		paramMap.put(CommonConst.DEFAULT_PRIMARY_KEY, UUIDKit.encodingUUID());
		paramMap.putAll(new UnifyFieldsUtil().createUnifyFields());
		Boolean result;
		try {
			result = daoService.insert(tableName, paramMap);
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_INSERT.getMsg());
		}
		return Result.ok(result);
	}



	/**
	 * 修改保存一条记录
	 */
	@PutMapping("/updateSam/{tableName}")
	@Log(title = "库表操作-更新一条记录-updateSam", businessType = BizOpType.SELECT)
	public Result<?> updateSam(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		paramMap = NamingKit.camelToUnderline(paramMap);
		try {
			return Result.ok(daoService.update(tableName, paramMap));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_UPDATE.getMsg());
		}
		//return Result.ok(samDao.update(tableName,paramMap));
	}

	/**
	 * 新增角色
	 */
	@PostMapping("/insertSam/{tableName}")
	@Log(title = "库表操作-新增一条记录-insertSam", businessType = BizOpType.SELECT)
	public Result<?> insertSam(@PathVariable String tableName, @RequestBody Map<String, Object> paramMap) {
		paramMap = NamingKit.camelToUnderline(paramMap);
		//return Result.ok(samDao.insert(tableName,paramMap));
		try {
			return Result.ok(daoService.insert(tableName, paramMap));
		} catch (BusinessException e) {
			return Result.warnMsg(ResultCode.SQL_INSERT.getMsg());
		}
	}
}