package jnpf.attendance.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jnpf.attendance.AttendanceGroupApi;
import jnpf.attendance.dto.AttendanceUserGroupVo;
import jnpf.attendance.dto.AttendanceUserListGroupVO;
import jnpf.attendance.service.AttendanceGroupService;
import jnpf.attendance.service.AttendanceUserService;
import jnpf.base.ActionResult;
import jnpf.entity.AttendanceGroup;
import jnpf.entity.AttendanceGroupUser;
import jnpf.entity.attendance.AppointPermission;
import jnpf.enums.attendance.GroupUserTypeEnum;
import jnpf.exception.HandleException;
import jnpf.model.attendance.dto.*;
import jnpf.model.attendance.vo.*;
import jnpf.model.attendance.vo.attendance.GroupLockVo;
import jnpf.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考勤组控制器
 *
 * @author yier
 * @create 2023-11-21
 */
@RestController
@RequestMapping(value = "/group")
public class AttendanceGroupController implements AttendanceGroupApi {
    @Resource
    private AttendanceUserService attendanceUserService;
    @Resource
    private AttendanceGroupService attendanceGroupService;

    /**
     * 查询考勤组管理列表
     *
     * @param groupQueryDto 考勤组名称查询实体
     * @return List<AttendanceGroupVo>
     */
    @GetMapping
    public ActionResult<List<AttendanceGroupVo>> list(GroupQueryDto groupQueryDto) {
        return ActionResult.success(attendanceGroupService.groupManagerList(groupQueryDto));
    }

    /**
     * 新增考勤组
     *
     * @param saveAttendanceGroupDto 考勤组保存实体
     * @return ActionResult<Void>
     */
    @PostMapping
    public ActionResult<Void> add(@RequestBody SaveAttendanceGroupDto saveAttendanceGroupDto) throws Exception {
        ParamUtil.checkParam(saveAttendanceGroupDto);
        int num = attendanceGroupService.save(saveAttendanceGroupDto);
        if (num < 0) {
            return ActionResult.fail("考勤组名称重复，请换一个名称!");
        }
        return ActionResult.success();
    }

    /**
     * 修改考勤组信息
     *
     * @param saveAttendanceGroupDto 考勤组保存实体
     * @return Void
     */
    @PutMapping
    public ActionResult<Void> update(@RequestBody SaveAttendanceGroupDto saveAttendanceGroupDto) throws Exception {
        ParamUtil.checkParam(saveAttendanceGroupDto);
        int num = attendanceGroupService.save(saveAttendanceGroupDto);
        if (num < 0) {
            return ActionResult.fail("考勤组名称重复，请换一个名称!");
        }
        return ActionResult.success();
    }

    /**
     * 删除考勤组
     *
     * @param saveAttendanceGroupDto 考勤组保存实体
     * @return Void
     */
    @DeleteMapping("/deleteGroup")
    public ActionResult<Void> delete(@RequestBody SaveAttendanceGroupDto saveAttendanceGroupDto) throws HandleException {
        /*移动考勤组*/
        String parentId = saveAttendanceGroupDto.getParentId();
        if (StrUtil.isNotBlank(parentId)) {
            AttendanceGroup moveGroup = attendanceGroupService.getById(parentId);
            if (moveGroup.getLevelCode().contains(saveAttendanceGroupDto.getId())) {
                throw new HandleException("不能将删除考勤组移动到本组获取子组!");
            }
        }

        String id = saveAttendanceGroupDto.getId();
        AttendanceGroup group = attendanceGroupService.getById(id);
        if (group.getDeleteMark() == 1) {
            throw new HandleException("该考勤组已删除，请勿频繁操作!");
        }

        attendanceGroupService.delete(saveAttendanceGroupDto.getId(), saveAttendanceGroupDto.getParentId());
        return ActionResult.success();
    }

    /**
     * 借调时展示我能查看到的考勤组列表
     *
     * @return ActionResult<List < AttendanceGroupVo>>
     */
    @GetMapping("/secondedQueryGroup")
    public ActionResult<List<AttendanceGroupVo>> queryManagerGroupList(String keyword) {
        List<AttendanceGroupVo> attendanceGroupVoList = attendanceGroupService.queryManagerGroupList(keyword);
        return ActionResult.success(attendanceGroupVoList);
    }

    /**
     * 查询所有考勤组
     */
    @GetMapping("/getAllGroup")
    public ActionResult<List<AttendanceGroupVo>> getAllGroup(String keyword) {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.queryList(keyword);
        return ActionResult.success(groupVoList);
    }

