package com.xjrsoft.module.personnel.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xjrsoft.common.model.result.RT;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.personnel.dto.*;
import com.xjrsoft.module.personnel.entity.BasePersonnelLabourCapital;
import com.xjrsoft.module.personnel.entity.BasePersonnelLabourCapitalData;
import com.xjrsoft.module.personnel.entity.BasePersonnelLabourCapitalTitle;
import com.xjrsoft.module.personnel.service.IBasePersonnelLabourCapitalService;
import com.xjrsoft.module.personnel.vo.BasePersonnelLabourCapitalPageVo;
import com.xjrsoft.module.personnel.vo.BasePersonnelLabourCapitalVo;
import com.xjrsoft.module.personnel.vo.BasePersonnelLabourCapitalMonthPageVo;
import com.xjrsoft.module.personnel.vo.BasePersonnelLabourCapitalYearPageVo;
import com.xjrsoft.module.weekly.dto.WeeklyDutySchedulePageDto;
import com.xjrsoft.module.weekly.vo.WeeklyDutyScheduleListVo;
import com.yomahub.liteflow.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* @title: 工资发放
* @Author dzx
* @Date: 2023-11-08
* @Version 1.0
*/
@RestController
@RequestMapping("/personnel" + "/basepersonnellabourcapital")
@Api(value = "/personnel"  + "/basepersonnellabourcapital",tags = "工资发放代码")
@AllArgsConstructor
public class BasePersonnelLabourCapitalController {


    private final IBasePersonnelLabourCapitalService basePersonnelLabourCapitalService;

