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.AlarmConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.entity.HolidayInfo;
import com.jpsoft.shinestar.modules.base.service.HolidayInfoService;
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.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.common.utils.POIUtils;
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.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 节假日设置
 */
@RestController
@RequestMapping("/base/holidayInfo")
public class HolidayInfoController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private HolidayInfoService holidayInfoService;

    @Autowired
    private UserService userService;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private OSSConfig ossConfig;

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

        HolidayInfo holidayInfo = new HolidayInfo();

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

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

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

            int affectCount = holidayInfoService.insert(holidayInfo);

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

        try {
            HolidayInfo holidayInfo = holidayInfoService.get(id);

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

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

            int affectCount = holidayInfoService.update(holidayInfo);

            if (affectCount > 0) {
                msgResult.setResult(true);
                msgResult.setData(holidayInfo);
            } 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 {
            HolidayInfo holidayInfo = holidayInfoService.get(id);
            holidayInfo.setDelFlag(true);
            holidayInfo.setUpdateBy(subject);
            holidayInfo.setUpdateTime(new Date());

            int affectCount = holidayInfoService.update(holidayInfo);

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

                affectCount += holidayInfoService.update(holidayInfo);
            }

            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(
            String companyId,String holidayName,String startDate,String endDate,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
            @RequestAttribute String subject){

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

        User user = userService.get(subject);
        CompanyInfo companyInfo = null;

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

        if(companyInfo==null){
            //如果当前不是系统管理员，则只能看见当前管理员所在单位设置假日
            if(!userService.hasRole(user.getId(),"SYSADMIN")) {
                companyInfo = companyInfoService.get(user.getCompanyId());
            }
        }

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

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

        if(companyInfo!=null){
            searchParams.put("companyCode", companyInfo.getCode() + "%");
        }

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

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

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

        List<Sort> sortList = new ArrayList<>();
        sortList.add(new Sort("a.begin_date","desc"));
        sortList.add(new Sort("b.level_","asc"));
        sortList.add(new Sort("b.sort_no","asc"));
        sortList.add(new Sort("b.name_","asc"));

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

        msgResult.setResult(true);
        msgResult.setData(PojoUtils.pageWrapper(page));

        return msgResult;
    }

    @ApiOperation(value="导出节假日设置")
    @RequestMapping(value = "exportXls",method = RequestMethod.POST)
    public MessageResult<String> exportXls(
            String id,String holidayName,String startDate,String endDate,
            @RequestParam(value="companyId",defaultValue="") String companyId,
            @RequestParam(value="pageIndex",defaultValue="0") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="100000") int pageSize,
            @RequestAttribute String subject){

        //当前用户ID
        System.out.println(subject);
        MessageResult<String> msgResult = new MessageResult<>();
        try {
            Map<String, Object> searchParams = new HashMap<>();

            User user = userService.get(subject);
            CompanyInfo companyInfo = null;

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

            if(companyInfo==null){
                //如果当前不是系统管理员，则只能看见当前管理员所在单位设置假日
                if(!userService.hasRole(user.getId(),"SYSADMIN")) {
                    companyInfo = companyInfoService.get(user.getCompanyId());
                }
            }


            if(companyInfo!=null){
                searchParams.put("companyCode", companyInfo.getCode() + "%");
            }

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

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

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

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("b.level_","asc"));
            sortList.add(new Sort("b.sort_no","asc"));
            sortList.add(new Sort("b.name_","asc"));
            sortList.add(new Sort("a.begin_date","asc"));

            Page<HolidayInfo> page = holidayInfoService.pageSearch(searchParams,pageIndex,pageSize,false,sortList);


            HSSFWorkbook workbook = new HSSFWorkbook();
            HSSFSheet sheet = workbook.createSheet();
            //表头
            HSSFRow rowTitle = sheet.createRow(0);
            HSSFCell cellTitle1 = rowTitle.createCell(0);
            cellTitle1.setCellValue("序号");

            HSSFCell cellTitle2 = rowTitle.createCell(1);
            cellTitle2.setCellValue("单位");
            sheet.setColumnWidth(1, 22 * 256);

            HSSFCell cellTitle3 = rowTitle.createCell(2);
            cellTitle3.setCellValue("节假日名称");
            sheet.setColumnWidth(2, 22 * 256);

            HSSFCell cellTitle4 = rowTitle.createCell(3);
            cellTitle4.setCellValue("开始日期");
            sheet.setColumnWidth(3, 22 * 256);

            HSSFCell cellTitle5 = rowTitle.createCell(4);
            cellTitle5.setCellValue("结束日期");
            sheet.setColumnWidth(4, 22 * 256);

            HSSFCell cellTitle6 = rowTitle.createCell(5);
            cellTitle6.setCellValue("是否需要上班");
            sheet.setColumnWidth(5, 22 * 256);

            HSSFCell cellTitle7 = rowTitle.createCell(6);
            cellTitle7.setCellValue("参考上班日");
            sheet.setColumnWidth(6, 22 * 256);

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

            for(int i=0; i<page.size(); i++){
                HolidayInfo hi = page.get(i);

                HSSFRow rowContent = sheet.createRow(i + 1);
                HSSFCell cellContent1 = rowContent.createCell(0);
                cellContent1.setCellValue(i+1);

                //单位
                HSSFCell cellContent2 = rowContent.createCell(1);
                if (hi.getCompanyName() != null) {
                    cellContent2.setCellValue(hi.getCompanyName());
                }
                //节假日名称
                HSSFCell cellContent3 = rowContent.createCell(2);
                if (hi.getHolidayName() != null) {
                    cellContent3.setCellValue(hi.getHolidayName());
                }
                //开始日期
                HSSFCell cellContent4 = rowContent.createCell(3);
                if (hi.getBeginDate() != null) {
                    cellContent4.setCellValue(sdf.format(hi.getBeginDate()));
                }
                //结束日期
                HSSFCell cellContent5 = rowContent.createCell(4);
                if (hi.getEndDate() != null) {
                    cellContent5.setCellValue(sdf.format(hi.getEndDate()));
                }
                //是否需要上班
                HSSFCell cellContent6 = rowContent.createCell(5);
                if (hi.getWorking() != null) {
                    cellContent6.setCellValue(hi.getWorking()?"是":"否");
                }
                //参考上班日
                HSSFCell cellContent7 = rowContent.createCell(6);
                if (hi.getRefWeekdayN() != null) {
                    cellContent7.setCellValue(hi.getRefWeekdayN());
                }
            }

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

            byte[] buffer = output.toByteArray();
            ByteArrayInputStream input = new ByteArrayInputStream(buffer);
            //格式化
            SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
            String fileName = "导出考勤时间设置数据" + sim.format(new Date()) + ".xls";
            String downloadUrl = OSSUtil.upload(ossConfig, "import", fileName, input);

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

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


        return msgResult;
    }


    @ApiOperation(value="导入节假日设置")
    @PostMapping("importXls")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uploadFile",value = "上传文件", required = true,paramType="form", dataType = "__file")
    })
    public MessageResult<String> importXls(MultipartFile uploadFile,
                                           String companyId,
                                           @RequestAttribute String subject){
        User user = userService.get(subject);
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            POIUtils poiUtils = new POIUtils(uploadFile.getInputStream());
            int sheetIndex = 0;
            Sheet sheet1 = poiUtils.getSheetAt(sheetIndex);

            String[] colNames = new String[]{"节假日名称","开始日期","结束日期","是否需要上班","参考上班日"};
            Map<String,Integer> headerMap = new HashMap<>();

            Row headerRow = sheet1.getRow(0);

            for (int i=0;i<colNames.length;i++) {
                String colName = colNames[i];

                for (int j = 0; j < headerRow.getLastCellNum(); j++) {
                    String title = headerRow.getCell(j).getStringCellValue();

                    if (title.indexOf(colName)!=-1){
                        headerMap.put(colName, j);
                        break;
                    }
                }
            }

            int affectCount = 0;
            int failCount = 0;
            int validateColIndex = 9;

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

            for(int rowIndex=1 ; rowIndex<=sheet1.getLastRowNum(); rowIndex++){
                try {
                    String holidayName = "";

                    if(headerMap.containsKey("节假日名称")){
                        holidayName = poiUtils.getCellValue(sheetIndex,rowIndex,headerMap.get("节假日名称")).toString().replace(" ","");
                    }

                    String beginDateStr = "";
                    Date tttt = null;
                    if(headerMap.containsKey("开始日期")) {
                        beginDateStr = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("开始日期")).toString().replace(" ", "");
                    }

                    String endDateStr = "";

                    if(headerMap.containsKey("结束日期")) {
                        endDateStr = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("结束日期")).toString().replace(" ", "");
                    }

                    String workingStr = "";

                    if(headerMap.containsKey("是否需要上班")) {
                        workingStr = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("是否需要上班")).toString().replace(" ", "");
                    }

                    String refWeekdayN = "";

                    if(headerMap.containsKey("参考上班日")) {
                        refWeekdayN = poiUtils.getCellValue(sheetIndex, rowIndex, headerMap.get("参考上班日")).toString().replace(" ", "");
                    }



                    CompanyInfo companyInfo = companyInfoService.get(companyId);

                    if(companyInfo == null){
                        sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("公司不存在!");
                        failCount++;
                        continue;
                    }else{
                        companyId = companyInfo.getId();
                    }


                    Date beginDate = null;
                    Date endDate = null;
                    Boolean working = false;
                    int refWeekday = 0;

                    if(StringUtils.isEmpty(holidayName)){
                        sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("请填写节假日名称!");
                        failCount++;
                        continue;
                    }

                    if(StringUtils.isNotEmpty(beginDateStr)){
                        try {
                            beginDate = sdf.parse(beginDateStr);
                        } catch (Exception ex) {
                            sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("开始日期格式有误!");
                            failCount++;
                            continue;
                        }
                    }else{
                        sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("请填写开始日期!");
                        failCount++;
                        continue;
                    }

                    if(StringUtils.isNotEmpty(endDateStr)){
                        try {
                            endDate = sdf.parse(endDateStr);
                        } catch (Exception ex) {
                            sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("结束日期格式有误!");
                            failCount++;
                            continue;
                        }
                    }else{
                        sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("请填写结束日期!");
                        failCount++;
                        continue;
                    }

                    if(StringUtils.isNotEmpty(workingStr)){
                        if("是".equals(workingStr)){
                            working = true;
                        }else{
                            working = false;
                        }
                    }

                    if(StringUtils.isNotEmpty(refWeekdayN)){
                        if("无".equals(refWeekdayN)){
                            refWeekday = 0;
                        }else if ("周一".equals(refWeekdayN)){
                            refWeekday = 1;
                        }else if ("周二".equals(refWeekdayN)){
                            refWeekday = 2;
                        }else if ("周三".equals(refWeekdayN)){
                            refWeekday = 3;
                        }else if ("周四".equals(refWeekdayN)){
                            refWeekday = 4;
                        }else if ("周五".equals(refWeekdayN)){
                            refWeekday = 5;
                        }else if ("周六".equals(refWeekdayN)){
                            refWeekday = 6;
                        }else if ("周日".equals(refWeekdayN)){
                            refWeekday = 7;
                        }else {
                            refWeekday = 0;
                        }
                    }else{
                        sheet1.getRow(rowIndex).createCell(validateColIndex).setCellValue("请填写参考上班日!");
                        failCount++;
                        continue;
                    }



                    //用户身份
                    HolidayInfo hi = new HolidayInfo();
                    hi.setId(UUID.randomUUID().toString());
                    hi.setCompanyId(companyId);
                    hi.setBeginDate(beginDate);
                    hi.setEndDate(endDate);
                    hi.setWorking(working);
                    hi.setHolidayName(holidayName);
                    hi.setRefWeekday(refWeekday);
                    hi.setDelFlag(false);
                    hi.setCreateBy(subject);
                    hi.setCreateTime(new Date());

                    //保存
                    holidayInfoService.insert(hi);
                    affectCount++;
                }
                catch(Exception innerEx){
                    logger.error(innerEx.getMessage(),innerEx);
                }
            }

            if (failCount>0){
                //有导入失败的记录
                msgResult.setResult(false);
                msgResult.setMessage("数据成功导入" + affectCount + "条,有" + failCount + "条数据未导入成功，错误原因请查看报表。");

                //todo 只保留错误数据的sheet
                Workbook wb = poiUtils.exportErrorXls(sheetIndex,validateColIndex,1 + affectCount + failCount);

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

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

                //格式化holidayInfo
                SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "error" + sim.format(new Date()) + ".xls";
                String downloadUrl = OSSUtil.upload(ossConfig,"import",fileName,input);

                //todo 返回导入失败报表下载链接
                msgResult.setData(downloadUrl);
            }
            else{
                msgResult.setResult(true);
                msgResult.setMessage("数据成功导入" + affectCount + "条");
            }
        }
        catch(Exception ex){
            logger.error(ex.getMessage(),ex);

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

        return msgResult;
    }
}
