package jnpf.personnels.controller.web.rewardspunishments;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import jnpf.base.ActionResult;
import jnpf.base.vo.PageListVO;
import jnpf.model.cultivate.CultivatePage;
import jnpf.model.personnels.dto.rewardspunishments.FtbEmployeeRewardRecordsQueryDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelSalaryRewardDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentExchangeOrderDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentQueryDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentStartDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentsAddDTO;
import jnpf.model.personnels.dto.rewardspunishments.FtbPersonnelsRewardsPunishmentsUpdateDTO;
import jnpf.model.personnels.dto.roster.FtbRosterImportDTO;
import jnpf.model.personnels.dto.salary.FtbSalaryMetaDataQueryDto;
import jnpf.model.personnels.dto.staff.roster.FtbPersonnelsStaffRosterDto;
import jnpf.model.personnels.dto.staff.roster.WorkerGroupDataDto;
import jnpf.model.personnels.req.roster.StaffRosterListReq;
import jnpf.model.personnels.vo.rewardspunishments.FtbEmployeeRewardRecordsVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbEmployeeRewardUserInfoVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelSalaryRewardVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelsRewardsPunishmentApprovalVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbPersonnelsRewardsPunishmentQueryVO;
import jnpf.model.personnels.vo.rewardspunishments.FtbXcEmployeeRewardRecordsVO;
import jnpf.permission.UserApi;
import jnpf.personnels.mapper.FtbPersonnelsRewardsPunishmentsMapper;
import jnpf.personnels.service.FtbPersonnelsRewardsPunishmentsService;
import jnpf.personnels.service.FtbPersonnelsStaffRosterService;
import jnpf.util.NoDataSourceBind;
import jnpf.util.TenantUtil;
import jnpf.util.excel.EasyExcelUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.annotation.Validated;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * web人事奖惩模块
 *
 * @author wcx
 * @since 2024-05-08
 */
@RestController
@RequestMapping("/ftb-personnels-rewards-punishments")
public class FtbPersonnelsRewardsPunishmentsController {

    @Resource
    private FtbPersonnelsRewardsPunishmentsService ftbPersonnelsRewardsPunishmentsService;

    @Autowired
    private TenantUtil tenantUtil;

    @Autowired
    UserApi userApi;

    @Resource
    FtbPersonnelsStaffRosterService staffRosterService;

    @Resource
    FtbPersonnelsRewardsPunishmentsMapper rewardsPunishmentsMapper;


    /**
     * 新增奖惩规则
     *
     * @param rewardsPunishmentsAddDTO
     * @return {@link ActionResult }
     */
    @PostMapping(value = "/add")
    public ActionResult add(@Validated @RequestBody FtbPersonnelsRewardsPunishmentsAddDTO rewardsPunishmentsAddDTO) {
        ftbPersonnelsRewardsPunishmentsService.add(rewardsPunishmentsAddDTO);
        return ActionResult.success();
    }

    /**
     * 删除奖惩规则
     *
     * @param id 主键id(必填)
     * @return {@link ActionResult }
     */
    @DeleteMapping(value = "/delete/{id}")
    public ActionResult delete(@PathVariable("id") String id) {
        ftbPersonnelsRewardsPunishmentsService.delete(id);
        return ActionResult.success();
    }

    /**
     * 编辑奖惩规则
     *
     * @return {@link ActionResult }
     */
    @PostMapping(value = "/update")
    public ActionResult updateData(@Validated @RequestBody FtbPersonnelsRewardsPunishmentsUpdateDTO rewardsPunishmentsUpdateDTO) {
        ftbPersonnelsRewardsPunishmentsService.updateData(rewardsPunishmentsUpdateDTO);
        return ActionResult.success();
    }

    /**
     * 奖惩规则启用/禁用
     *
     * @return {@link ActionResult }
     */
    @PostMapping(value = "/start-and-stop")
    public ActionResult startAndStop(@Validated @RequestBody FtbPersonnelsRewardsPunishmentStartDTO rewardsPunishmentStartDTO) {
        ftbPersonnelsRewardsPunishmentsService.startAndStop(rewardsPunishmentStartDTO);
        return ActionResult.success();
    }

