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

import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.business.dto.UpdatePersonAttendanceDTO;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.utils.NewWordUtils;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.common.utils.PojoUtils;
import com.jpsoft.shinestar.modules.sys.entity.User;
import com.jpsoft.shinestar.modules.sys.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
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.*;

/**
 * 外出请假审批
 * sz
 */
@RestController
@RequestMapping("/base/businessOut")
@Api(description = "businessOut")
public class BusinessOutController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private BusinessOutService businessOutService;
    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private PersonInfoService personInfoService;
    @Autowired
    private PersonPopedomService personPopedomService;
    @Autowired
    private PersonRoleInfoService personRoleInfoService;
    @Autowired
    private OSSConfig ossConfig;
    @Autowired
    private UserService userService;
    @Autowired
    RabbitTemplate rabbitTemplate;

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

        BusinessOut businessOut = new BusinessOut();

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

        return msgResult;
    }

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

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

            int affectCount = businessOutService.insert(businessOut);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(businessOut);
            } 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<BusinessOut> edit(@PathVariable("id") String id){
        MessageResult<BusinessOut> msgResult = new MessageResult<>();

        try {
            BusinessOut businessOut = businessOutService.get(id);

            if (businessOut != null) {
                msgResult.setResult(true);
                msgResult.setData(businessOut);
            } 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<BusinessOut> update(@RequestBody BusinessOut businessOut,@RequestAttribute String subject){
        MessageResult<BusinessOut> msgResult = new MessageResult<>();

        try {
            businessOut.setUpdateBy(subject);
        //    businessOut.setUpdateTime(new Date());

            int affectCount = businessOutService.update(businessOut);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(businessOut);
            } 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<Integer> delete(@PathVariable("id") String id,@RequestAttribute String subject){
        MessageResult<Integer> msgResult = new MessageResult<>();

        try {
            BusinessOut businessOut = businessOutService.get(id);
            businessOut.setDelFlag(true);
            businessOut.setUpdateBy(subject);
            businessOut.setUpdateTime(new Date());

            int affectCount = businessOutService.update(businessOut);

            if (affectCount > 0) {
                UpdatePersonAttendanceDTO updatePersonAttendanceDTO = new UpdatePersonAttendanceDTO(
                        businessOut.getPersonId(), businessOut.getStartTime(),businessOut.getEndTime());

                rabbitTemplate.convertAndSend("updatePersonAttendanceQueue", updatePersonAttendanceDTO);


                Long personId = businessOut.getPersonId();

                PersonInfo personInfo = personInfoService.get(personId);

                if(personInfo!=null){
                    personInfo.setWorkStatus("1");
                    personInfo.setUpdateBy(subject);
                    personInfo.setUpdateTime(new Date());
                    personInfoService.update(personInfo);
                }

                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("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) {
                BusinessOut businessOut = businessOutService.get(id);
                businessOut.setDelFlag(true);
                businessOut.setUpdateBy(subject);
                businessOut.setUpdateTime(new Date());

                affectCount += businessOutService.update(businessOut);
            }

            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="列表")
    @RequestMapping(value = "pageList",method = RequestMethod.POST)
    public MessageResult<Map> pageList(
            @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,
            @RequestParam(value="personName",defaultValue="") String personName,
            @RequestParam(value="type",defaultValue="") String type,
            @RequestParam(value="status",defaultValue="") String status,
            @RequestParam(value="approvalNo",defaultValue="") String approvalNo,
            @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,
            @RequestAttribute String subject){

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();

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

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

        if (StringUtils.isNotEmpty(companyId)){
            CompanyInfo companyInfo = companyInfoService.get(companyId);

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

        if (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);
        }

        if (StringUtils.isNotEmpty(personName)) {
            searchParams.put("personName","%" + personName + "%");
        }

        if (StringUtils.isNotEmpty(type)) {
            searchParams.put("type",type);
        }

        if (StringUtils.isNotEmpty(status)) {
            searchParams.put("status",status);
        }

        if (StringUtils.isNotEmpty(approvalNo)) {
            searchParams.put("approvalNo","%" + approvalNo + "%");
        }

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

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

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

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

        //系统管理员
        boolean sysAdmin = userService.hasRole(subject,"SYSADMIN");

        if(!sysAdmin){
            User user = userService.get(subject);
            CompanyInfo companyInfo = companyInfoService.get(user.getCompanyId());
            List<CompanyInfo> inCompanyIdList = companyInfoService.findAllCompanyByCode(companyInfo.getCode() + "%");
            searchParams.put("inCompanyIdList",inCompanyIdList);
        }

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

        for(BusinessOut bo : page.getResult()){
            //翻译
            CompanyInfo ci = companyInfoService.get(bo.getPersonCompanyId());
            bo.setPersonCompanyName(ci.getName());

            String approvalPopedomId = bo.getApprovalPersonPopedomId();
            PersonPopedom pp = personPopedomService.get(approvalPopedomId);
            if(pp == null){
                continue;
            }
            PersonRoleInfo pri = personRoleInfoService.get(pp.getPersonRoleId());
            PersonInfo pi = personInfoService.get(pp.getPersonId());

            if(pi == null){
                continue;
            }
            bo.setApprovalPersonId(pi.getId());
            bo.setApprovalPersonName(pi.getName());
            if(pri == null){
                continue;
            }
            bo.setApprovalPersonRoleName(pri.getPersonRoleName());
        }
        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }

    @ApiOperation(value="导出人员")
    @PostMapping("createWord")
    public MessageResult<String> createWord(
            @RequestParam(value = "id", defaultValue = "") String id,
            @RequestAttribute String subject){
        MessageResult<String> msgResult = new MessageResult<>();
        try {
            BusinessOut bo = businessOutService.get(id);
            PersonPopedom pp = personPopedomService.get(bo.getPersonPopedomId());
            PersonInfo pi = personInfoService.get(pp.getPersonId());
            CompanyInfo ci = companyInfoService.get(pi.getCompanyId());

            if(bo == null ){
                throw new Exception("没有查到此单据");
            }
            String inputUrl = "static/businessout.docx";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            Map<String, String> testMap = new HashMap<String, String>();
            testMap.put("name", pi.getName());
            testMap.put("department", ci.getName());
            testMap.put("address", bo.getDestination());
            testMap.put("start", sdf.format(bo.getStartTime()));
            String end = "";
            if(bo.getEndTime() != null){
                end = sdf.format(bo.getEndTime());
            }
            testMap.put("end", end);
            testMap.put("reason", bo.getContent());
            testMap.put("num", bo.getApprovalNo());
            Date createTime =  bo.getCreateTime();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(createTime);
            testMap.put("year",String.valueOf(calendar.get(calendar.YEAR)));
            testMap.put("month", String.valueOf(calendar.get(calendar.MONTH)));
            testMap.put("day", String.valueOf(calendar.get(calendar.DATE)));

            List<String[]> testList = new ArrayList<String[]>();

            String downloadUrl = NewWordUtils.changWord(inputUrl,ossConfig, testMap, testList);

            msgResult.setResult(true);
            msgResult.setData(downloadUrl);
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

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

        return msgResult;
    }

    @ApiOperation(value="审核列表")
    @PostMapping("flowList/{id}")
    public MessageResult<Map> flowList(@PathVariable("id") String id,@RequestAttribute String subject){
        MessageResult<Map> msgResult = new MessageResult<>();
        List<BusinessOut> list = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");

        try {
            BusinessOut businessOut = businessOutService.get(id);

            if(StringUtils.isNotEmpty(businessOut.getApprovalPersonIdStr())) {
                String[] personIdStr = businessOut.getApprovalPersonIdStr().split(",");
                String[] statusStr = businessOut.getApprovalStatusStr().split(",");
                String[] timeStr = businessOut.getApprovalTimeStr().split(",");
                String[] contentStr = businessOut.getApprovalContentStr().split(",");
                for (int i = 0; i < personIdStr.length; i++) {
                    BusinessOut newBusinessOut = new BusinessOut();
                    newBusinessOut.setApprovalPersonPopedomId(personIdStr[i]);
                    newBusinessOut.setStatus(statusStr[i]);
                    newBusinessOut.setApprovalTime(simpleDateFormat.parse(timeStr[i]));
                    newBusinessOut.setApprovalContent(contentStr[i]);
                    list.add(newBusinessOut);
                }
            }

            BusinessOut newBusinessOutLast = new BusinessOut();
            newBusinessOutLast.setApprovalPersonPopedomId(businessOut.getApprovalPersonPopedomId());
            newBusinessOutLast.setStatus(businessOut.getStatus());
            newBusinessOutLast.setApprovalTime(businessOut.getApprovalTime());
            newBusinessOutLast.setApprovalContent(businessOut.getApprovalContent());
            list.add(newBusinessOutLast);

            for(BusinessOut bo : list){
                //翻译
//                CompanyInfo ci = companyInfoService.get(bo.getPersonCompanyId());
//                bo.setPersonCompanyName(ci.getName());

                String approvalPopedomId = bo.getApprovalPersonPopedomId();
                PersonPopedom pp = personPopedomService.get(approvalPopedomId);
                if(pp == null){
                    continue;
                }
                PersonRoleInfo pri = personRoleInfoService.get(pp.getPersonRoleId());
                PersonInfo pi = personInfoService.get(pp.getPersonId());

                if(pi == null){
                    continue;
                }
                bo.setApprovalPersonId(pi.getId());
                bo.setApprovalPersonName(pi.getName());
                if(pri == null){
                    continue;
                }
                bo.setApprovalPersonRoleName(pri.getPersonRoleName());
            }

            Map<String,Object> map = new HashMap<>();
            map.put("data", list);

            msgResult.setResult(true);
            msgResult.setData(map);
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

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

        return msgResult;
    }

    @ApiOperation(value="导出考勤报表")
    @RequestMapping(value = "exportXls",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="companyId",value = "单位编号",required = true,paramType = "form"),
            @ApiImplicitParam(name = "subordinate",value = "是否查询下级单位", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name="name",value = "用户姓名",required = false,paramType = "form"),
            @ApiImplicitParam(name="jobNumber",value = "工号",required = false,paramType = "form"),
            @ApiImplicitParam(name = "startDate",value = "开始时间", required = true,paramType="form"),
            @ApiImplicitParam(name = "endDate",value = "截止时间", required = true,paramType="form"),
            @ApiImplicitParam(name = "subject",value = "subject", required = false,paramType="form")
    })
    public MessageResult<String> exportXls(
            @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,
            @RequestParam(value="personName",defaultValue="") String personName,
            @RequestParam(value="type",defaultValue="") String type,
            @RequestParam(value="status",defaultValue="") String status,
            @RequestParam(value="approvalNo",defaultValue="") String approvalNo,
            @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,@RequestAttribute String subject) throws Exception {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            MessageResult<Map> searchResult = pageList(companyId,subordinate,
                    hqCompanyId,hqSubordinate,personName,type,status,approvalNo,
                    requestStartTime,requestEndTime,auditStartTime,auditEndTime,1,10000,subject);

            Map<String,Object> dataMap = searchResult.getData();

            List<BusinessOut> businessOutList = (List<BusinessOut>)dataMap.get("data");

            ClassPathResource resource = new ClassPathResource("static/businessOutList.xlsx");

            Workbook wb = WorkbookFactory.create(resource.getInputStream());

            Sheet sheet = wb.getSheetAt(0);

            int startRowIndex = 1;

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

            for (int i = 0; i < businessOutList.size(); i++) {
                int colIndex = 0;

                Row row = sheet.createRow(startRowIndex + i);
                BusinessOut businessOut = businessOutList.get(i);

                //序号
                row.createCell(colIndex).setCellValue(i+1);
                colIndex++;

                //部门
                row.createCell(colIndex).setCellValue(businessOut.getPersonCompanyName());
                colIndex++;

                //工号
                row.createCell(colIndex).setCellValue(businessOut.getJobNumber());
                colIndex++;

                //姓名
                row.createCell(colIndex).setCellValue(businessOut.getPersonName());
                colIndex++;

                //从
                row.createCell(colIndex).setCellValue(sdf.format(businessOut.getStartTime()));
                colIndex++;

                //上午、下午
                int startHour = new DateTime(businessOut.getStartTime()).getHourOfDay();
                row.createCell(colIndex).setCellValue(startHour==0 ? "上午" : "下午");
                colIndex++;

                DateTime endTime = new DateTime(businessOut.getEndTime());
                int endHour = new DateTime(businessOut.getEndTime()).getHourOfDay();

                if (endHour==0){
                    endTime = endTime.plusDays(-1);
                }

                //到
                row.createCell(colIndex).setCellValue(endTime.toString("yyyy-MM-dd"));
                colIndex++;

                //上午、下午
                row.createCell(colIndex).setCellValue(endHour==12 ? "上午" : "下午");
                colIndex++;

                //类别(出差)
                row.createCell(colIndex).setCellValue("出差");
                colIndex++;

                //备注
                row.createCell(colIndex).setCellValue(businessOut.getContent());
                colIndex++;
            }

            CellStyle cellStyle1 = createCellStyle(wb);

            for (int i = 0; i < businessOutList.size(); i++) {
                Row row = sheet.getRow(startRowIndex + i);

                if (row != null) {
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        if (row.getCell(j) == null) {
                            row.createCell(j);
                        }

                        row.getCell(j).setCellStyle(cellStyle1);
                    }
                }
            }

            //todo 将wb保存到oss
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            wb.write(output);

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

            String fileName = "出差申请记录.xls";

            String downloadUrl = OSSUtil.upload(ossConfig, "businessOut", fileName, input);

            wb.write(output);
            wb.close();
            output.close();

            msgResult.setData(downloadUrl);
            msgResult.setResult(true);
        }
        catch (Exception ex){
            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
            logger.error(ex.getMessage(),ex);
        }

        return msgResult;
    }

    private CellStyle createCellStyle(Workbook wb){
        CellStyle cellStyle = wb.createCellStyle();

        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setWrapText(true);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        return cellStyle;
    }
}
