package com.engine.salary.web;

import com.engine.common.util.ParamUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldFormDTO;
import com.engine.salary.entity.datacollection.dto.AttendQuoteFieldSettingListDTO;
import com.engine.salary.entity.datacollection.dto.AttendQuoteListDTO;
import com.engine.salary.entity.datacollection.param.*;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.util.ResponseResult;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.wrapper.AttendQuoteDataWrapper;
import com.engine.salary.wrapper.AttendQuoteFieldSettingWrapper;
import com.engine.salary.wrapper.AttendQuoteFieldWrapper;
import com.engine.salary.wrapper.AttendQuoteWrapper;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.extern.slf4j.Slf4j;
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.time.YearMonth;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Slf4j
public class AttendQuoteController {

    private AttendQuoteWrapper getAttendQuoteWrapper(User user) {
        return ServiceUtil.getService(AttendQuoteWrapper.class, user);
    }

    private AttendQuoteDataWrapper getAttendQuoteDataWrapper(User user) {
        return ServiceUtil.getService(AttendQuoteDataWrapper.class, user);
    }

    private AttendQuoteFieldWrapper getAttendQuoteFieldWrapper(User user) {
        return ServiceUtil.getService(AttendQuoteFieldWrapper.class, user);
    }

    private AttendQuoteFieldSettingWrapper getAttendQuoteFieldSettingWrapper(User user) {
        return ServiceUtil.getService(AttendQuoteFieldSettingWrapper.class, user);
    }

    /**
     * 考勤数据列表
     */
    @POST
    @Path("/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String list(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteQueryParam, PageInfo<AttendQuoteListDTO>>(user).run(getAttendQuoteWrapper(user)::list, queryParam);
    }


//    @GET
//    @Path("/getSyncForm")
//    @Produces(MediaType.APPLICATION_JSON)
//    public String getSyncForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
//        User user = HrmUserVarify.getUser(request, response);
//        return new ResponseResult<Long, Map<String, Object>>(user).run(getService(user)::getSyncForm, (long)user.getUID());
//    }


    /**
     * 检查是否可以操作
     * 说明：已经核算过的不能再操作
     *
     * @param checkOperationParam
     * @return
     */
    @POST
    @Path("/checkOperation")
    @Produces(MediaType.APPLICATION_JSON)
    public String checkOperation(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteCheckOperationParam checkOperationParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteCheckOperationParam, Boolean>(user).run(getAttendQuoteWrapper(user)::checkOperation, checkOperationParam);
    }

    /**
     * 获取薪资周期和考勤周期
     *
     * @return
     */
    @GET
    @Path("/getSalaryCycleAndAttendCycle")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalaryCycleAndAttendCycle(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salaryYearMonthStr") String salaryYearMonthStr, @QueryParam(value = "salarySobId") Long salarySobId) {
        User user = HrmUserVarify.getUser(request, response);

        QuerySalaryCycleAndAttendCycleParam param = QuerySalaryCycleAndAttendCycleParam.builder().salarySobId(salarySobId).salaryYearMonth(SalaryDateUtil.String2YearMonth(salaryYearMonthStr)).build();
        return new ResponseResult<QuerySalaryCycleAndAttendCycleParam, Map<String, Object>>(user).run(getAttendQuoteWrapper(user)::getSalaryCycleAndAttendCycle, param);
    }


    /**
     * 同步引用考勤数据
     *
     * @return
     */
    @POST
    @Path("/syncAttendQuoteData")
    @Produces(MediaType.APPLICATION_JSON)
    public String syncAttendQuoteData(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataSyncParam syncParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataSyncParam, String>(user).run(getAttendQuoteDataWrapper(user)::syncAttendQuoteData, syncParam);
    }