    /**
     * 奖惩规则列表
     *
     * @return {@link ActionResult }
     */
    @GetMapping(value = "/list")
    public ActionResult<List<FtbPersonnelsRewardsPunishmentQueryVO>> listData(FtbPersonnelsRewardsPunishmentQueryDTO rewardsPunishmentQueryDTO) {
        List<FtbPersonnelsRewardsPunishmentQueryVO> results = ftbPersonnelsRewardsPunishmentsService.listQuery(rewardsPunishmentQueryDTO);
        return ActionResult.success(results);
    }

    /**
     * 奖惩规则交换顺序
     *
     * @return {@link ActionResult }
     */
    @PostMapping(value = "/exchange-order")
    public ActionResult exchangeOrder(@Validated @RequestBody FtbPersonnelsRewardsPunishmentExchangeOrderDTO rewardsPunishmentExchangeOrderDTO) {
        ftbPersonnelsRewardsPunishmentsService.exchangeOrder(rewardsPunishmentExchangeOrderDTO);
        return ActionResult.success();
    }

    /**
     * OA审批获取奖惩规则
     *
     * @param type     类型，0奖励，1惩罚
     * @param tenantId 租户ID
     * @return {@link ActionResult }
     */
    @GetMapping(value = "/list-approval-second")
    @NoDataSourceBind
    public ActionResult<List<FtbPersonnelsRewardsPunishmentApprovalVO>> listApproval(@RequestParam("type") Integer type
            , @RequestParam(value = "tenantId") String tenantId) {
        tenantUtil.switchTenant(tenantId);
        List<FtbPersonnelsRewardsPunishmentApprovalVO> results = ftbPersonnelsRewardsPunishmentsService.listApproval(type);
        return ActionResult.success(results);
    }

    /**
     * OA审批获取奖惩规则
     *
     * @param type 类型，0奖励，1惩罚
     * @return {@link ActionResult }
     */
    @GetMapping(value = "/list-approval")
    public ActionResult<List<FtbPersonnelsRewardsPunishmentApprovalVO>> listApprovalSecond(@RequestParam("type") Integer type) {
        List<FtbPersonnelsRewardsPunishmentApprovalVO> results = ftbPersonnelsRewardsPunishmentsService.listApproval(type);
        return ActionResult.success(results);
    }

    /**
     * 薪酬奖励合计
     */
    @PostMapping(value = "/salary-reward")
    public List<FtbPersonnelSalaryRewardVO> salaryReward(@RequestBody @Validated FtbPersonnelSalaryRewardDTO ftbPersonnelSalaryRewardDTO) {
        return ftbPersonnelsRewardsPunishmentsService.salaryReward(ftbPersonnelSalaryRewardDTO);
    }

    /**
     * 薪酬惩罚合计
     */
    @PostMapping(value = "/pay-penalty")
    public List<FtbPersonnelSalaryRewardVO> totalSalaryPenalty(@RequestBody @Validated FtbPersonnelSalaryRewardDTO ftbPersonnelSalaryRewardDTO) {
        return ftbPersonnelsRewardsPunishmentsService.totalSalaryPenalty(ftbPersonnelSalaryRewardDTO);
    }

    /**
     * OA奖惩审批金额查询
     *
     * @param id 奖惩id
     * @return {@link ActionResult }<{@link FtbPersonnelsRewardsPunishmentApprovalVO }>
     */
    @GetMapping(value = "/list-approval-money")
    public ActionResult<FtbPersonnelsRewardsPunishmentApprovalVO> listApprovalMoney(@RequestParam("id") String id) {
        FtbPersonnelsRewardsPunishmentApprovalVO results = ftbPersonnelsRewardsPunishmentsService.listApprovalMoney(id);
        return ActionResult.success(results);
    }

