package com.hotent.uc.controller.openController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.hotent.base.annotation.ApiGroup;
import com.hotent.base.annotation.OpenApi;
import com.hotent.base.constants.ApiGroupConsts;
import com.hotent.base.exception.BaseException;
import com.hotent.base.feign.PortalFeignService;
import com.hotent.base.jwt.JwtTokenHandler;
import com.hotent.base.model.CommonResult;
import com.hotent.base.query.*;
import com.hotent.base.util.JwtUtil;
import com.hotent.base.util.StringUtil;
import com.hotent.uc.manager.DemensionManager;
import com.hotent.uc.manager.OrgUserManager;
import com.hotent.uc.manager.UserManager;
import com.hotent.uc.model.Demension;
import com.hotent.uc.model.User;
import com.hotent.uc.params.org.OrgVo;
import com.hotent.uc.params.user.UserVo;
import com.hotent.vo.OrgShortVo;
import com.hotent.vo.OrgUserVo;
import com.hotent.vo.UserFullVo;
import com.hotent.vo.UserShortVo;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Api(tags = "三方厂家Api用户接口")
@RequestMapping("/${openApi.prefix}/server/user/")
@ApiGroup(group= {ApiGroupConsts.GROUP_UC})
@OpenApi(moduleName = "user用户模块",function = "开放接口")
public class UserApiController {
    @Autowired
    UserManager userService;
    @Autowired
    OrgUserManager orgUserService;
    @Resource
    JwtTokenHandler jwtTokenHandler;
    @Autowired
    private DemensionManager demensionManager;
    @Autowired
    private PortalFeignService portalFeignService;
    /**
     * 获取组织下的用户列表
     * @param orgId
     */
    @RequestMapping(value="getUserListByOrgId",method= RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "获取组织下的用户列表", httpMethod = "GET", notes = "获取组织下的用户列表，参数{\"orgId\":\"1\"}")
    @OpenApi(description = "获取组织下的用户列表")
    public CommonResult<?> getUserListByOrgId(
            HttpServletRequest request,
            @ApiParam(name="orgId",value="组织id") @RequestParam(required=false) String orgId,
            @ApiParam(name="pageNum",value="页号") @RequestParam(required=false) Integer pageNum,
            @ApiParam(name="pageSize",value="加载数据数") @RequestParam(required=false) Integer pageSize) throws Exception {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String sysCode= (String) claims.get("sysCode");

        if (StringUtil.isEmpty(orgId)) {
            throw new BaseException("组织Id【orgId】不能为空！");
        }
        if(pageNum==null) {
            pageNum = 1;
        }
        if(pageSize==null) {
            pageSize = 20;
        }

        QueryFilter<User> filter = QueryFilter.build();
        filter.withPage(new PageBean(pageNum, pageSize));
        filter.withQuery(new QueryField("ORG_ID_",orgId, QueryOP.EQUAL));
        filter.withSorter(new FieldSort("update_time_", Direction.DESC));
        IPage<User> page = userService.getOrgUserQuery(filter);

        List<String> userIdList = page.getRecords().stream()
                .map(User::getId)
                .collect(Collectors.toList());
        Map<String, List<OrgUserVo>> orgMap = this.queryOrgUserByUserId(userIdList);

        List<UserShortVo> userList = page.getRecords().stream()
                .map(item -> {
                    UserShortVo vo = new UserShortVo();
                    BeanUtils.copyProperties(item, vo);
                    vo.setOrgUserList(orgMap.get(vo.getId()));
                    return vo;
                })
                .collect(Collectors.toList());



        List<String> orgIdList=getPermissionList(sysCode);
        List<UserShortVo> filteredList = userList.stream()
                .filter(entity -> orgIdList.contains(entity.getId()))
                .collect(Collectors.toList());


        PageList<UserShortVo> pageList = new PageList();
        pageList.setPage(page.getCurrent());
        pageList.setPageSize(page.getSize());
        pageList.setTotal(filteredList.size());
        pageList.setRows(filteredList);
        return new CommonResult(true, "获取组织下的用户列表成功", pageList);
    }

