package com.engine.salary.web;

import com.engine.common.util.ServiceUtil;
import com.engine.salary.entity.SalarySobExtRangePO;
import com.engine.salary.entity.salaryitem.dto.SalaryItemSobListDTO;
import com.engine.salary.entity.salaryitem.param.SalaryItemSearchParam;
import com.engine.salary.entity.salarysob.dto.*;
import com.engine.salary.entity.salarysob.param.*;
import com.engine.salary.entity.salarysob.po.SalarySobItemGroupPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.util.ResponseResult;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.wrapper.*;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 薪资账套
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalarySobController {


    private SalarySobWrapper getSalarySobWrapper(User user) {
        return ServiceUtil.getService(SalarySobWrapper.class, user);
    }

    private SalarySobRangeWrapper getSalarySobRangeWrapper(User user) {
        return ServiceUtil.getService(SalarySobRangeWrapper.class, user);
    }

    private SalarySobItemWrapper getSalarySobItemWrapper(User user) {
        return ServiceUtil.getService(SalarySobItemWrapper.class, user);
    }

    private SalarySobAdjustRuleWrapper getSalarySobAdjustRuleWrapper(User user) {
        return ServiceUtil.getService(SalarySobAdjustRuleWrapper.class, user);
    }

    private SalarySobCheckRuleWrapper getSalarySobCheckRuleWrapper(User user) {
        return ServiceUtil.getService(SalarySobCheckRuleWrapper.class, user);
    }

    private SalarySobBackItemWrapper getSalarySobBackItemWrapper(User user) {
        return ServiceUtil.getService(SalarySobBackItemWrapper.class, user);
    }

    /**********************************薪资账套 start*********************************/

    /**
     * 薪资账套列表
     */
    @POST
    @Path("/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSalarySob(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobListQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobListQueryParam, PageInfo<SalarySobListDTO>>(user).run(getSalarySobWrapper(user)::listPage, queryParam);
    }

    /**
     * 薪资账套列表
     */
    @POST
    @Path("/listAll")
    @Produces(MediaType.APPLICATION_JSON)
    public String listAll(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobListQueryParam, List<SalarySobPO>>(user).run(getSalarySobWrapper(user)::listAll);
    }


    /**
     * 薪资账套基本信息表单
     */
    @GET
    @Path("/basic/getForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobBasicForm(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "id") Long id) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, Map<String, Object>>(user).run(getSalarySobWrapper(user)::getForm, id);
    }

    /**
     * 保存薪资账套基本信息
     */
    @POST
    @Path("/basic/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobBasicForm(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobBasicSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        if (saveParam.getId() == null || saveParam.getId() <= 0) {
            return new ResponseResult<SalarySobBasicSaveParam, Long>(user).run(getSalarySobWrapper(user)::save, saveParam);
        } else {
            return new ResponseResult<SalarySobBasicSaveParam, Long>(user).run(getSalarySobWrapper(user)::update, saveParam);
        }
    }

    /**
     * 启用/禁用薪资账套
     */
    @POST
    @Path("/disable")
    @Produces(MediaType.APPLICATION_JSON)
    public String updateSalarySobDisable(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobDisableParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobDisableParam, Map<String, Object>>(user).run(getSalarySobWrapper(user)::updateDisable, saveParam);
    }

    /**
     * 删除薪资账套
     */
    @POST
    @Path("/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalarySob(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
        }
        return new ResponseResult<Collection<Long>, Map<String, Object>>(user).run(getSalarySobWrapper(user)::delete, ids);
    }

    /**
     * 复制薪资账套
     */
    @POST
    @Path("/duplicate")
    @Produces(MediaType.APPLICATION_JSON)
    public String duplicate(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobDuplicateParam duplicateParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobDuplicateParam, Map<String, Object>>(user).run(getSalarySobWrapper(user)::duplicate, duplicateParam);
    }

    /**********************************薪资账套 end*********************************/

    /**********************************薪资账套的人员范围 start*********************************/


    /**
     * 薪资账套人员范围（包含）列表
     */
    @POST
    @Path("/range/listInclude")
    @Produces(MediaType.APPLICATION_JSON)
    public String listPage4Include(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeQueryParam, PageInfo<SalarySobRangeListDTO>>(user).run(getSalarySobRangeWrapper(user)::listPage4Include, queryParam);
    }


    /**
     * 薪资账套人员范围（排除）列表
     */
    @POST
    @Path("/range/listExclude")
    @Produces(MediaType.APPLICATION_JSON)
    public String listPage4Exclude(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeQueryParam, PageInfo<SalarySobRangeListDTO>>(user).run(getSalarySobRangeWrapper(user)::listPage4Exclude, queryParam);
    }

