package jnpf.personnels.controller.web.employmentapply;

import jnpf.authority.utils.PermissionsEnums;
import jnpf.authority.utils.PermissionsUtils;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.vo.PageListVO;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.model.personnels.dto.audit.FtbPersonnelsAuditDto;
import jnpf.model.personnels.dto.emp.FtbEmpAddNewDTO;
import jnpf.model.personnels.dto.emp.FtbEmpConfirmDTO;
import jnpf.model.personnels.dto.emp.FtbEmpEntryDTO;
import jnpf.model.personnels.dto.emp.FtbEmpQueryDTO;
import jnpf.model.personnels.dto.oa.RequestForOA;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.staff.roster.WorkerGroupDataDto;
import jnpf.model.personnels.vo.emp.FtbEmpAddNewVO;
import jnpf.model.personnels.vo.emp.FtbEmpConfirmVO;
import jnpf.model.personnels.vo.emp.FtbEmpEntryVO;
import jnpf.model.personnels.vo.emp.FtbEmpResultVO;
import jnpf.personnels.service.FtbPersonnelsEmEntryService;
import jnpf.personnels.utils.FtbPersonnlesIMUtils;
import jnpf.personnels.utils.SmsConfig;
import jnpf.personnels.utils.SmsSendUtil;
import jnpf.util.NoDataSourceBind;
import jnpf.util.UserProvider;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * web入职管理
 * @Author: peng.hao
 * @create: 2025/4/7
 */
@RestController
@RequestMapping("/web/personnels-emp-entry")
public class FtbPersonnelsEmEntryController {

    @Resource
    FtbPersonnelsEmEntryService ftbPersonnelsEmEntryService;

    @Resource
    FtbPersonnlesIMUtils ftbPersonnlesIMUtils;

    @Resource
    RedissonClient redissonClient;

    @Resource
    PermissionsUtils permissionsUtils;

    @Autowired
    private SmsSendUtil smsSendUtil;


    @Autowired
    private SmsConfig smsConfig;

    /**
     * 查询入职管理列表
     */
    @PostMapping("/query-list")
    public ActionResult<PageListVO<FtbEmpEntryVO>> pageLists(@RequestBody FtbEmpEntryDTO empEntryDTO) {
        return ActionResult.success(ftbPersonnelsEmEntryService.pageLists(empEntryDTO, "Web"));
    }

    /**
     * 新增员工/编辑未办理员工
     */
    @PutMapping("/add-or-update-new-emp")
    public ActionResult<FtbEmpResultVO> addNewEmp(@Validated @RequestBody FtbEmpAddNewDTO dto) {
        FtbEmpResultVO result = ftbPersonnelsEmEntryService.addNewEmp(dto);
        return ActionResult.success(result);
    }
    /**
     * 查询编辑未办理员工
     */
    @GetMapping("/query-new-emp")
    public ActionResult<FtbEmpAddNewVO> queryNewEmp(String id) {
        FtbEmpAddNewVO c =  ftbPersonnelsEmEntryService.queryNewEmp(id);
        return ActionResult.success(c);
    }

    /**
     * 入职办理列表-导出
     */
    @PostMapping("/onboarding-list-export")
    public void onboardingListExport(@RequestBody FtbEmpEntryDTO req, HttpServletResponse response) throws IOException {
        ftbPersonnelsEmEntryService.onboardingListExport(req,response);
    }

    /**
     * 删除员工入职记录
     *
     * @param id 主键id，必传
     */
    @DeleteMapping("/delete/{id}")
    public ActionResult<Void> deleteEmployeeOnboardingRecords(@PathVariable("id") String id) {
        ftbPersonnelsEmEntryService.deleteEmployeeOnboardingRecords(id);
        return ActionResult.success();
    }

    /**
     * 终止入职
     */
    @PutMapping("/terminate-onboarding/{id}")
    public ActionResult<Void> terminateOnboarding(@PathVariable String id) {
        ftbPersonnelsEmEntryService.terminateOnboarding(id);
        return ActionResult.success();
    }