    /**
     * 根据用户id 获取用户和组织关系
     * @param userIds
     */
    private Map<String, List<OrgUserVo>> queryOrgUserByUserId(List<String> userIds) {

        QueryFilter<User> relFilter = QueryFilter.build();
        relFilter.withPage(new PageBean(1, PageBean.WITHOUT_PAGE));
        relFilter.withQuery(new QueryField("relTable.userId", userIds, QueryOP.IN));
        IPage<HashMap<String,Object>> orgPage = orgUserService.getUserOrgPage(relFilter);

        Map<String, List<OrgUserVo>> orgMap = new HashedMap();
        for (int i = 0; i < orgPage.getRecords().size(); i++) {
            HashMap<String,Object> map = orgPage.getRecords().get(i);
            OrgUserVo vo = new OrgUserVo();
            vo.setId((String)map.get("orgUserId"));
            vo.setOrgId((String)map.get("orgId"));
            vo.setOrgName((String)map.get("orgName"));
            vo.setUserId((String)map.get("userId"));
            vo.setPosId((String)map.get("posId"));
            vo.setPostName((String)map.get("posName"));
            vo.setIsMaster((Integer)map.get("isMaster"));
            vo.setIsCharge((Integer)map.get("isCharge"));
            vo.setStatus((Integer)map.get("status"));
            vo.setStartDate(this.toLocalDateTime((Timestamp)map.get("startDate")));
            vo.setEndDate(this.toLocalDateTime((Timestamp)map.get("endDate")));
            vo.setCreateTime(this.toLocalDateTime((Timestamp)map.get("createTime")));
            vo.setUpdateTime(this.toLocalDateTime((Timestamp)map.get("updateTime")));
            List<OrgUserVo> ou = orgMap.get(vo.getUserId());
            if(ou==null) {
                ou = new ArrayList();
            }
            ou.add(vo);
            orgMap.put(vo.getUserId(), ou);
        }
        return orgMap;
    }

    private LocalDateTime toLocalDateTime(Timestamp time) {
        if(time==null) return null;
        return time.toLocalDateTime();
    }

    /**
     * 获取全部用户列表
     * @param pageNum
     * @param pageSize
     */
    @RequestMapping(value="getUsersAll",method= RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "获取全部用户列表", httpMethod = "GET", notes = "获取全部用户列表，参数{\"pageNum\":\"1\",\"pageSize\":\"20\"}")
    @OpenApi(description = "获取全部用户列表")
    public CommonResult<?> getUsersAll(
            HttpServletRequest request,
            @ApiParam(name="pageNum",value="页号") @RequestParam(required=false) Integer pageNum,
            @ApiParam(name="pageSize",value="加载数据数") @RequestParam(required=false) Integer pageSize) throws Exception {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String sysCode= (String) claims.get("sysCode");

        if(pageNum==null) {
            pageNum = 1;
        }
        if(pageSize==null) {
            pageSize = 20;
        }
        QueryFilter<User> filter = QueryFilter.build();
        filter.withPage(new PageBean(pageNum, pageSize));
        filter.withSorter(new FieldSort("update_time_", Direction.DESC));
        IPage<User> page = userService.getOrgUserQuery(filter);

        List<String> userIdList = page.getRecords().stream()
                .map(User::getId)
                .collect(Collectors.toList());
        Map<String, List<OrgUserVo>> orgMap = this.queryOrgUserByUserId(userIdList);

        List<UserShortVo> userList = page.getRecords().stream()
                .map(item -> {
                    UserShortVo vo = new UserShortVo();
                    BeanUtils.copyProperties(item, vo);
                    vo.setOrgUserList(orgMap.get(vo.getId()));
                    return vo;
                })
                .collect(Collectors.toList());

        List<String> orgIdList=getPermissionList(sysCode);
        List<UserShortVo> filteredList = userList.stream()
                .filter(entity -> orgIdList.contains(entity.getId()))
                .collect(Collectors.toList());


        PageList<UserShortVo> pageList = new PageList();
        pageList.setPage(page.getCurrent());
        pageList.setPageSize(page.getSize());
        pageList.setTotal(filteredList.size());
        pageList.setRows(filteredList);
        return new CommonResult(true, "获取用户列表成功", pageList);
    }

