package com.jpsoft.shinestar.modules.business.controller;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.util.StringUtil;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.service.CompanyInfoService;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.business.entity.YearRequestForLeaveInfo;
import com.jpsoft.shinestar.modules.business.service.YearRequestForLeaveInfoService;
import com.jpsoft.shinestar.modules.common.utils.IdCardUtils;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.sys.entity.DataDictionary;
import com.jpsoft.shinestar.modules.sys.entity.User;
import com.jpsoft.shinestar.modules.sys.service.UserService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.ResultMap;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/business/yearRequestForLeaveInfo")
public class YearRequestForLeaveInfoController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private YearRequestForLeaveInfoService yearRequestForLeaveInfoService;

    @Autowired
    private UserService userService;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private OSSConfig ossConfig;


    @ApiOperation(value = "创建空记录")
    @GetMapping("create")
    public MessageResult<YearRequestForLeaveInfo> create() {
        MessageResult<YearRequestForLeaveInfo> msgResult = new MessageResult<>();

        YearRequestForLeaveInfo yearRequestForLeaveInfo = new YearRequestForLeaveInfo();

        msgResult.setData(yearRequestForLeaveInfo);
        msgResult.setResult(true);

        return msgResult;
    }

    @ApiOperation(value = "添加信息")
    @PostMapping("add")
    public MessageResult<YearRequestForLeaveInfo> add(@RequestBody YearRequestForLeaveInfo yearRequestForLeaveInfo, @RequestAttribute String subject) {
        MessageResult<YearRequestForLeaveInfo> msgResult = new MessageResult<>();

        try {
            yearRequestForLeaveInfo.setId(UUID.randomUUID().toString());
            yearRequestForLeaveInfo.setDelFlag(false);
            yearRequestForLeaveInfo.setCreateBy(subject);
            yearRequestForLeaveInfo.setCreateTime(new Date());

            int affectCount = yearRequestForLeaveInfoService.insert(yearRequestForLeaveInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(yearRequestForLeaveInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库添加失败");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "获取信息")
    @GetMapping("edit/{id}")
    public MessageResult<YearRequestForLeaveInfo> edit(@PathVariable("id") String id) {
        MessageResult<YearRequestForLeaveInfo> msgResult = new MessageResult<>();

        try {
            YearRequestForLeaveInfo yearRequestForLeaveInfo = yearRequestForLeaveInfoService.get(id);

            if (yearRequestForLeaveInfo != null) {
                msgResult.setResult(true);
                msgResult.setData(yearRequestForLeaveInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库不存在该记录!");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "更新用户")
    @PostMapping("update")
    public MessageResult<YearRequestForLeaveInfo> update(@RequestBody YearRequestForLeaveInfo yearRequestForLeaveInfo, @RequestAttribute String subject) {
        MessageResult<YearRequestForLeaveInfo> msgResult = new MessageResult<>();

        try {
            yearRequestForLeaveInfo.setUpdateBy(subject);
            yearRequestForLeaveInfo.setUpdateTime(new Date());

            int affectCount = yearRequestForLeaveInfoService.update(yearRequestForLeaveInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(yearRequestForLeaveInfo);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库更新失败");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "删除用户")
    @PostMapping("delete/{id}")
    public MessageResult<YearRequestForLeaveInfo> delete(@PathVariable("id") String id, @RequestAttribute String subject) {
        MessageResult<YearRequestForLeaveInfo> msgResult = new MessageResult<>();

        try {

            YearRequestForLeaveInfo yearRequestForLeaveInfo = yearRequestForLeaveInfoService.get(id);
            yearRequestForLeaveInfo.setDelFlag(true);
            yearRequestForLeaveInfo.setUpdateBy(subject);
            yearRequestForLeaveInfo.setUpdateTime(new Date());

            int affectCount = yearRequestForLeaveInfoService.update(yearRequestForLeaveInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("数据库删除失败");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }


    @ApiOperation(value = "批量删除")
    @PostMapping("batchDelete")
    public MessageResult<Integer> batchDelete(@RequestBody List<String> idList, @RequestAttribute String subject) {
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            int affectCount = 0;

            for (String id : idList) {
                YearRequestForLeaveInfo yearRequestForLeaveInfo = yearRequestForLeaveInfoService.get(id);
                yearRequestForLeaveInfo.setDelFlag(true);
                yearRequestForLeaveInfo.setUpdateBy(subject);
                yearRequestForLeaveInfo.setUpdateTime(new Date());

                affectCount += yearRequestForLeaveInfoService.update(yearRequestForLeaveInfo);
            }

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(affectCount);
            } else {
                msgResult.setResult(false);
                msgResult.setMessage("删除失败");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "请假记录分页")
    @PostMapping(value = "pageList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "所属班级", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "status", value = "审批状态", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "requestStartTime", value = "请假开始日期", paramType = "form"),
            @ApiImplicitParam(name = "requestEndTime", value = "请假结束日期", paramType = "form"),
            @ApiImplicitParam(name = "auditStartTime", value = "审核开始日期", paramType = "form"),
            @ApiImplicitParam(name = "auditEndTime", value = "审核结束日期", paramType = "form"),
            @ApiImplicitParam(name = "exportXls", value = "导出报表", paramType = "form")
    })
    public MessageResult<Object> pageList(
            String name,
            String classId,
            Integer status,
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "hqCompanyId", defaultValue = "") String hqCompanyId,
            @RequestParam(value = "hqSubordinate", defaultValue = "false") Boolean hqSubordinate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date requestStartTime,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date requestEndTime,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date auditStartTime,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date auditEndTime,
            @RequestParam(value = "pageIndex", defaultValue = "1") int pageIndex,
            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
            @RequestParam(value = "exportFlag", defaultValue = "false") Boolean exportFlag,
            @RequestAttribute String subject) {
        MessageResult<Object> messageResult = new MessageResult<>();

        try {
            //当前用户ID
            User user = userService.get(subject);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("create_time", "desc"));

            Map<String, Object> searchParams = new HashMap<>();

            if (!userService.hasRole(user.getId(), "SYSADMIN")) {
                //非系统管理员
                CompanyInfo companyInfo = companyInfoService.get(user.getCompanyId());
                searchParams.put("companyCode", companyInfo.getCode() + "%");
            }

            if (StringUtil.isNotEmpty(name)) {
                searchParams.put("name", "%" + name + "%");
            }

            if (StringUtil.isNotEmpty(classId)) {
                searchParams.put("classId", classId);
            }

            if (status != null) {
                searchParams.put("status", status);
            }

            if (requestStartTime != null) {
                searchParams.put("requestStartTime", requestStartTime);
            }

            if (requestEndTime != null) {
                searchParams.put("requestEndTime", new DateTime(requestEndTime).plusDays(1).plusSeconds(-1).toDate());
            }

            if (auditStartTime != null) {
                Date t = DateUtil.beginOfDay(auditStartTime);
                searchParams.put("auditStartTime", t);
            }

            if (auditEndTime != null) {
                Date t = DateUtil.endOfDay(auditEndTime);
                searchParams.put("auditEndTime", t);
            }

            if (com.jpsoft.shinestar.modules.common.utils.StringUtils.isNotEmpty(companyId)) {
                CompanyInfo companyInfo = companyInfoService.get(companyId);

                if (subordinate) {
                    searchParams.put("companyCode", companyInfo.getCode() + "%");
                } else {
                    searchParams.put("companyCode", companyInfo.getCode());
                }
            }

            if (com.jpsoft.shinestar.modules.common.utils.StringUtils.isNotEmpty(hqCompanyId)) {
                if ("hq1".equals(hqCompanyId)) {
                    //后勤1
                    searchParams.put("hqStatus", "1");
                } else if ("hq2".equals(hqCompanyId)) {
                    //后勤2
                    searchParams.put("hqStatus", "2");
                } else {
                    CompanyInfo companyInfo = companyInfoService.get(hqCompanyId);

                    if (hqSubordinate) {
                        searchParams.put("hqCompanyCode", companyInfo.getCode() + "%");
                    } else {
                        searchParams.put("hqCompanyCode", companyInfo.getCode());
                    }
                }

                searchParams.put("hqPerson", true);
            }

            searchParams.put("pageIndex", pageIndex);
            searchParams.put("pageSize", pageSize);

            Page<YearRequestForLeaveInfo> page = yearRequestForLeaveInfoService.pageSearch(searchParams, pageIndex, pageSize, true, sortList);

            List<Map> mapList = new ArrayList<>();

            for (YearRequestForLeaveInfo target : page) {
                Map<String, Object> map = new HashMap<>();

                map.put("id", target.getId());

                map.put("faceImageUrl", target.getFaceImageUrl());
                map.put("name", target.getStudentName());

                map.put("statusN", target.getStatusN());

                //身份证号
                map.put("idCard", IdCardUtils.decrypt(target.getIdCard()));

                //班级
                map.put("className", target.getClassName());

                map.put("approvedName", target.getApprovedName());


                //请假时间
                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");

                String startTimeQuantum = "上午";

                if ("1".equals(target.getStartTimeQuantum())) {
                    startTimeQuantum = "下午";
                }

                String endTimeQuantum = "上午";

                if ("1".equals(target.getEndTimeQuantum())) {
                    endTimeQuantum = "下午";
                }

                map.put("startTime", sdf1.format(target.getStartTime()));
                map.put("days", target.getDays());

                int days = differentDaysByMillisecond(target.getStartTime(), target.getEndTime());

                if (days < 1) {
                    if ("0".equals(target.getStartTimeQuantum()) && "1".equals(target.getEndTimeQuantum())) {
                        //请假一天
                        map.put("time", String.format("%s年%s", new DateTime(target.getStartTime()).getYear(),
                                sdf2.format(target.getStartTime())
                        ));
                    } else {
                        //请假半天
                        map.put("time", String.format("%s年%s", new DateTime(target.getStartTime()).getYear(),
                                sdf2.format(target.getStartTime()) + startTimeQuantum
                        ));
                    }

                } else {
                    map.put("time", String.format("%s年%s至%s", new DateTime(target.getStartTime()).getYear(),
                            sdf2.format(target.getStartTime()) + startTimeQuantum,
                            sdf2.format(target.getEndTime()) + endTimeQuantum
                    ));
                }

                //请假理由
                map.put("reason", target.getReason());

                //上传图片
                map.put("imageUrl", target.getImageUrl());

                //申请时间
                map.put("createTime", sdf1.format(target.getCreateTime()));

                //审批意见
                map.put("remark", target.getRemark());

                //审批时间
                if (target.getUpdateTime() != null) {
                    map.put("updateTime", sdf1.format(target.getUpdateTime()));
                }

                map.put("approvalExplain", target.getApprovalExplain());

                if (target.getApprovedTime() != null) {
                    map.put("approvedTime", sdf1.format(target.getApprovedTime()));
                }

                mapList.add(map);
            }

            if (exportFlag) {
                String filePath = exportXls(mapList);
                messageResult.setData(filePath);
            } else {
                Map<String, Object> dataMap = PojoUtils.pageWrapper(page);
                dataMap.put("data", mapList);
                messageResult.setData(dataMap);
            }

            messageResult.setResult(true);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            messageResult.setResult(false);
        }

        return messageResult;
    }


    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        return days;
    }


    private String exportXls(List<Map> mapList) {
        String downloadUrl = "";

        Workbook workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet();

        //表头
        Row rowTitle = sheet.createRow(0);

        String[] titles = new String[]{"序号", "申请时间", "姓名", "身份证号", "所属单位",
                "审批人", "审批状态", "年假时间", "请假天数", "请假事由", "审核意见", "审核时间"};

        for (int i = 0; i < titles.length; i++) {
            Cell cell = rowTitle.createCell(i);
            cell.setCellValue(titles[i]);
        }

        for (int i = 0; i < mapList.size(); i++) {
            Map<String, Object> map = mapList.get(i);

            Row row = sheet.createRow(i + 1);

            int colIndex = 0;
            row.createCell(colIndex++).setCellValue(i + 1);
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("createTime"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("name"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("idCard"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("className"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("approvedName"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("statusN"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("time"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("days"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("reason"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("remark"), ""));
            row.createCell(colIndex++).setCellValue(com.jpsoft.shinestar.modules.common.utils.StringUtils.strValue(map.get("updateTime"), ""));
        }

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        try {
            workbook.write(output);

            byte[] buffer = output.toByteArray();
            ByteArrayInputStream input = new ByteArrayInputStream(buffer);

            downloadUrl = OSSUtil.upload(ossConfig, "requestForLeave", "请假记录.xls", input);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }

        return downloadUrl;
    }
}