    /**
     * @param tenantId 租户ID
     * @param type     奖惩类型 类型，0奖励，1惩罚
     * @param typeName 类型名称
     * @return :java.math.BigDecimal 金额
     * @decription 薪酬获取人事奖惩金额
     * @date 2024/11/5 17:27
     * @author AoTeMan
     */
    @PostMapping(value = "/salaryMetaDataQuery")
    @NoDataSourceBind
    public BigDecimal salaryMetaDataQuery(@RequestBody FtbSalaryMetaDataQueryDto dto) {
        tenantUtil.switchTenant(dto.getTenantId());
        return ftbPersonnelsRewardsPunishmentsService.salaryMetaDataQuery(dto);
    }

    @PostMapping(value = "/salary-meta-data-batch-query")
    @NoDataSourceBind
    public List<FtbXcEmployeeRewardRecordsVO> salaryBatchMetaDataQuery(@RequestBody FtbSalaryMetaDataQueryDto dto) {
        tenantUtil.switchTenant(dto.getTenantId());
        return ftbPersonnelsRewardsPunishmentsService.salaryBatchMetaDataQuery(dto);
    }


    /**
     * 员工奖惩记录列表
     *
     * @return {@link ActionResult }
     */
    @GetMapping("/employee-punishment-records-list")
    public ActionResult<PageListVO<FtbEmployeeRewardRecordsVO>> employeeRewardAndPunishmentRecords(CultivatePage cultivatePage, FtbEmployeeRewardRecordsQueryDTO queryDTO) {
        Page<FtbEmployeeRewardRecordsVO> page = cultivatePage.coverCultivatePage("g.operateTime");
        page = ftbPersonnelsRewardsPunishmentsService.employeeRewardAndPunishmentRecords(page, queryDTO);
        return ActionResult.success(CultivatePage.coverPageList(page));
    }