    /**
     * 根据更新时间获取 用户数据列表
     * @param updateTime yyyy-MM-dd
     * @param pageSize
     * @param pageNum
     * @return
     */
    @RequestMapping(value="getUserListByUpdateTime",method= RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "根据更新时间获取 用户数据列表", httpMethod = "GET", notes = "根据更新时间获取 用户数据列表，参数{\"updateTime\":\"2024-02-29\",\"pageNum\":\"1\",\"pageSize\":\"20\"}")
    @OpenApi(description = "根据更新时间获取 用户数据列表")
    public CommonResult<?> getUserListByUpdateTime(
            HttpServletRequest request,
            @ApiParam(name="updateTime",value="更新时间") @RequestParam(required=false) String updateTime,
            @ApiParam(name="pageNum",value="页号") @RequestParam(required=false) Integer pageNum,
            @ApiParam(name="pageSize",value="加载数据数") @RequestParam(required=false) Integer pageSize) throws Exception {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String sysCode= (String) claims.get("sysCode");
        if (StringUtil.isEmpty(updateTime)) {
            throw new BaseException("更新时间【updateTime】不能为空！");
        }
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Date minDate;
        try {
            Date date = fmt.parse(updateTime);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            minDate = calendar.getTime();
        } catch (Exception e) {
            throw new BaseException("更新时间格式错误【updateTime】不能为空！");
        }

        if(pageNum==null) {
            pageNum = 1;
        }
        if(pageSize==null) {
            pageSize = 20;
        }
        QueryFilter<User> filter = QueryFilter.build();
        filter.withPage(new PageBean(pageNum, pageSize));
        filter.withQuery(new QueryField("OU_CREATE_TIME_", minDate, QueryOP.GREAT_EQUAL, FieldRelation.OR));
        filter.withQuery(new QueryField("OU_UPDATE_TIME_", minDate, QueryOP.GREAT_EQUAL, FieldRelation.OR));
        filter.withSorter(new FieldSort("update_time_", Direction.DESC));
        IPage<HashMap<String,Object>> page = userService.getUserListMapByOrgQuery(filter);

        List<UserShortVo> userList = page.getRecords().stream()
                .map(item -> {
                    UserShortVo vo = new UserShortVo();
                    vo.setId((String)item.get("ID_"));
                    vo.setFullname((String)item.get("FULLNAME_"));
                    vo.setAccount((String)item.get("ACCOUNT_"));
                    vo.setMobile((String)item.get("MOBILE_"));
                    vo.setStatus((Integer)item.get("STATUS_"));
                    vo.setSex((String)item.get("SEX_"));
                    vo.setAddress((String)item.get("ADDRESS_"));
                    return vo;
                })
                .collect(Collectors.toList());

        List<String> userIdList = userList.stream()
                .map(UserShortVo::getId)
                .collect(Collectors.toList());
        Map<String, List<OrgUserVo>> orgMap = this.queryOrgUserByUserId(userIdList);

        userList.stream()
            .map(item -> {
                item.setOrgUserList(orgMap.get(item.getId()));
                return item;
            })
            .collect(Collectors.toList());
//        List<UserShortVo> userListTemp=userList.stream().distinct().collect(Collectors.toList());
        userList = userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new  TreeSet<>(Comparator.comparing(UserShortVo :: getId))), ArrayList::new));
        List<String> orgIdList=getPermissionList(sysCode);
        List<UserShortVo> filteredList = userList.stream()
                .filter(entity -> orgIdList.contains(entity.getId()))
                .collect(Collectors.toList());

        PageList<UserShortVo> pageList = new PageList();
        pageList.setPage(page.getCurrent());
        pageList.setPageSize(page.getSize());
        pageList.setTotal(filteredList.size());
        pageList.setRows(filteredList);
        return new CommonResult(true, "获取用户列表成功", pageList);
    }

    /**
     * 获取用户详情
     * @param userId
     */
    @RequestMapping(value="getUserDetail",method= RequestMethod.GET, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "根据用户id，获取用户详情", httpMethod = "GET", notes = "获取用户详情，参数{\"userId\":\"1\"}")
    @OpenApi(description = "根据用户id，获取用户详情")
    public CommonResult<?> getUserDetail(
            HttpServletRequest request,
            @ApiParam(name="userId",value="用户id") @RequestParam(required=false) String userId) {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String sysCode= (String) claims.get("sysCode");
        if (StringUtil.isEmpty(userId)) {
            throw new BaseException("用户id【userId】不能为空！");
        }
        boolean flag= getPermissionList(sysCode).stream().anyMatch(e->e.equals(userId));
        if(flag){
            User user = userService.get(userId);
            if(user==null){
                return new CommonResult(false, "未查询到用户信息");
            }

            List<String> userIdList = new ArrayList<>();
            userIdList.add(user.getId());
            Map<String, List<OrgUserVo>> orgMap = this.queryOrgUserByUserId(userIdList);

            UserFullVo vo = new UserFullVo();
            BeanUtils.copyProperties(user, vo);
            vo.setOrgUserList(orgMap.get(vo.getId()));
            return new CommonResult(true, "获取用户信息成功", vo);
        }else{
            User user = userService.get(userId);
            if(user==null){
                return new CommonResult(false, "未查询到用户信息");
            }
            return new CommonResult(false, "获取用户信息失败，权限不足", null);
        }

    }

    @RequestMapping(value = "addOrEditUser", method = RequestMethod.POST, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "新增、编辑用户", httpMethod = "POST", notes = "新增、编辑用户")
    @OpenApi(description = "新增、编辑用户")
    public CommonResult<?> addOrEditUser(HttpServletRequest request,@ApiParam(name="orgValue",value="编辑用户",required=true) @RequestBody UserVo userVo)
            throws Exception {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String orgName= userVo.getFullname();
        if(StringUtil.isEmpty(orgName)){
            return new CommonResult(false, "姓名不能为空");
        }
        String account= userVo.getAccount();
        if(StringUtil.isEmpty(account)){
            return new CommonResult(false, "账号不能为空");
        }
        String password= userVo.getPassword();
        if(StringUtil.isEmpty(password)){
            return new CommonResult(false, "登录密码不能为空");
        }
        String mobile= userVo.getMobile();
        if(StringUtil.isEmpty(mobile)){
            return new CommonResult(false, "手机号不能为空");
        }
        String orgId= userVo.getOrgId();
        if(StringUtil.isEmpty(orgId)){
            return new CommonResult(false, "所属组织id不能为空");
        }
        return userService.addOrEditUser(userVo,demId);
    }
    @RequestMapping(value = "deleteUser", method = RequestMethod.DELETE, produces = { "application/json; charset=utf-8" })
    @ApiOperation(value = "删除用户", httpMethod = "DELETE", notes = "删除用户")
    @OpenApi(description = "删除用户")
    public CommonResult<?> deleteUser(HttpServletRequest request,@ApiParam(name="orgValue",value="删除用户",required=true) @RequestBody UserVo userVo)
            throws Exception {
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String demId=getDemId(request);
        String id= userVo.getId();
        if(StringUtil.isEmpty(id)){
            return new CommonResult(false, "id不能为空");
        }
        return userService.deleteUser(userVo,demId);
    }
    /**
     * @description 获取用户token中的单位默认维度id
     * @author  yangzibin
     * @date    2024/7/13 14:03
     * @param	request
     * @return  String
     */
    private String getDemId(HttpServletRequest request){
        String token = JwtUtil.getToken(request);
        Claims claims = jwtTokenHandler.parseToken(token);
        String tenantId = (String) claims.get("tenantId"); //获取维度
        String demId="";
        QueryWrapper<Demension> lambdaQueryWrapper=new QueryWrapper<>();
        lambdaQueryWrapper.eq("TENANT_ID_",tenantId);
        lambdaQueryWrapper.eq("IS_DEFAULT_","1");
        Demension demension=demensionManager.getBaseMapper().selectOne(lambdaQueryWrapper);
        if(demension!=null){
            demId=demension.getId();
        }
        return demId;
    }
    /**
     * @description
     * @author  yangzibin
     * @date    2024/7/13 15:25
     * @param	sysCode
     * @return  java.util.List<java.lang.String>
     */
    private List<String> getPermissionList(String sysCode){
        ArrayNode arrayNode=portalFeignService.getOrgIdList(sysCode,"1","","");
        List<String> idsList=new ArrayList<>();
        for (JsonNode str : arrayNode) {
            idsList.add(str.asText());
        }
        return idsList;
    }
}
