/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.person.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;

import javax.validation.Valid;

import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.DictCodeConstant;
import org.springblade.community.entity.*;
import org.springblade.community.feign.*;
import org.springblade.community.vo.*;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.enterprise.vo.ChartDataVO;
import org.springblade.enterprise.vo.EnterpriseBizTypePieDataVO;
import org.springblade.estate.feign.IUserAccessPermissionsClient;
import org.springblade.person.dto.HouseUserDTO;
import org.springblade.person.entity.*;
import org.springblade.person.service.*;
import org.springblade.person.vo.HouseUserVO;
import org.springblade.person.wrapper.HouseUserWrapper;
import org.springblade.system.entity.DictBiz;
import org.springblade.system.expand.feign.IConfClient;
import org.springblade.system.feign.IDictBizClient;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;

import org.springblade.core.boot.ctrl.BladeController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 控制器
 *
 * @author BladeX
 * @since 2021-04-14
 */
@RestController
@AllArgsConstructor
@RequestMapping("/houseuser")
@Api(value = "", tags = "接口")
public class HouseUserController extends BladeController {

	private final HouseUserService houseUserService;
	private final IElderlyPeopleService elderlyPeopleService;
	private final IKeyPeopleService keyPeopleService;
	private final IDisablerService disablerService;
	private IAgencyClient agencyClient;
	private IResidentialClient residentialClient;
	private IBuildingClient buildingClient;
	private IRoomClient roomClient;
	private IUserService<HouseUser> userService;
	private final IDrugService drugService;
	private final IAdolescentService adolescentService;
	private IAidsService aidsService;
	private ICorrectionalStaffService correctionalStaffService;
	private IEstablishFilecardService establishFilecardService;
	private IFertileWomanService fertileWomanService;
	private IPrisonerService prisonerService;
	private IPsychiatricService psychiatricService;
	private IVeteransService veteransService;
	private IAllowancesPeopleService allowancesPeopleService;
	private final IConfClient confClient;
	private final IUserAccessPermissionsClient userAccessPermissionsClient;
	private final IDictBizClient dictBizClient;


	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入basicInfo")
	public R<HouseUserVO> detail(HouseUser houseUser) {
		HouseUser detail = houseUserService.getOne(Condition.getQueryWrapper(houseUser));
		return R.data(HouseUserWrapper.build().entityVO(detail));
	}