    /**
     * 员工详情
     */
    @GetMapping("/employee-punishment-records-detail")
    public ActionResult<FtbEmployeeRewardRecordsVO> queryDetail(@RequestParam("id") String id) {
        FtbEmployeeRewardRecordsVO results = ftbPersonnelsRewardsPunishmentsService.queryDetail(id);
        return ActionResult.success(results);
    }
    /**
     * 员工奖惩记录列表导出
     */
    @GetMapping(value = "/list-export")
    public void listExport(CultivatePage cultivatePage
            , FtbEmployeeRewardRecordsQueryDTO queryDTO) throws IOException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse httpServletResponse = requestAttributes.getResponse();
        Page<FtbEmployeeRewardRecordsVO> page = cultivatePage.coverCultivatePage("g.operateTime");
        page.setSize(-1);
        page = ftbPersonnelsRewardsPunishmentsService.employeeRewardAndPunishmentRecords(page, queryDTO);
        page.getRecords().forEach(item -> {
            item.setTypeName(item.getType() == 1 ? "乐捐" : "奖励");
            //  0.审核中  1.通过 2.未通过 3撤回,4 无需审批
            Integer status = item.getStatus();
            if (status == 0){
                item.setStatusName("审核中");
            }else if (status == 1){
                item.setStatusName("已通过");
            }else if (status == 2){
                item.setStatusName("审批不通过");
            }else if (status == 3){
                item.setStatusName("已撤回");
            }else if (status == 4){
                item.setStatusName("无需审批");
            }
        });
        EasyExcelUtils.exportExcel(httpServletResponse, "员工奖惩记录", page.getRecords(), FtbEmployeeRewardRecordsVO.class);
    }

    /**
     * 导入
     *
     * @param file
     * @return
     */
    @PostMapping("/importData")
    public ActionResult<Object> importData(@RequestBody @Validated FtbRosterImportDTO file) {
        Map<String, Object> stringObjectMap;
        try (InputStream inputStream = EasyExcelUtils.checkExcelFile(file.getFileUrl())) {
            stringObjectMap = ftbPersonnelsRewardsPunishmentsService.importData(inputStream);
        } catch (Exception e) {
            return ActionResult.fail(e.getMessage());
        }
        return ActionResult.success(stringObjectMap);
    }

    /**
     * 导出错误数据
     */
    @GetMapping("/exportErrDate")
    public void exportErrData(HttpServletResponse response) throws IOException {
        ftbPersonnelsRewardsPunishmentsService.exportErrData(response);
    }

    /**
     * 导入点击
     * @param type   类型，0奖励，1惩罚
     */
    @GetMapping("/importData/click")
    public ActionResult<Object> importDataClick(@RequestParam("type") Integer type,
                                                @RequestParam("orgId") String orgId) {
        ftbPersonnelsRewardsPunishmentsService.importDataClick(type,orgId);
        return ActionResult.success();
    }
    /**
     * 导出模版文件
     * @param type   类型，0奖励，1惩罚
     *  @param orgId 组织id
     */
    @GetMapping("/exportTheTemplate")
    public void exportTheTemplate(@RequestParam("type") Integer type,
                                  @RequestParam("orgId") String orgId,
                                  HttpServletResponse httpServletResponse) throws IOException {
        String templateFileName ="classpath:roster/rewards.xlsx";
        StaffRosterListReq req = new StaffRosterListReq();
        req.setCurrOrg(orgId);
        req.setPageSize(-1);
        req.setIsQueryAuth("0");
        PageInfo<FtbPersonnelsStaffRosterDto> list = staffRosterService.getPageList(req,false);
        List<FtbPersonnelsStaffRosterDto> collection = list.getList();
        List<FtbEmployeeRewardUserInfoVO> userInfoVOList = new ArrayList<>();
        if (CollUtil.isNotEmpty(collection)) {
            Map<String, FtbPersonnelsStaffRosterDto> voMap = collection.stream().collect(Collectors.toMap(FtbPersonnelsStaffRosterDto::getUserId, Function.identity()));
                userInfoVOList =  collection.stream().map(item -> {
                    FtbEmployeeRewardUserInfoVO vo = new FtbEmployeeRewardUserInfoVO();
                    WorkerGroupDataDto userInfoVo = voMap.get(item.getUserId()).getOrgList()
                            .stream().findFirst().orElse(new WorkerGroupDataDto());
                    vo.setName(item.getName());
                    vo.setEmployeeId(item.getSystemWokerId());
                    vo.setOrgName(userInfoVo.getAffiliatedOrgName());
                    vo.setPostName(userInfoVo.getAffiliatedPositionName());
                    if (type == 0) {
                        vo.setType("奖励");
                    } else {
                        vo.setType("乐捐");
                    }
                    return vo;
                }).collect(Collectors.toList());
        }else {
            throw new RuntimeException("组织下无员工");
        }
        FtbPersonnelsRewardsPunishmentQueryDTO queryDTO = new FtbPersonnelsRewardsPunishmentQueryDTO();
        queryDTO.setType(type);
        queryDTO.setStatus(0);
        List<FtbPersonnelsRewardsPunishmentQueryVO> result = rewardsPunishmentsMapper.listQuery(queryDTO);
        httpServletResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setHeader("Content-Disposition",
                "attachment;filename*=utf-8''" + "test"+System.currentTimeMillis()+".xlsx");
        templateFileName = templateFileName.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length());
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        try (ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(new ClassPathResource(templateFileName).getInputStream()).build()) {
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            WriteSheet one = EasyExcel.writerSheet(0).build();
            WriteSheet two = EasyExcel.writerSheet(1).build();
            excelWriter.fill(userInfoVOList,fillConfig, one);
            excelWriter.fill(result,fillConfig, two);
        }
    }
    /**
     * 删除人员记录
     * @param id
     * @param type  类型，0奖励，1惩罚
     */
    @DeleteMapping("/deleteUserInfo/{id}/{type}")
    public ActionResult deleteUserInfo(@PathVariable("id") String id,
                                       @PathVariable("type") Integer type) {
        ftbPersonnelsRewardsPunishmentsService.deleteUserInfo(id,type);
        return ActionResult.success("删除成功");
    }
}