    /**
     * 下载导入模板
     */
    @GET
    @Path("/downloadTemplate")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);
            String salaryYearMonth = request.getParameter("salaryYearMonth");
            String salarySobId = request.getParameter("salarySobId");
            AttendQuoteDataExportTemplateParam param = AttendQuoteDataExportTemplateParam.builder()
                    .salarySobId(Long.valueOf(salarySobId))
                    .salaryYearMonth(YearMonth.parse(salaryYearMonth))
                    .build();
            if (param.getSalaryYearMonth() == null || param.getSalarySobId() == null) {
                throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100250, "薪资所属月和薪资账套id不能为空"));
            }
            XSSFWorkbook workbook = getAttendQuoteDataWrapper(user).downloadTemplate(param);
            String fileName = "考勤引用导入模板" + LocalDate.now();
            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) {
            log.error("考勤引用导入模板导出异常", e);
            throw e;
        }

    }

    /**
     * 预览
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/preview")
    @Produces(MediaType.APPLICATION_JSON)
    public String preview(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataImportParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataImportParam, Map<String, Object>>(user).run(getAttendQuoteDataWrapper(user)::preview, queryParam);
    }


    /**
     * 导入考勤数据
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/importAttendQuoteData")
    @Produces(MediaType.APPLICATION_JSON)
    public String importAttendQuoteData(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataImportParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataImportParam, Map<String, Object>>(user).run(getAttendQuoteDataWrapper(user)::importAttendQuoteData, queryParam);
    }


    /**
     * 查看考勤数据
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/view")
    @Produces(MediaType.APPLICATION_JSON)
    public String view(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataQueryParam, Map<String, Object>>(user).run(getAttendQuoteDataWrapper(user)::view, queryParam);
    }


    @POST
    @Path("/getData")
    @Produces(MediaType.APPLICATION_JSON)
    public String getData(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataEditParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataEditParam, Map<String, Object>>(user).run(getAttendQuoteDataWrapper(user)::getData, queryParam);
    }

    /**
     * 编辑考勤数据
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/editData")
    @Produces(MediaType.APPLICATION_JSON)
    public String editData(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteDataEditParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteDataEditParam, Map<String, Object>>(user).run(getAttendQuoteDataWrapper(user)::editData, queryParam);
    }

    @GET
    @Path("/selectSalarySobList")
    @Produces(MediaType.APPLICATION_JSON)
    public String selectSalarySobList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, List<Map<String, Object>>>(user).run(getAttendQuoteWrapper(user)::selectSalarySobList);
    }


    /**
     * 删除考勤数据
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/delete")
    @Produces(MediaType.APPLICATION_JSON)
    public String delete(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getAttendQuoteWrapper(user)::delete, ids);
    }

    /**
     * 导出考勤数据
     *
     * @return
     */
    @GET
    @Path("/export")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response export(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);
            String attendQuoteId = request.getParameter("attendQuoteId");
            AttendQuoteDataQueryParam param = AttendQuoteDataQueryParam.builder().attendQuoteId(Long.valueOf(attendQuoteId)).build();
            XSSFWorkbook workbook = getAttendQuoteDataWrapper(user).export(param);
            String fileName = "考勤导出" + LocalDate.now();
            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) {
            log.error("考勤导出异常", e);
            throw e;
        }


    }


    /**
     * 考勤字段管理列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/fieldList")
    @Produces(MediaType.APPLICATION_JSON)
    public String fieldList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        Map<String, Object> map = ParamUtil.request2Map(request);
        map.put("queryParam", queryParam);
        return new ResponseResult<AttendQuoteFieldQueryParam, Map<String, Object>>(user).run(getAttendQuoteFieldWrapper(user)::list, queryParam);
    }

    /**
     * 同步考勤模块字段
     *
     * @return
     */
    @POST
    @Path("/syncAttendFields")
    @Produces(MediaType.APPLICATION_JSON)
    public String syncAttendFields(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, String>(user).run(getAttendQuoteFieldWrapper(user)::syncAttendFields);
    }

    /**
     * 获取考勤字段表单
     *
     * @return
     */
    @GET
    @Path("/getFieldForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getFieldForm(@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.parseLong(request.getParameter("id"));
        }
        return new ResponseResult<Long, AttendQuoteFieldFormDTO>(user).run(getAttendQuoteFieldWrapper(user)::getFrom, id);
    }


    /**
     * 新建考勤字段
     */
    @POST
    @Path("/saveField")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveField(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSaveParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSaveParam, String>(user).run(getAttendQuoteFieldWrapper(user)::save, param);
    }



    /**
     * 修改考勤字段
     */
    @POST
    @Path("/updateField")
    @Produces(MediaType.APPLICATION_JSON)
    public String updateField(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSaveParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSaveParam, String>(user).run(getAttendQuoteFieldWrapper(user)::update, param);
    }


    /**
     * 删除考勤字段
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/deleteField")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteField(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getAttendQuoteFieldWrapper(user)::delete, ids);
    }


    /**
     * 启用/停用自定义字段
     */
    @POST
    @Path("/updateEnableStatus")
    @Produces(MediaType.APPLICATION_JSON)
    public String updateEnableStatus(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSaveParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSaveParam, String>(user).run(getAttendQuoteFieldWrapper(user)::updateEnableStatus, param);
    }


    /**
     * 数据采集-考勤引用字段设置列表
     */
    @POST
    @Path("/fieldSetting/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String fieldSettingList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSettingQueryParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSettingQueryParam, List<AttendQuoteFieldSettingListDTO>>(user).run(getAttendQuoteFieldSettingWrapper(user)::list, param);
    }

    /**
     * 数据采集-考勤引用字段设置保存
     *
     * @return
     */
    @POST
    @Path("/fieldSetting/save")
    @Produces(MediaType.APPLICATION_JSON)
    public String fieldSettingSave(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSettingSaveParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSettingSaveParam, String>(user).run(getAttendQuoteFieldSettingWrapper(user)::save, param);
    }

    /**
     * 数据采集-考勤引用字段设置-恢复默认设置
     */
    @POST
    @Path("/fieldSetting/recoverAsDefault")
    @Produces(MediaType.APPLICATION_JSON)
    public String fieldSettingRecoverAsDefault(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSettingRecoverParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSettingRecoverParam, List<AttendQuoteFieldSettingListDTO>>(user).run(getAttendQuoteFieldSettingWrapper(user)::recoverAsDefault, param);
    }

    /**
     * 数据采集-考勤引用字段设置-设为默认设置
     *
     * @return
     */
    @POST
    @Path("/fieldSetting/saveAsDefault")
    @Produces(MediaType.APPLICATION_JSON)
    public String fieldSettingSaveAsDefault(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody AttendQuoteFieldSettingSaveParam param) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<AttendQuoteFieldSettingSaveParam, String>(user).run(getAttendQuoteFieldSettingWrapper(user)::saveAsDefault, param);
    }

}
