package com.jeeplus.test.reimbursementsys.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jeeplus.aop.demo.annotation.DemoMode;
import com.jeeplus.aop.logging.annotation.ApiLog;
import com.jeeplus.common.beanvalidator.BeanValidators;
import com.jeeplus.core.excel.ExcelOptions;
import com.jeeplus.core.excel.ExportMode;
import com.jeeplus.core.excel.utils.EasyPoiUtil;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.DictUtils;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.test.reimbursementProject.domain.dto.ProjectReimbursementDTO;
import com.jeeplus.test.reimbursementsys.domain.dto.*;
import com.jeeplus.test.reimbursementsys.service.ReimbursementUserService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 徐滕
 * @version 1.0.0
 * @ClassName ReimbursementUserController.java
 * @Description TODO 报销人员年份金额信息
 * @createTime 2022年05月16日 10:35:21
 */
@RestController
@RequestMapping("/reimbursementUser")
public class ReimbursementUserController {

    @Autowired
    private ReimbursementUserService service;

    /**
     * 根据id报销人员信息
     * @param id
     * @return
     */
    @ApiLog("根据id报销人员信息")
    @PreAuthorize("hasAnyAuthority('reimbursementUser:view','reimbursementUser:add','reimbursementUser:edit')")
    @GetMapping("queryById")
    public ResponseEntity queryById(@RequestParam String id) {
        ReimbursementUserDTO reimbursementDTO = service.queryById (id);
        return ResponseEntity.ok (reimbursementDTO);
    }

    /**
     * 根据id报销人员信息
     * @return
     */
    @ApiLog("查询字典中日报销额度和年度假日天数")
    @PreAuthorize("hasAnyAuthority('reimbursementUser:add')")
    @GetMapping("getReimbursementQuotaDay")
    public ResponseEntity getReimbursementQuotaDay() {
        ReimbursementUserDTO reimbursementDTO = new ReimbursementUserDTO();
        //获取日报销额度
        String reimbursementQuotaDay = DictUtils.getDictLabel("1", "reimbursement_quota_day", null);
        //获取当年度的总天数
        int yearDay = LocalDate.now().lengthOfYear();
        //获取年度休假天数
        String holidayDay = DictUtils.getDictLabel("1", "reimbursement_holiday_day", null);
        Integer reimbursementAllDay = yearDay;
        if(StringUtils.isNotBlank(holidayDay)){
            int i = Integer.parseInt(holidayDay);
            reimbursementAllDay = yearDay - Integer.parseInt(holidayDay);
        }
        reimbursementDTO.setReimbursementQuotaDay(reimbursementQuotaDay);
        reimbursementDTO.setReimbursementAllDay(reimbursementAllDay);
        return ResponseEntity.ok (reimbursementDTO);
    }


    /**
     * 查询报销信息
     * @return
     */
    @ApiLog("查询报销人员信息列表")
    @GetMapping("findList")
    public ResponseEntity findList(ReimbursementUserDTO reimbursementUser, Page<ReimbursementUserDTO> page) {
        IPage<ReimbursementUserDTO> list = service.findList(page,reimbursementUser);
        return ResponseEntity.ok(list);
    }