    @GetMapping(value = "/page")
    @ApiOperation(value="工资发放列表(分页)")
    @SaCheckPermission("basepersonnellabourcapital:detail")
    public RT<PageOutput<BasePersonnelLabourCapitalPageVo>> page(@Valid BasePersonnelLabourCapitalPageDto dto){

        LambdaQueryWrapper<BasePersonnelLabourCapital> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                    .orderByDesc(BasePersonnelLabourCapital::getId)
                .select(BasePersonnelLabourCapital.class,x -> VoToColumnUtil.fieldsToColumns(BasePersonnelLabourCapitalPageVo.class).contains(x.getProperty()));
        IPage<BasePersonnelLabourCapital> page = basePersonnelLabourCapitalService.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<BasePersonnelLabourCapitalPageVo> pageOutput = ConventPage.getPageOutput(page, BasePersonnelLabourCapitalPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/monthpage")
    @ApiOperation(value="手机端月工资条发放列表(分页)")
    @SaCheckPermission("basepersonnellabourcapital:detail")
    public RT<PageOutput<BasePersonnelLabourCapitalMonthPageVo>> monthPage(@Valid BasePersonnelLabourCapitalMonthPageDto dto){
        Page<BasePersonnelLabourCapitalMonthPageVo> page = basePersonnelLabourCapitalService.getMonthPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
        PageOutput<BasePersonnelLabourCapitalMonthPageVo> pageOutput = ConventPage.getPageOutput(page, BasePersonnelLabourCapitalMonthPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/yearpage")
    @ApiOperation(value="手机端年工资条发放列表(分页)")
    @SaCheckPermission("basepersonnellabourcapital:detail")
    public RT<PageOutput<BasePersonnelLabourCapitalYearPageVo>> yearPage(@Valid BasePersonnelLabourCapitalYearPageDto dto){
        Page<BasePersonnelLabourCapitalYearPageVo> page = basePersonnelLabourCapitalService.getYearPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
        PageOutput<BasePersonnelLabourCapitalYearPageVo> pageOutput = ConventPage.getPageOutput(page, BasePersonnelLabourCapitalYearPageVo.class);
        return RT.ok(pageOutput);
    }

    @GetMapping(value = "/info")
    @ApiOperation(value="根据id查询工资发放信息")
    @SaCheckPermission("basepersonnellabourcapital:detail")
    public RT<BasePersonnelLabourCapitalVo> info(@RequestParam Long id){
        BasePersonnelLabourCapital basePersonnelLabourCapital = basePersonnelLabourCapitalService.getByIdDeep(id);
        if (basePersonnelLabourCapital == null) {
           return RT.error("找不到此数据！");
        }
        return RT.ok(BeanUtil.toBean(basePersonnelLabourCapital, BasePersonnelLabourCapitalVo.class));
    }


    @PostMapping
    @ApiOperation(value = "新增工资发放")
    @SaCheckPermission("basepersonnellabourcapital:add")
    public RT<Boolean> add(@Valid @RequestBody AddBasePersonnelLabourCapitalDto dto){
        BasePersonnelLabourCapital basePersonnelLabourCapital = BeanUtil.toBean(dto, BasePersonnelLabourCapital.class);
        boolean isSuccess = basePersonnelLabourCapitalService.add(basePersonnelLabourCapital);
    return RT.ok(isSuccess);
    }

    @PutMapping
    @ApiOperation(value = "修改工资发放")
    @SaCheckPermission("basepersonnellabourcapital:edit")
    public RT<Boolean> update(@Valid @RequestBody UpdateBasePersonnelLabourCapitalDto dto){

        BasePersonnelLabourCapital basePersonnelLabourCapital = BeanUtil.toBean(dto, BasePersonnelLabourCapital.class);
        return RT.ok(basePersonnelLabourCapitalService.update(basePersonnelLabourCapital));

    }

    @DeleteMapping
    @ApiOperation(value = "删除工资发放")
    @SaCheckPermission("basepersonnellabourcapital:delete")
    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
        return RT.ok(basePersonnelLabourCapitalService.delete(ids));

    }
    @PostMapping("/import")
    @ApiOperation(value = "导入")
    public RT<Boolean> importData(@Valid AddBasePersonnelLabourCapitalDto dto, @RequestParam("file") MultipartFile file) throws IOException, ParseException {
        List<Map<Integer, Object>> excelDataList = EasyExcel.read(file.getInputStream()).sheet().headRowNumber(4 - 1).doReadSync();
        //验证数据

        //构造数据
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        BasePersonnelLabourCapital basePersonnelLabourCapital = BeanUtil.toBean(dto, BasePersonnelLabourCapital.class);
        basePersonnelLabourCapital.setDataRow(4);
        basePersonnelLabourCapital.setPersonnelNameColumn(3);
        basePersonnelLabourCapital.setAmountToColumn(4);
        basePersonnelLabourCapital.setIdTypeColumn(0);
        basePersonnelLabourCapital.setIdNumberColumn(1);
        basePersonnelLabourCapital.setJobNumberColumn(2);
        basePersonnelLabourCapital.setDateOfIssue(sdf.parse(dto.getDateOfIssue()));

        //处理表头数据，目前只支持2行表头
        List<BasePersonnelLabourCapitalTitle> titleList = initTitleList(excelDataList.get(0), excelDataList.get(1), basePersonnelLabourCapital);
        //读取表内容数据
        List<BasePersonnelLabourCapitalData> dataList = initDataList(dto, excelDataList);

        //添加表头数据
        basePersonnelLabourCapital.setBasePersonnelLabourCapitalTitleList(titleList);
        basePersonnelLabourCapital.setBasePersonnelLabourCapitalDataList(dataList);

        Boolean result = basePersonnelLabourCapitalService.add(basePersonnelLabourCapital);
        return RT.ok(result);
    }

    /**
     * 处理教师工资数据
     * @param excelDataList 表格数据
     * @return 返回集合
     */
    List<BasePersonnelLabourCapitalData> initDataList(AddBasePersonnelLabourCapitalDto dto, List<Map<Integer, Object>> excelDataList){
        List<BasePersonnelLabourCapitalData> resultList = new ArrayList<>();
        for (int i = 0; i < excelDataList.size(); i ++){
            //跳过表头
            if(i < 2){
                continue;
            }
            Map<Integer, Object> datatMap = excelDataList.get(i);
            BasePersonnelLabourCapitalData data = new BasePersonnelLabourCapitalData();
            data.setName(datatMap.get(3) == null?null:datatMap.get(3).toString());
            data.setIdNumber(datatMap.get(1) == null?null:datatMap.get(1).toString());
            data.setIdType(datatMap.get(0) == null?null:datatMap.get(0).toString());
            data.setAmountTo(datatMap.get(4) == null?null:datatMap.get(4).toString());
            data.setJobNumber(datatMap.get(2) == null?null:datatMap.get(2).toString());
            data.setExtendJson(JsonUtil.toJsonString(datatMap));
            resultList.add(data);
        }

        return resultList;
    }

    /**
     * 处理表头数据
     * @param titleRow1 第一行数据
     * @param titleRow2 第二行数据
     * @return 返回集合
     */
    List<BasePersonnelLabourCapitalTitle> initTitleList(Map<Integer, Object> titleRow1, Map<Integer, Object> titleRow2, BasePersonnelLabourCapital capital){
        List<BasePersonnelLabourCapitalTitle> resultList = new ArrayList<>();
        //识别第一行
        int mergeColumns = 0, mergeRows = 0;
        for (Integer column : titleRow1.keySet()) {
            BasePersonnelLabourCapitalTitle title = new BasePersonnelLabourCapitalTitle();
            Object value = titleRow1.get(column);
            if(value == null){
                mergeColumns = 0;
                continue;
            }
            for (int i = column + 1; i < titleRow1.size(); i ++){
                Object mergeValue = titleRow1.get(i);
                if(mergeValue != null){
                    break;
                }
                mergeColumns ++;
            }

            Object value2 = titleRow2.get(column);
            if(value2 == null){
                mergeRows = 2;
            }

            title.setName(value.toString());
            title.setColumnNumber(column);
            title.setRowsNumber(capital.getDataRow() - 1);
            title.setMergeColumns(mergeColumns);
            title.setMergeRows(mergeRows);
            resultList.add(title);

            mergeColumns = 0;
            mergeRows = 0;
        }

        //识别第二行
        for (Integer column : titleRow2.keySet()) {
            BasePersonnelLabourCapitalTitle title = new BasePersonnelLabourCapitalTitle();
            Object value = titleRow2.get(column);
            if(value == null){
                continue;
            }

            title.setName(value.toString());
            title.setColumnNumber(column);
            title.setRowsNumber(capital.getDataRow());
            title.setMergeColumns(mergeColumns);
            title.setMergeRows(mergeRows);
            resultList.add(title);
        }

        return resultList;
    }

    @GetMapping("/export")
    @ApiOperation(value = "导出")
    public ResponseEntity<byte[]> exportData(@Valid WeeklyDutySchedulePageDto dto, @RequestParam(defaultValue = "false") Boolean isTemplate) {
        List<BasePersonnelLabourCapital> list = basePersonnelLabourCapitalService.list();
        ByteArrayOutputStream bot = new ByteArrayOutputStream();
        EasyExcel.write(bot, BasePersonnelLabourCapital.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(list);

        return RT.fileStream(bot.toByteArray(), "BasePersonnelLabourCapital" + ExcelTypeEnum.XLSX.getValue());
    }

}