	/**
	 * 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入basicInfo")
	public R<IPage<HouseUserVO>> list(@RequestParam Map<String, Object> houseUser, Query query, BladeUser bladeUser) {
//		Integer auditStatus = null;
//		Long residentialId = null;
//		if(basicInfo.get("auditStatus") != null){
//			auditStatus = Integer.parseInt(String.valueOf(basicInfo.get("auditStatus")));
//			basicInfo.remove("auditStatus");
//		}
//		if(basicInfo.get("residentialId") != null){
//			residentialId = Long.parseLong(String.valueOf(basicInfo.get("residentialId")));
//			basicInfo.remove("residentialId");
//		}
//		LambdaQueryWrapper<HouseUser> wrapper = new QueryWrapperUtil<HouseUser>().getBasicQueryWrapperByMap(HouseUser::getOrgPosition, basicInfo, new HouseUser(), bladeUser, orgPositionClient);
		QueryWrapper<HouseUser> queryWrapper = Condition.getQueryWrapper(houseUser, HouseUser.class);
		queryWrapper.lambda().orderByDesc(HouseUser::getCreateTime);
		IPage<HouseUser> pages = houseUserService.page(Condition.getPage(query), queryWrapper);
		return R.data(HouseUserWrapper.build().pageVO(pages));
	}


	/**
	 * 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入basicInfo")
	public R<IPage<HouseUserVO>> page(HouseUserVO basicInfo, Query query) {
		IPage<HouseUserVO> pages = houseUserService.selectBasicInfoPage(Condition.getPage(query), basicInfo);
		return R.data(pages);
	}

	/**
	 * 新增
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入basicInfo")
	public R save(@Valid @RequestBody HouseUser houseUser) {
		Assert.hasText(houseUser.getIdCard(), "身份证号必传");
		Assert.notNull(houseUser.getRoomId(),"房间id不能为空");
		Assert.isTrue(!houseUserService.judgeHaveHouseUser(houseUser.getIdCard(),houseUser.getRoomId()),"同一个房间下不能存在相同身份住户");
		String faceUrl = houseUser.getFaceUrl();
		if (StrUtil.isNotBlank(faceUrl)) {
			houseUser.setFaceUrl(confClient.removePrefix(houseUser.getFaceUrl()));
		}
		houseUser.setAuditStatus(1);
		houseUser.setCreateType(1);
		boolean save = houseUserService.save(houseUser);
		if (save) {
			houseUserService.submitUserTags(houseUser);
		}
		return R.status(save);

	}

	/**
	 * 修改
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入basicInfo")
	public R update(@Valid @RequestBody HouseUser houseUser) {
		Assert.hasText(houseUser.getIdCard(), "身份证号必传");
		Assert.notNull(houseUser.getRoomId(),"房间id不能为空");
		HouseUser houseUser1 = houseUserService.getById(houseUser.getId());
		if (!StringUtil.isEmpty(houseUser1.getIdCard()) && !houseUser.getIdCard().equals(houseUser1.getIdCard())){
			Assert.isTrue(!houseUserService.judgeHaveHouseUser(houseUser.getIdCard(),houseUser.getRoomId()),"同一个房间下不能存在相同身份住户");
		}
		String faceUrl = houseUser.getFaceUrl();
		if (StrUtil.isNotBlank(faceUrl)) {
			houseUser.setFaceUrl(confClient.removePrefix(houseUser.getFaceUrl()));
		}
		boolean update = houseUserService.updateById(houseUser);
		if (update) {
			houseUserService.submitUserTags(houseUser);
		}
		return R.status(update);
	}


	/**
	 * 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入houseUser")
	public R submit(@Valid @RequestBody HouseUserDTO houseUserDTO) {
		Assert.hasText(houseUserDTO.getIdCard(), "身份证号必传");
		Assert.notNull(houseUserDTO.getRoomId(),"房间id不能为空");
		Assert.isTrue(!houseUserService.judgeHaveHouseUser(houseUserDTO.getIdCard(),houseUserDTO.getRoomId()),"同一个房间下不能存在相同身份住户");
		houseUserDTO.setCreateType(1);
		return houseUserService.submit(houseUserDTO);

	}

	/**
	 * 删除
	 */
	@PostMapping("/delFace")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R delFace(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<Long> idsList = Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
		;
		//批量关联删除
		List<HouseUser> houseUserList = null;
		if (idsList != null && idsList.size() > 0) {
			houseUserList = houseUserService.listByIds(idsList);
		}
		//下发删除人脸指令
		if (houseUserList != null && houseUserList.size() > 0) {
			return userService.pushDelFace(houseUserList, new HashMap<>());
		} else {
			return R.status(true);
		}
	}

	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {

		List<Long> idsList = Arrays.stream(ids.split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
		;
		//批量关联删除
		List<HouseUser> houseUserList = null;
		if (idsList != null && idsList.size() > 0) {
			houseUserList = houseUserService.listByIds(idsList);
		}
		for (Long id : idsList) {
			QueryWrapper queryWrapper = new QueryWrapper();
			queryWrapper.eq("parent_id", id);
			disablerService.getBaseMapper().delete(queryWrapper);
			keyPeopleService.getBaseMapper().delete(queryWrapper);
			elderlyPeopleService.getBaseMapper().delete(queryWrapper);
			adolescentService.getBaseMapper().delete(queryWrapper);
			aidsService.getBaseMapper().delete(queryWrapper);
			correctionalStaffService.getBaseMapper().delete(queryWrapper);
			disablerService.getBaseMapper().delete(queryWrapper);
			drugService.getBaseMapper().delete(queryWrapper);
			elderlyPeopleService.getBaseMapper().delete(queryWrapper);
			establishFilecardService.getBaseMapper().delete(queryWrapper);
			prisonerService.getBaseMapper().delete(queryWrapper);
			psychiatricService.getBaseMapper().delete(queryWrapper);
			veteransService.getBaseMapper().delete(queryWrapper);
		}
		boolean b = houseUserService.deleteLogic(Func.toLongList(ids));
		if (b) {
			//下发删除人脸指令
			if (houseUserList != null && houseUserList.size() > 0) {
				return userService.pushDelFace(houseUserList, new HashMap<>());
			} else {
				return R.status(true);
			}
		} else {
			return R.status(false);
		}
	}

	/**
	 * 入场记录初始化，关联新的小区和图片去除前缀
	 */
	@PostMapping("/initData")
	@ApiOperationSupport(order = 8)
	public R initData() {
		long beginTime = System.currentTimeMillis();
		List<HouseUser> houseUsers = this.houseUserService.getBaseMapper().selectList(new QueryWrapper<>(new HouseUser()));
		houseUsers.forEach(houseUser -> {
			if (houseUser.getResidentialId() != null) {
				Residential residential = residentialClient.getById(houseUser.getResidentialId());
				if (residential != null) {
					houseUser.setAgencyId(residential.getAgencyId());
					houseUser.setAgencyName(residential.getAgencyName());
				}
			}

			houseUserService.updateById(houseUser);

		});
		long endTime = System.currentTimeMillis();
		return R.data("耗时：" + (endTime - beginTime) / 1000 + "秒");
	}

	/**
	 * 【web端】一联通-人脸权限-常住人员下发列表
	 * 获取常住人员，下发列表
	 * type:0待下发,1已下发
	 */
	@GetMapping("/getHouseUserXFList")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "常住人员下发列表")
	public R getHouseUserXFList(Query query, @RequestParam Integer type) {
		List<Long> userIdList = userAccessPermissionsClient.getUserIdsByUserType(CommonConstant.UserFlag.HOUSE_USER_FLAG.getValue());
		LambdaQueryWrapper<HouseUser> queryWrapper = null;
		if (type.equals(0)) {
			//常住人员待下发列表
			queryWrapper = Condition.getQueryWrapper(new HouseUser()).lambda().eq(HouseUser::getAuditStatus, CommonConstant.UserAuditStatus.pass.getValue()).notIn(CollUtil.isNotEmpty(userIdList), HouseUser::getId, userIdList);
		} else if (type.equals(1)) {
			//常驻人员已下发列表
			queryWrapper = Condition.getQueryWrapper(new HouseUser()).lambda().eq(HouseUser::getAuditStatus, CommonConstant.UserAuditStatus.pass.getValue()).in(CollUtil.isNotEmpty(userIdList), HouseUser::getId, userIdList);
		}
		IPage<HouseUser> houseUserIPage = houseUserService.page(Condition.getPage(query), queryWrapper);
		return R.data(houseUserIPage);
	}