    /**
     * 办理入职
     */
    @PutMapping("/handle-join-job")
    public ActionResult<Void> handleJoinJob(@Validated @RequestBody FtbEmpConfirmDTO ftbEmpConfirmDTO) {
        String lockKey = "HANDLE_JOIN_JOB:" + ftbEmpConfirmDTO.getPhone();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean b = lock.tryLock(1000, TimeUnit.MILLISECONDS);
            if (!b) {return ActionResult.fail("当前手机号正在办理中请勿重复点击");}
            ftbPersonnelsEmEntryService.handleJoinJob(ftbEmpConfirmDTO);
        }catch (Exception e){
            e.printStackTrace();
            return ActionResult.fail(e.getMessage());
        }finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return ActionResult.success();
    }

    /**
     * 办理入职(oa)
     */
    @PostMapping("/handle-join-job-oa")
    public ActionResult<Void> handleJoinJobOA( @RequestBody FtbEmpConfirmDTO ftbEmpConfirmDTO) {
        String lockKey = "HANDLE_JOIN_JOB:" + ftbEmpConfirmDTO.getPhone();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean b = lock.tryLock(1000, TimeUnit.MILLISECONDS);
            if (!b) {return ActionResult.fail("当前手机号正在办理中请勿重复点击");}
            ftbPersonnelsEmEntryService.handleJoinJobOA(ftbEmpConfirmDTO);
        }catch (Exception e){
            e.printStackTrace();
            return ActionResult.fail(e.getMessage());
        }finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return ActionResult.success();
    }

    /**
     * 查看入职详情
     */
    @GetMapping("/onboarding-details")
    public ActionResult<FtbEmpConfirmVO> onboardingDetails(@RequestParam String id) {
        return ActionResult.success(ftbPersonnelsEmEntryService.onboardingDetails(id));
    }

    /**
     * 入职审批(oa)
     */
    @PostMapping("/approval")
    public ActionResult<Void> onboardingApprovals(@RequestBody FtbPersonnelsAuditDto personnelsAuditDto) {
        ftbPersonnelsEmEntryService.onboardingApprovals(personnelsAuditDto);
        return ActionResult.success();
    }

    /**
     * 入职撤回(oa)
     */
    @PostMapping("/revoke")
    public ActionResult<Void> onboardingWithdrawal(@RequestBody FtbPersonnelsAuditDto personnelsAuditDto) {
        ftbPersonnelsEmEntryService.onboardingWithdrawal(personnelsAuditDto);
        return ActionResult.success();
    }

    /**
     * 发送im消息通知
     * @param userId  用户id
     */
    @GetMapping("/send-im-msg")
    public ActionResult<Void> sendImMsg(String userId,String url){
        UserInfo user = UserProvider.getUser();
        if(userId.equals(user.getUserId())){
            return ActionResult.fail("不能发送给自己");
        }

        ftbPersonnlesIMUtils.sendMsg(user.getTenantId(),userId,user.getUserName());
        return ActionResult.success();
    }
    /**
     * (oa)计算计划转正日期
     * @param workType 正式 / 试用
     * @param probationPeriod 试用期
     * @param probationPeriodDay 试用天数
     * @param actualStartDate 入职日期
     */
    @GetMapping("/calculate-planned-conversion-date")
    public ActionResult<Map<String, Object>> calculatePlannedConversionDate(String workType,
                                                                            String probationPeriod,
                                                                            String probationPeriodDay,
                                                                            String actualStartDate)  {
        if(workType.equals("303")){
            Map<String, Object> map = new HashMap<>();
            map.put("conversionDate",actualStartDate);
            return ActionResult.success(map);
        }
        // 入职日期
        int probation = 0;
        // 创建一个 Calendar 实例并设置为当前日期
        Calendar calendar = Calendar.getInstance();
        long timestamp = Long.parseLong(actualStartDate);
        Date date = new Date(timestamp);
        calendar.setTime(date);
        if ("101".equals(probationPeriod) && StringUtils.isEmpty(probationPeriodDay)) throw new RuntimeException("请选择试用期天数!");
        if ("101".equals(probationPeriod) && StringUtils.isNotEmpty(probationPeriodDay)) {
            // 这里就是天数
            calendar.add(Calendar.DAY_OF_MONTH, Integer.parseInt(probationPeriodDay));
        } else {
            switch (probationPeriod) {
                case "102":
                    probation = 1;
                    break;
                case "103":
                    probation = 2;
                    break;
                case "104":
                    probation = 3;
                    break;
                case "105":
                    probation = 4;
                    break;
                case "106":
                    probation = 5;
                    break;
                case "107":
                    probation = 6;
                    break;
                case "108":
                    probation = 7;
                    break;
                case "109":
                    probation = 8;
                    break;
                case "110":
                    probation = 9;
                    break;
                case "111":
                    probation = 10;
                    break;
                case "112":
                    probation = 11;
                    break;
                case "113":
                    probation = 12;
            }
            calendar.add(Calendar.MONTH, probation);
        }
        Date time = calendar.getTime();
        Map<String, Object> map = new HashMap<>();
        map.put("conversionDate",time);
        return ActionResult.success(map);
    }

    /**
     * (oa)试用天数 返回 1到 30的值
     */
    @GetMapping("/probation-period-day")
    public ActionResult<List<Map<String, Object>>> probationPeriodDay(){
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,31);
        List<Map<String, Object>> collect = integers.stream().map(i -> {
            Map<String, Object> map = new HashMap<>();
            map.put("day", i);
            return map;
        }).collect(Collectors.toList());
        return ActionResult.success(collect);
    }

    /**
     * (oa)查询入职人员列表
     */
    @GetMapping("/onboarding-list")
    public ActionResult<List<FtbEmpEntryVO>> onboardingList(String phone) {
        List<FtbEmpEntryVO> entryVOS = ftbPersonnelsEmEntryService.onboardingList(phone);
        return ActionResult.success(entryVOS);
    }

    /**
     * (oa) 根据userId加组织id查询填写班组信息
     *
     * @param request
     * @return
     */
    @PostMapping("/queryCrewsWithEntry")
    public ActionResult<List<WorkerGroupDataDto>> queryCrewsWithEntry(@RequestBody RequestForOA request) {
        if (request.getPrimaryKeyId() != null && StringUtils.isNotEmpty(request.getAffiliatedOrg())){
            List<WorkerGroupDataDto>  workerGroupDataDto  =  ftbPersonnelsEmEntryService.queryCrewsWithEntry(request);
            return ActionResult.success(workerGroupDataDto);
        }
        return ActionResult.success();
    }
    /**
     * 测试是否有权限发消息
     */
    @SneakyThrows
    @GetMapping("/test-im-msg")
    @NoDataSourceBind
    public ActionResult<List<String>> testImMsg(String userId,String tenantId,String currOrg,String moduleId){
        TenantDataSourceUtil.switchTenant(tenantId);
        new Thread(()->{
            List<String> stringList = permissionsUtils.getUserPersonnelOrganizationIdDataPermissions(userId,
                    List.of(PermissionsEnums.PERSONNEL_MANAGEMENT_Button.getValue().split(",")),
                    "",
                    List.of(PermissionsEnums.PERSONNEL_MANAGEMENT_WEB.getValue(),
                            PermissionsEnums.PERSONNEL_MANAGEMENT_APP.getValue()),
                    tenantId, currOrg,moduleId);
            ftbPersonnlesIMUtils.sendMsgWithList(tenantId,stringList, "测试发送角色", moduleId);
        }).start();
        return ActionResult.success();
    }
    /**
     * 根据userId修改手机号信息
     */
    @PutMapping("/update-phone-by-userId")
    public void updatePhoneByUserId( @RequestParam("userId") String userId,
                                                   @RequestParam("phone") String phone){
        ftbPersonnelsEmEntryService.updatePhoneByUserId(userId,phone);
    }

    @GetMapping("/send-sms")
    @NoDataSourceBind
    public ActionResult<Void> sendImMsg(String phone,String tenantId,String code) throws Exception {
        Map<String, SmsConfig.TenantConfig> tenants = smsConfig.getTenants();
        SmsConfig.TenantConfig tenantConfig;
        if (tenants.containsKey(tenantId)){
            tenantConfig = tenants.get(tenantId);
        }else {
            tenantConfig = tenants.get("common");
        }
        String signContent = tenantConfig.getSmsSignContent();
        HashMap<String, Object> map = new HashMap<>();
        map.put("1", signContent);
        map.put("2", phone);
        map.put("3", "0000");
        smsSendUtil.sendSms(List.of(phone), code,map ,null);
        return ActionResult.success();
    }

    /**
     * 薪酬搜索 电话 名称
     */
    @PostMapping("/search-phone-name")
    public List<FtbPersonnelsStaffRosterDto> searchPhoneName(@RequestBody FtbEmpQueryDTO dto){
        List<FtbPersonnelsStaffRosterDto> maps = ftbPersonnelsEmEntryService.searchPhoneName(dto);
        return maps;
    }
}