    /**
     * 根据考勤组名称模糊查询考勤组列表（带权限控制）
     * 返回用户有管理权限的考勤组，支持名称模糊查询
     *
     * @param groupName 考勤组名称（支持模糊查询）
     * @return ActionResult<List<AttendanceGroupVo>>
     */
    @GetMapping("/searchByName")
    public ActionResult<List<AttendanceGroupVo>> searchGroupByName(@RequestParam String groupName) {
        return ActionResult.success(attendanceGroupService.searchGroupByName(groupName));
    }

    /**
     * 查询我所在的考勤组列表(In:app/考勤规则)
     *
     * @return ActionResult<List < AttendanceGroupVo>>
     */
    @GetMapping("/queryMyGroupList")
    public ActionResult<List<AttendanceGroup>> queryMyGroupList() {
        List<AttendanceGroup> groupList = attendanceGroupService.queryMyGroups();
        return ActionResult.success(groupList);
    }

    /**
     * 查询考勤组下成员
     *
     * @param id 考勤组id
     * @return ActionResult<List < AttendanceGroupUserVo>>
     */
    @GetMapping("/{id}/userList")
    public ActionResult<List<AttendanceGroupUserVo>> queryUserList(@PathVariable String id, String name, Integer type, String month) {
        Date start = DateDetail.getMonthBeginDate(month);
        Date end = DateDetail.getMonthEndDate(month);
        return ActionResult.success(attendanceUserService.queryUsersByGroupId(id, name, type, null, start,end));
    }

    /**
     * 借调查询考勤组下成员
     *
     * @param id 考勤组id
     * @return ActionResult<List < AttendanceGroupUserVo>>
     */
    @GetMapping("/userList")
    public ActionResult<List<AttendanceGroupUserVo>> queryUserListOfSecondment(@RequestParam String id, @RequestParam(required = false) String name, @RequestParam(required = false) Integer type, @RequestParam(required = false) String time) {
        Assert.isFalse(StringUtil.isBlank(time), "未选择借调时间");
        String[] split = StringUtil.split(time, ",");
        Assert.isFalse(split.length < 2, "未选择借调时间");
        Date secondedStartTime = new Date(Long.parseLong(split[0]));
        Date secondedEndTime = new Date(Long.parseLong(split[1]));
        List<AttendanceGroupUserVo> listActionResult = attendanceUserService.queryUsersByGroupId(id, name, type,null, secondedStartTime, secondedEndTime);
        if (listActionResult!= null) {
            listActionResult.forEach(v -> {
                v.setRealName(v.getRealName() + "（" + v.getPositionName() + "）");
            });
        }
        return ActionResult.success(listActionResult);
    }

    /**
     * 考勤组下拉列表
     *
     * @return ActionResult<List < AttendanceGroup>>
     */
    @GetMapping("/dropList")
    public ActionResult<List<AttendanceGroup>> dropList() {
        List<AttendanceGroup> dropList = attendanceGroupService.queryDropList();
        return ActionResult.success(dropList);
    }

    /**
     * 借调开始
     *
     * @param attendanceSecondedDto 借调参数数据
     * @return ActionResult<Void>
     */
    @PostMapping("/secondedStart")
    public ActionResult<Void> secondedStart(@RequestBody AttendanceSecondedDto attendanceSecondedDto) throws HandleException {
        attendanceGroupService.secondedStart(attendanceSecondedDto);
        return ActionResult.success();
    }

    /**
     * 切换考勤组配置状态
     *
     * @param dto 考勤组配置状态参数
     * @return ActionResult<Void>
     */
    @PutMapping("/exchangeGroupStatus")
    public ActionResult<Void> exchangeGroupStatus(@RequestBody AttendanceGroupStatusDto dto) {
        attendanceGroupService.exchangeGroupStatus(dto);
        return ActionResult.success();
    }

    /**
     * 获取考勤组配置状态
     *
     * @param groupId 考勤组id
     * @return ActionResult<Void>
     */
    @GetMapping("groupSettingStatus")
    public ActionResult<AttendanceGroupStatusDto> groupSettingStatus(@RequestParam String groupId) {
        return ActionResult.success(attendanceGroupService.groupSettingStatus(groupId, Boolean.FALSE));
    }