//
//    @GetMapping("/range/getForm")
//    @ApiOperation("薪资账套人员范围表单")
//    @WeaPermission
//    public WeaResult<WeaForm> getSalarySobRangeForm() {
//        WeaForm weaForm = salarySobRangeWrapper.getForm();
//        return WeaResult.success(weaForm);
//    }

    @POST
    @Path("/ext/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalarySobExtRange(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeExtSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeExtSaveParam, String>(user).run(getSalarySobRangeWrapper(user)::saveExtRange, saveParam);
    }

    @POST
    @Path("/range/ext/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listPage4Ext(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeQueryParam, PageInfo<SalarySobExtRangePO>>(user).run(getSalarySobRangeWrapper(user)::listPage4Ext, queryParam);
    }

    /**
     * 删除薪资账套人员范围
     */
    @POST
    @Path("/range/ext/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalarySobExtRange(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalarySobRangeWrapper(user)::deleteSalarySobExtRange, ids);
    }

    /**
     * 保存薪资账套人员范围
     */
    @POST
    @Path("/range/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalarySobRange(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeSaveParam, String>(user).run(getSalarySobRangeWrapper(user)::save, saveParam);
    }

    /**
     * 删除薪资账套人员范围
     */
    @POST
    @Path("/range/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalarySobRange(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalarySobRangeWrapper(user)::delete, ids);
    }

    /***
     * @description 下载薪资账套人员范围导入模板
     * @return Response
     * @author Harryxzy
     * @date 2023/1/9 11:10
     */
    @GET
    @Path("/range/downloadTemplate")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadSobRangeTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salarySobId") Long salarySobId) {
        User user = HrmUserVarify.getUser(request, response);
        SalarySobPO salarySobPO = Objects.isNull(salarySobId) ? null : getSalarySobWrapper(user).getSalarySobService(user).getById(salarySobId);
        if(Objects.isNull(salarySobPO)){
            throw new SalaryRunTimeException("薪资账套不存在或已被删除");
        }
        try {
            XSSFWorkbook workbook = getSalarySobRangeWrapper(user).exportImportTemplate();
            String time = LocalDate.now().toString();
            String fileName = salarySobPO.getName() + "人员范围导入模板" + time ;
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };
            response.setContentType("application/octet-stream");
            return Response.ok(output).
                    header("Content-disposition", "attachment;filename=" + fileName).
                    header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * @description 薪资账套人员范围导入预览
     * @return String
     * @author Harryxzy
     * @date 2023/1/9 13:32
     */
    @POST
    @Path("/range/preview")
    @Produces(MediaType.APPLICATION_JSON)
    public String preview(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeImportParam importParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeImportParam, Map<String, Object>>(user).run(getSalarySobRangeWrapper(user)::preview, importParam);
    }

    /**
     * @description 薪资账套人员范围导入
     * @return String
     * @author Harryxzy
     * @date 2023/1/9 13:32
     */
    @POST
    @Path("/range/importData")
    @Produces(MediaType.APPLICATION_JSON)
    public String importData(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobRangeImportParam importParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobRangeImportParam, Map<String, Object>>(user).run(getSalarySobRangeWrapper(user)::importData, importParam);
    }

    /**********************************薪资账套的人员范围 end*********************************/

    /**********************************薪资账套的薪资项目 start*********************************/

    /**
     * 薪资账套可选薪资项目
     */
    @POST
    @Path("/item/listSalaryItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSalaryItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryItemSearchParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryItemSearchParam, PageInfo<SalaryItemSobListDTO> >(user).run(getSalarySobItemWrapper(user)::listPage4SalaryItem, queryParam);
    }


    /**
     * 薪资账套可选薪资项目分类
     */
    @GET
    @Path("/item/group/getForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobItemGroupForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String idStr = request.getParameter("id");
        Long id = null;
        if (StringUtils.isNotBlank(idStr)) {
            id = Long.valueOf(idStr);
        }
        return new ResponseResult<Long, SalarySobItemGroupPO>(user).run(getSalarySobItemWrapper(user)::getGroupForm, id);
    }

    /**
     * 薪资账套薪资项目详情
     */
    @GET
    @Path("/item/getForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobItemForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String salarySobIdStr = request.getParameter("salarySobId");
        Long salarySobId = null;
        if (StringUtils.isNotBlank(salarySobIdStr)) {
            salarySobId = Long.valueOf(salarySobIdStr);
        }
        return new ResponseResult<Long, SalarySobItemAggregateDTO>(user).run(getSalarySobItemWrapper(user)::getForm, salarySobId);
    }

    /**
     * 人员信息字段列表
     */
    @GET
    @Path("/empField/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String empFieldList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String, Collection<Map<String, String>>>(user).run(getSalarySobItemWrapper(user)::empFieldList);
    }

    /**
     * 保存薪资账套薪资项目
     */
    @POST
    @Path("/item/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalarySobItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobItemSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobItemSaveParam, Map<String, Object>>(user).run(getSalarySobItemWrapper(user)::save, saveParam);
    }

    /**
     * 薪资账套-薪资项目的详情
     */
    @POST
    @Path("/item/getSalaryItemForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalaryItemForm(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobItemPO param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobItemPO, SalarySobItemFormDTO>(user).run(getSalarySobItemWrapper(user)::getSalaryItemForm, param);
    }



    /**********************************薪资账套的薪资项目 end*********************************/



    /**********************************薪资账套的回算项目 start*********************************/
    
    /**
     * @description 薪资账套回算项目列表
     * @return String
     * @author Harryxzy
     * @date 2022/11/16 14:01
     */
    @GET
    @Path("/backitem/getAggregate")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobBackItemAggregate(@Context HttpServletRequest request, @Context HttpServletResponse response,@QueryParam(value = "salarySobId") Long salarySobId) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long,SalarySobBackItemAggregateDTO>(user).run(getSalarySobBackItemWrapper(user)::getAggregate, salarySobId);
    }

    /**
     * @description 薪资账套回算项目详情(编辑前获取)
     * @return null
     * @author Harryxzy
     * @date 2022/11/16 14:02
     */
    @GET
    @Path("/backitem/getForm")
    @ApiOperation("薪资账套回算项目详情")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalarySobBackItemForm(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value ="id") Long id) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long,SalarySobBackItemFormDTO>(user).run(getSalarySobBackItemWrapper(user)::getForm, id);
    }

    /**
     * @description 保存薪资账套回算项目
     * @return String
     * @author Harryxzy
     * @date 2022/11/16 15:05
     */
    @POST
    @Path("/backitem/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalarySobBackItem(@Context HttpServletRequest request, @Context HttpServletResponse response,@RequestBody SalarySobBackItemSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobBackItemSaveParam,List<SalarySobBackItemDTO>>(user).run(getSalarySobBackItemWrapper(user)::save, saveParam);
    }

    /**********************************薪资账套的回算项目 end*********************************/



    /**********************************调薪计薪规则 start*********************************/


    /**
     * 调薪计薪规则列表
     */
    @POST
    @Path("/adjustmentrule/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listAdjustmentRule(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobAdjustRuleQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobAdjustRuleQueryParam, List<SalarySobAdjustRuleListDTO>>(user).run(getSalarySobAdjustRuleWrapper(user)::list, queryParam);
    }


    /**
     * 调薪计薪规则保存
     */
    @POST
    @Path("/adjustmentrule/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveAdjustmentRule(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobAdjustRuleSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobAdjustRuleSaveParam, String>(user).run(getSalarySobAdjustRuleWrapper(user)::save, saveParam);
    }

    /**
     * 调薪计薪规则可选的薪资项目列表
     */
    @POST
    @Path("/adjustmentrule/listSalarySobItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSalarySobItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobAdjustRuleItemQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobAdjustRuleItemQueryParam, List<SalaryItemBaseDTO>>(user).run(getSalarySobAdjustRuleWrapper(user)::list4SalarySobItem, queryParam);
    }

    /**********************************调薪计薪规则 end*********************************/

    /**********************************校验规则 start*********************************/


    /**
     * 薪资账套校验规则列表
     */
    @POST
    @Path("/checkrule/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String listSalarySobCheckRule(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobCheckRuleQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalarySobCheckRuleQueryParam, PageInfo<SalarySobCheckRuleListDTO>>(user).run(getSalarySobCheckRuleWrapper(user)::listPage, queryParam);
    }

    /**
     * 薪资账套校验规则表单
     */
    @GET
    @Path("/checkrule/getForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String idStr = request.getParameter("id");
        Long id = null;
        if (StringUtils.isNotBlank(idStr)) {
            id = Long.valueOf(idStr);
        }
        return new ResponseResult<Long, SalarySobCheckRuleFormDTO>(user).run(getSalarySobCheckRuleWrapper(user)::getForm, id);
    }

    /**
     * 保存薪资账套校验规则
     */
    @POST
    @Path("/checkrule/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalarySobCheckRule(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalarySobCheckRuleSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        if (saveParam.getId() == null || saveParam.getId() <= 0) {
            return new ResponseResult<SalarySobCheckRuleSaveParam, String>(user).run(getSalarySobCheckRuleWrapper(user)::save, saveParam);
        } else {
            return new ResponseResult<SalarySobCheckRuleSaveParam, String>(user).run(getSalarySobCheckRuleWrapper(user)::update, saveParam);
        }

    }

    /**
     * 编辑薪资账套校验规则公式
     */
    @POST
    @Path("/checkrule/formula/update")
    @Produces(MediaType.APPLICATION_JSON)
    public String updateSalarySobCheckRuleFormula(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody UpdateCheckRuleFormulaParam updateParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<UpdateCheckRuleFormulaParam, String>(user).run(getSalarySobCheckRuleWrapper(user)::updateFormulaId, updateParam);
    }

    /**
     * 删除薪资账套校验规则
     */
    @POST
    @Path("/checkrule/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalarySobCheckRule(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        if (CollectionUtils.isEmpty(ids)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(84026, "参数错误"));
        }
        return new ResponseResult<Collection<Long>, String>(user).run(getSalarySobCheckRuleWrapper(user)::delete, ids);
    }


    /**********************************校验规则 end*********************************/

}