    /**
     * 保存业务报销编码
     * @return
     */
    @ApiLog("保存报销人员信息")
    @PostMapping("save")
    public ResponseEntity save(@RequestBody ReimbursementUserDTO reimbursementUser) {
        Map<String, Object> result = service.save(reimbursementUser);
        Boolean success = (Boolean) result.get("success");
        if(success){
            return ResponseEntity.ok(result.get("message"));
        }
        return ResponseEntity.badRequest ().body (result.get("message"));
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @DemoMode
    @ApiLog("批量删除")
    @PreAuthorize("hasAuthority('reimbursementUser:del')")
    @DeleteMapping("delete")
    public ResponseEntity delete(String ids) {
        String idArray[] =ids.split(",");
        Map<String, Object> result = service.delete(Lists.newArrayList(idArray));
        if(!(Boolean) result.get("success")){
            return ResponseEntity.badRequest ().body (result.get("message"));
        }
        return ResponseEntity.ok (result.get("message"));
    }


    /**
     * 初始化部门人员报销数据信息（当年）
     * @return
     */
    @ApiLog("初始化部门人员报销数据信息（当年）")
    @PreAuthorize("hasAnyAuthority('reimbursementUser:add')")
    @PostMapping("initialize")
    public ResponseEntity initialize(String officeType) {
        Map<String, Object> result = service.initialize("中审众环",officeType);
        Boolean success = (Boolean) result.get("success");
        if(success){
            return ResponseEntity.ok(result.get("message"));
        }
        return ResponseEntity.badRequest ().body (result.get("message"));
    }



    /**
     * 查询报销信息
     * @return
     */
    @ApiLog("查询业务报销信息列表")
    @PreAuthorize("hasAuthority('reimbursementBusiness:view')")
    @GetMapping("findListByUserId")
    public ResponseEntity findListByUserId(ReimbursementBusinessReturnDTO reimbursementBusinessReturnDTO) {
        if(StringUtils.isBlank(reimbursementBusinessReturnDTO.getUserId())){
            return ResponseEntity.badRequest ().body ("请先选择报销人员信息");
        }

        //根据id查询人员填报的报销信息
        ReimbursementUserDTO reimbursementUserDTO = service.queryById(reimbursementBusinessReturnDTO.getUserId());
        if(null == reimbursementUserDTO){
            return ResponseEntity.badRequest ().body ("报销人员信息无效，请重新选择");
        }
        ReimbursementBusinessReturnDTO info = service.findListByUserId(reimbursementUserDTO,reimbursementBusinessReturnDTO);
        info.setUserId(reimbursementBusinessReturnDTO.getUserId());
        return ResponseEntity.ok(info);
    }
    /**
     * 下载导入用户数据模板
     *
     * @param response
     * @return
     */
    @PreAuthorize ("hasAnyAuthority('reimbursementUser:import')")
    @GetMapping("import/template")
    @ApiOperation(value = "下载模板")
    public void importFileTemplate(HttpServletResponse response) {
        String fileName = "报销人员数据导入模板.xlsx";
        List<ReimbursementUserImportDTO> list = Lists.newArrayList();
        EasyPoiUtil.exportExcel ( list, "报销人员数据",  "报销人员数据", ReimbursementUserImportDTO.class, fileName, response );
    }

    /**
     * 导入用户数据
     *
     * @return
     */
    @DemoMode
    @PreAuthorize("hasAnyAuthority('reimbursementUser:import')")
    @PostMapping("import")
    @ApiOperation(value = "导入员工报销信息excel")
    public ResponseEntity importFile(MultipartFile file) {
        try {
            int successNum = 0;
            int failureNum = 0;
            StringBuilder failureMsg = new StringBuilder ( );
            List <ReimbursementUserDTO> list = EasyPoiUtil.importExcel ( file, 1, 1, ReimbursementUserDTO.class );
            List<ReimbursementUserDTO> saveList = Lists.newArrayList();
            Map<String, Object> resultMap = new HashMap<>();
            for (ReimbursementUserDTO user : list) {
                try {
                    //根据部门和人员名称查询人员信息
                    List<UserDTO> userByNameAndOfficeName = service.getUserByNameAndOfficeName(user);
                    if(userByNameAndOfficeName.size()>1){
                        failureMsg.append ( "。 " + user.getOfficeName() + " 部门下的员工 " + user.getUserName() + " 存在多个，无法进行导入;" );
                        failureNum++;
                    }else if(userByNameAndOfficeName.size() == 0){
                        failureMsg.append ( "。 " + user.getOfficeName() + " 部门下的员工 " + user.getUserName() + " 不存在，无法进行导入;" );
                        failureNum++;
                    }else {
                        user.setUserId(userByNameAndOfficeName.get(0).getId());
                        user.setUser(userByNameAndOfficeName.get(0));
                        user.setKeyFlag(user.getYear() + user.getUserId());
                        saveList.add(user);
                        successNum ++;
                    }
                } catch (ConstraintViolationException ex) {
                    failureMsg.append ( "。 " + user.getOfficeName() + " 部门下的员工 " + user.getUserName() + " 导入失败：" );
                    List <String> messageList = BeanValidators.extractPropertyAndMessageAsList ( ex, ": " );
                    for (String message : messageList) {
                        failureMsg.append ( message + "; " );
                        failureNum++;
                    }
                } catch (Exception ex) {
                    failureNum++;
                    failureMsg.append ( "。 " + user.getOfficeName() + " 部门下的员工 " + user.getUserName() + " 导入失败：" + ex.getMessage ( ) );
                }
            }

            if ( failureNum > 0 ) {
                failureMsg.insert ( 0, "，失败 " + failureNum + " 条员工报销数据，导入信息如下：" );
            }

            if(saveList.size()>0){
                resultMap = service.saveList(saveList);

                Boolean success = (Boolean) resultMap.get("success");
                if(!success){
                    return ResponseEntity.badRequest().body ( resultMap.get("message"));
                }
                Object saveCount = resultMap.get("saveCount");
                Object message = resultMap.get("message");
                return ResponseEntity.ok ( "已成功导入 " + saveCount + " 条员工报销数据" + failureMsg+message );
            }
            return ResponseEntity.ok ( "已成功导入 " + successNum + " 条员工报销数据" + failureMsg );
        } catch (Exception e) {
            return ResponseEntity.badRequest().body ( "导入员工报销数据失败！失败信息：" + e.getMessage ( ) );
        }
    }


    /**
     * 导出中审众环人员信息数据
     * @param reimbursementUserDTO
     * @param page
     * @param response
     * @throws Exception
     */
    @ApiLog("导出中审众环人员信息数据")
    @GetMapping("export")
    @ApiOperation(value = "导出中审众环人员信息数据excel")
    public void exportFile(ReimbursementUserDTO reimbursementUserDTO, Page <ReimbursementUserDTO> page, ExcelOptions options, HttpServletResponse response) {
        String fileName = options.getFilename ( );

        List <ReimbursementUserDTO> result;
        if ( ExportMode.current.equals ( options.getMode ( ) ) ) {
            result = service.findList ( page, reimbursementUserDTO ).getRecords();
        } else if ( ExportMode.selected.equals ( options.getMode ( ) ) ) {
            result = service.findList ( page, reimbursementUserDTO ).getRecords().stream ( ).filter ( reimbursement ->
                    options.getSelectIds ( ).contains ( reimbursement.getId ( ) )
            ).collect ( Collectors.toList ( ) );
        } else {
            page.setSize ( -1 );
            page.setCurrent ( 0 );
            result = service.findList ( page, reimbursementUserDTO ).getRecords();
        }
        EasyPoiUtil.exportExcel ( result, "中审众环人员信息数据",  options.getSheetName ( ), ReimbursementUserDTO.class, fileName, response );
    }


    /**
     * 导出中审众环人员信息数据
     * @param reimbursementBusinessReturnDTO
     * @param response
     * @throws Exception
     */
    @ApiLog("人员报销详情导出")
    @GetMapping("exportUserBusinessExcel")
    @ApiOperation(value = "人员报销详情导出Excel")
    public void exportUserBusinessExcel(ReimbursementBusinessReturnDTO reimbursementBusinessReturnDTO, ExcelOptions options, HttpServletResponse response) {
        String fileName = options.getFilename ( );


        //根据id查询人员填报的报销信息
        ReimbursementUserDTO reimbursementUserDTO = service.queryById(reimbursementBusinessReturnDTO.getUserId());

        ReimbursementBusinessReturnDTO info = service.findListByUserId(reimbursementUserDTO,reimbursementBusinessReturnDTO);
        for (ReimbursementBusinessDTO businessInfo : info.getList()) {
            switch (businessInfo.getReimbursementAddress()){
                case "1":
                    businessInfo.setReimbursementAddress("总所报销");
                    break;
                case "0":
                    businessInfo.setReimbursementAddress("分所报销");
                    break;
                default:
                    businessInfo.setReimbursementAddress("——");
                    break;

            }
        }

        EasyPoiUtil.exportExcel ( info.getList(), "人员报销详情",  options.getSheetName ( ), ReimbursementBusinessDTO.class, fileName, response );
    }

}