    /**
     * 获取默认考勤组
     *
     * @return ActionResult<AttendanceGroup>
     */
    @GetMapping("/getDefaultGroup")
    public ActionResult<AttendanceGroupVo> getDefaultGroup() {
        AttendanceGroupVo defaultGroup = attendanceGroupService.getDefaultGroup();
        return ActionResult.success(defaultGroup);
    }

    /**
     * 切换考勤组
     *
     * @param groupId 考勤组Id
     * @return ActionResult<Void>
     */
    @GetMapping("/handoffGroup")
    public ActionResult<Void> handoffGroup(String groupId) {
        attendanceGroupService.handoffGroup(groupId);
        return ActionResult.success();
    }

    /**
     * 排班考勤组列表
     *
     * @return ActionResult<AttendanceGroupVo>
     */
    @GetMapping("/schedulingGroupList")
    public ActionResult<List<AttendanceGroupVo>> schedulingGroupList() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.schedulingGroupList();
        return ActionResult.success(groupVoList);
    }

    /**
     * 排班考勤组列表过滤固定班
     *
     * @return ActionResult<AttendanceGroupVo>
     */
    @GetMapping("/schedulingGroupListByNotFixed")
    public ActionResult<List<AttendanceGroupVo>> schedulingGroupListByNotFixed() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.schedulingGroupListByNotFixed();
        return ActionResult.success(groupVoList);
    }

    /**
     * 余额考勤组列表
     *
     * @return ActionResult<AttendanceGroupVo>
     */
    @GetMapping("/balanceManagementGroupList")
    public ActionResult<List<AttendanceGroupVo>> balanceManagementGroupList() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.balanceManagement();
        return ActionResult.success(groupVoList);
    }

    /**
     * 查询我有借调权限的考勤组管理列表
     *
     */
    @GetMapping("/querySecondedApprovalGroupList")
    public ActionResult<List<AttendanceGroupVo>> querySecondedApprovalGroupList() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.secondedApprovalGroupList();
        return ActionResult.success(groupVoList);
    }

    /**
     * 切换考勤组查询我管理的考勤组
     *
     */
    @GetMapping("/handoffGroupTreeList")
    public ActionResult<List<AttendanceGroupVo>> handoffGroupTreeList() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.handoffGroupTreeList();
        return ActionResult.success(groupVoList);
    }

    /**
     * 通过组织Id找到组织下的考勤组
     *
     * @param orgId 组织Id
     */
    @GetMapping("/groupListByOrgId/{orgId}")
    public ActionResult<List<AttendanceGroupVo>> groupListByOrgId(@PathVariable("orgId") String orgId) {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.groupListByOrgId(orgId);
        return ActionResult.success(groupVoList);
    }

    /**
     * 通过组织Id找到组织下的考勤组
     *
     * @param orgId 组织Id
     */
    @GetMapping("/groupListByOrgId")
    public ActionResult<List<AttendanceGroupVo>> groupListByOrgIds(@RequestParam("orgId") String orgId) {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.groupListByOrgId(orgId);
        return ActionResult.success(groupVoList);
    }

    /**
     * 通过考勤组Id获取绑定的组织名称（拼接好的）及考勤组人数
     *
     * @param groupId 考勤组Id
     */
    @GetMapping("/getGroupBindingOrg/{groupId}")
    public ActionResult<AttendanceGroupVo> getGroupBindingOrg(@PathVariable("groupId") String groupId,@RequestParam(value = "workGroupId",required = false) String workGroupId) {
        return ActionResult.success(attendanceGroupService.getGroupBindingOrg(groupId, workGroupId));
    }
    /**
     * 划线排班-通过考勤组Id获取绑定的组织名称（拼接好的）及考勤组人数
     *
     * @param groupId 考勤组Id
     */
    @GetMapping("/line/getGroupBindingOrg/{groupId}")
    public ActionResult<AttendanceGroupVo> getGroupBindingOrgForLine(@PathVariable("groupId") String groupId,@RequestParam(value = "workGroupId",required = false) String workGroupId) {
        return ActionResult.success(attendanceGroupService.getGroupBindingOrgForLine(groupId, workGroupId));
    }


    /**
     * 绑定考勤组的组织
     *
     * @param attendanceGroupOrgDto 考勤组和组织信息
     */
    @PutMapping("/updateGroupOrg")
    public ActionResult<Void> updateGroupOrg(@RequestBody AttendanceGroupOrgDto attendanceGroupOrgDto) {
        attendanceGroupService.updateGroupOrg(attendanceGroupOrgDto);
        return ActionResult.success();
    }

    /**
     * 获取考勤组名称
     *
     * @param groupId 考勤组Id
     */
    @Override
    @GetMapping("/queryTheNameOfTheAttendanceGroup")
    public AttendanceGroup queryTheNameOfTheAttendanceGroup(@RequestParam(value = "groupId") String groupId) {
        LambdaQueryWrapper<AttendanceGroup> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttendanceGroup::getId, groupId);
        queryWrapper.eq(AttendanceGroup::getDeleteMark, 0);
        return attendanceGroupService.getOne(queryWrapper);
    }

    /**
     * 获取用户考勤组
     *
     * @param userIds 用户ids
     */
    @Override
    @GetMapping("/attendanceUserGroup")
    public List<AttendanceUserGroupVo> getAttendanceUserGroup(@RequestParam("userIds") List<String> userIds) {
        return attendanceGroupService.getAttendanceUserGroup(userIds);
    }

    /**
     * 批量获取用户绑定的考勤组 ,包含全名称 xxx/xxx/xxx
     *
     * @param userIds 用户ids
     */
    @Override
    @PostMapping("/list/user_bound")
    public ActionResult<List<AttendanceUserListGroupVO>> getAttendanceUserListGroupVO(@RequestBody List<String> userIds) {

        return ActionResult.success(attendanceGroupService.getAttendanceUserListGroupVO(userIds));
    }

    /**
     * 获取组织下的考勤组
     *
     * @param organizeId 组织id
     * @return List<AttendanceGroup>
     */
    @GetMapping("/getGroupListByOrgId")
    @Override
    public List<AttendanceGroup> getGroupListByOrgId(@RequestParam("organizeId") String organizeId) {
        QueryWrapper<AttendanceGroup> groupQuery = new QueryWrapper<>();
        groupQuery.lambda()
                .eq(AttendanceGroup::getOrgId, organizeId);
        return attendanceGroupService.getByOrgId(organizeId);
    }

    /**
     * 详情---获取一个考勤组
     *
     * @param organizeName 组织名称
     * @param groupName    考勤组名称
     * @return 一个考勤组
     */
    @Override
    @GetMapping("/info/organize_group/name")
    public ActionResult<AttendanceGroupVo> getAttendanceGroupByName(@RequestParam("organizeName") String organizeName, @RequestParam("groupName") String groupName) {

        return ActionResult.success(attendanceGroupService.getAttendanceGroupByNameOrganizeAndGroup(organizeName, groupName));
    }

    /**
     * 锁定考勤组
     *
     * @param groupId 考勤组id
     */
    @PutMapping(value = "/lock/{groupId}")
    public Object lockGroup(@PathVariable(value = "groupId") String groupId) {

        attendanceGroupService.lockGroup(groupId);
        return ActionResult.success();
    }
    /**
     * 考勤组2.0历史数据处理
     *
     * @param tenantId 考勤组id
     */
    @GetMapping(value = "/oldDataProcessing/{tenantId}")
    @NoDataSourceBind
    public Object oldDataProcessing(@PathVariable(value = "tenantId") String tenantId) {
        attendanceGroupService.oldDataProcessing(tenantId);
        return ActionResult.success();
    }

    /**
     * 查询用户当前考勤组锁定信息
     *
     * @param userId 用户id
     * @return java.lang.Object
     */
    @GetMapping(value = "/lockInfo/{userId}")
    public Object getUserCurrentGroupLockInfo(@PathVariable(value = "userId") String userId) throws Exception {

        GroupLockVo groupLockVo = attendanceGroupService.getUserCurrentGroupLockInfo(userId);
        return ActionResult.success(groupLockVo);
    }

    /**
     * 查询当前考勤组锁定信息
     *
     * @param groupId 考勤组id
     * @return java.lang.Object
     */
    @GetMapping(value = "/groupLockInfo/{groupId}")
    public Object getGroupLockInfo(@PathVariable(value = "groupId") String groupId) throws Exception {

        GroupLockVo groupLockVo = attendanceGroupService.getGroupLockInfo(groupId);
        return ActionResult.success(groupLockVo);
    }

    /**
     * 查询用户所在考勤组是否有指定权限
     * @param appointPermission 参数
     */
    @GetMapping("/appointPermission")
    public ActionResult<Boolean> appointPermission(AppointPermission appointPermission) {
        return ActionResult.success(attendanceGroupService.appointPermission(appointPermission));
    }

    //*************************************考勤V1.9***************************************************/

    /**
     * V1.9 查询考勤组管理列表
     * @param groupQueryDto 考勤组名称查询实体
     * @return List<AttendanceGroupVo>
     */
    @GetMapping("/list")
    public ActionResult<List<AttendanceGroupVo>> groupList(GroupQueryDto groupQueryDto) {
        return ActionResult.success(attendanceGroupService.groupMyManagerList(groupQueryDto));
    }


    /**
     *  V1.9 排班考勤组列表过滤固定班
     * @return ActionResult<AttendanceGroupVo>
     */
    @GetMapping("/schedulingGroupListByNotFixedNew")
    public ActionResult<List<AttendanceGroupVo>> schedulingGroupListByNotFixedNew() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.schedulingGroupListByNotFixedNew();
        return ActionResult.success(groupVoList);
    }

    /**
     *  V1.9 切换考勤组查询我管理的考勤组
     */
    @GetMapping("/handoffGroupTreeListNew")
    public ActionResult<List<AttendanceGroupVo>> handoffGroupTreeListNew() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.handoffGroupTreeListNew();
        return ActionResult.success(groupVoList);
    }

    /**
     * v1.9获取默认考勤组
     *
     * @return ActionResult<AttendanceGroup>
     */
    @GetMapping("/getDefaultGroupNew")
    public ActionResult<AttendanceGroupVo> getDefaultGroupNew() {
        AttendanceGroupVo defaultGroup = attendanceGroupService.getDefaultGroupNew();
        return ActionResult.success(defaultGroup);
    }

    /**
     * v1.9排班考勤组列表
     */
    @GetMapping("/schedulingGroupListNew")
    public ActionResult<List<AttendanceGroupVo>> schedulingGroupListNew() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.schedulingGroupListNew();
        return ActionResult.success(groupVoList);
    }


    /**
     * v1.9余额考勤组列表
     */
    @GetMapping("/balanceManagementGroupListNew")
    public ActionResult<List<AttendanceGroupVo>> balanceManagementGroupListNew() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.balanceManagementNew();
        return ActionResult.success(groupVoList);
    }


    /**
     * V2.0 出勤变更查询考勤组列表
     */
    @GetMapping("/querySecondedApprovalGroupListNew")
    public ActionResult<List<AttendanceGroupVo>> querySecondedApprovalGroupListNew() {
        List<AttendanceGroupVo> groupVoList = attendanceGroupService.secondedApprovalGroupListNew();
        return ActionResult.success(groupVoList);
    }

    /**
     * 是否有考勤组排班权限排班
     */
    @Override
    @GetMapping("/checkScheduling")
    public boolean checkScheduling() {
        return attendanceGroupService.checkScheduling();
    }

    /**
     * 获取有指定模块的权限的考勤组管理列表
     *
     * @param positionModuleName 权限模块名称
     * @return List<AttendanceGroupVo>
     */
    @GetMapping("/getPermissionsGroupList")
    public ActionResult<List<AttendanceGroupVo>> getPermissionsGroupList(@RequestParam("positionModuleName") String positionModuleName) {
        return ActionResult.success(attendanceGroupService.getPermissionsGroupList(positionModuleName));
    }

    /**
     * 获取端考勤组列表(左侧选择组织||考勤组)
     */
    @GetMapping("/getOrgOrGroupList")
    public ActionResult<List<AttendanceOrgOrGroupVo>> getOrgOrGroupList(String keyword) {
        return ActionResult.success(attendanceGroupService.getOrgOrGroupList(keyword));
    }

    /**
     * 设置考勤组负责人
     *
     * @param dto 考勤组负责人信息
     * @return Boolean
     */
    @PutMapping(value = "/setGroupCharge")
    public ActionResult<Boolean> setGroupCharge(@Valid @RequestBody AttendanceGroupChargeDto dto) {
        return ActionResult.success(attendanceGroupService.setGroupCharge(dto));
    }

    /**
     * 获取考勤组负责人
     *
     * @param groupId 考勤组id
     * @return List<AttendanceGroupVo>
     */
    @GetMapping(value = "/getGroupChargeInfo/{groupId}")
    public ActionResult<AttendanceGroupChargeVo> getGroupChargeInfo(@PathVariable(value = "groupId") String groupId) {
        return ActionResult.success(attendanceGroupService.getGroupChargeInfo(groupId));
    }
}