	/**
	 * 根据用户类型统计【web端智能运营中心】
	 */
	@GetMapping("/userType")
	@ApiOperationSupport(order = 1)
	public R bizType() {
		String OTHER_BIZ_TYPE = "其他";
		List<DictBiz> dictList = dictBizClient.getList(DictCodeConstant.HOUSEHOLD_TYPE).getData();
		Assert.isTrue(CollUtil.isNotEmpty(dictList), DictCodeConstant.DICT_LIST_IS_EMPTY);
		List<HouseUser> houseUsers = houseUserService.list(Condition.getQueryWrapper(new HouseUser()).lambda().select(HouseUser::getId, HouseUser::getType));
		List<String> legendData = new ArrayList<>();
		List<ChartDataVO> chartData = new ArrayList<>();
		if (CollUtil.isNotEmpty(houseUsers)) {
			long otherCount = houseUsers.stream().filter(item -> Objects.isNull(item.getType())).count();
			Map<Integer, List<HouseUser>> collect = houseUsers.stream().filter(item -> Objects.nonNull(item.getType())).collect(Collectors.groupingBy(HouseUser::getType));
			for (DictBiz dictBiz : dictList) {
				String dictValue = dictBiz.getDictValue();
				Integer dictKey = Convert.toInt(dictBiz.getDictKey());
				int count = 0;
				if (collect.get(dictKey) != null) {
					count = collect.get(dictKey).size();
				}
				legendData.add(dictValue);
				chartData.add(ChartDataVO.builder()
					.name(dictValue)
					.value(Convert.toLong(count))
					.build());
			}
			legendData.add(OTHER_BIZ_TYPE);
			chartData.add(ChartDataVO.builder()
				.name(OTHER_BIZ_TYPE)
				.value(Convert.toLong(otherCount))
				.build());
		}
		return R.data(EnterpriseBizTypePieDataVO.builder()
			.legendData(legendData)
			.data(chartData)
			.build());
	}

	/**
	 * 当日新增住户统计，默认是当天
	 */
	@GetMapping("/houseUserStat")
	@ApiOperationSupport(order = 13)
	@ApiOperation(value = "当日住户统计", notes = "传入guest")
	public R guestStat(@RequestParam(value = "beginDate", required = false) String beginDate, @RequestParam(value = "endDate", required = false) String endDate) {
		return R.data(this.houseUserService.houseUserStat(beginDate, endDate));
	}

}
