package com.ltgk.crew.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ltgk.common.annotation.Log;
import com.ltgk.common.annotation.RepeatSubmit;
import com.ltgk.common.constant.Constants;
import com.ltgk.common.core.controller.BaseController;
import com.ltgk.common.core.domain.AjaxResult;
import com.ltgk.common.core.domain.entity.SysUser;
import com.ltgk.common.core.page.TableDataInfo;
import com.ltgk.common.enums.BusinessType;
import com.ltgk.common.enums.SexTypeEnums;
import com.ltgk.common.utils.SecurityUtils;
import com.ltgk.common.utils.StringUtils;
import com.ltgk.common.utils.poi.ExcelUtil;
import com.ltgk.common.validation.groups.Add;
import com.ltgk.common.validation.groups.Detail;
import com.ltgk.common.validation.groups.Update;
import com.ltgk.crew.domain.dto.DsBoatCrewDTO;
import com.ltgk.crew.domain.entity.DsBoatCrew;
import com.ltgk.crew.domain.vo.DsBoatCrewVO;
import com.ltgk.crew.service.IDsBoatCrewService;
import com.ltgk.system.domain.SysAreaInfo;
import com.ltgk.system.service.SysAreaInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Validator;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 船员档案管理   前端控制器
 *
 * @author Qi ChengBin
 * @date 2024/12/02 14:59:04
 */
@Api(tags = "船员档案管理")
@RestController
@RequestMapping("/fishingPort/dsBoatCrew")
public class DsBoatCrewController extends BaseController {

    @Resource
    private IDsBoatCrewService dsBoatCrewService;
    @Resource
    private Validator validator;
    @Resource
    private SysAreaInfoService sysAreaInfoService;

    /**
     * 分页查询船员信息
     *
     * @param dsBoatCrewDTO: 船员信息查询对象
     * @return com.ltgk.common.core.page.TableDataInfo
     * @author Qi ChengBin
     * @date 2024/12/2 15:52
     */
    @PostMapping("/page")
    @ApiOperation("分页查询船员信息")
    @Log(title = "分页查询船员信息", businessType = BusinessType.PAGE_QUERY)
    public TableDataInfo page(@RequestBody DsBoatCrewDTO dsBoatCrewDTO) {
//        DsBoatCrew dsBoatCrew = getDsBoatCrew(dsBoatCrewDTO);
//        String beginTime = dsBoatCrewDTO.getStartTime();
//        String endTime = dsBoatCrewDTO.getEndTime();
//        // 获取系统用户信息
//        SysUser user = SecurityUtils.getLoginUser().getUser();
//        Integer pageNum = dsBoatCrewDTO.getPageNum();
//        Integer pageSize = dsBoatCrewDTO.getPageSize();
//        return getDataTable(dsBoatCrewService.selectByPage(dsBoatCrew, beginTime, endTime, user, pageNum, pageSize));
        return newPage(dsBoatCrewDTO);
    }

    // todo: 分页查询船员信息 优化
    public TableDataInfo newPage(DsBoatCrewDTO dsBoatCrewDTO) {
        return getDataTable(dsBoatCrewService.selectByPageNew(dsBoatCrewDTO));
    }

    /**
     * 新增 船员信息
     *
     * @param dsBoatCrew: 船员信息实体
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/3 09:49
     */
    @RepeatSubmit(message = "请勿重复提交")
    @ApiOperation(value = "添加船员信息")
    @Log(title = "新增船员信息", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@Validated(Add.class) @RequestBody DsBoatCrew dsBoatCrew) {
        String userName = SecurityUtils.getLoginUser().getUser().getNickName();
        dsBoatCrew.setCreateBy(userName)
                .setCreateAt(new Date())
                .setUpdateBy(userName)
                .setUpdateAt(new Date())
                .setDelFlag(Constants.FLAG_FALSE);
        return AjaxResult.success(dsBoatCrewService.save(dsBoatCrew));
    }

    /**
     * 修改船员信息
     *
     * @param dsBoatCrew: 船员档案信息实体对象
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/3 09:49
     */
    @ApiOperation(value = "修改船员信息")
    @Log(title = "修改船员信息", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    public AjaxResult update(@Validated(Update.class) @RequestBody DsBoatCrew dsBoatCrew) {
        String userName = SecurityUtils.getLoginUser().getUser().getNickName();
        dsBoatCrew.setUpdateBy(userName)
                .setUpdateAt(new Date());
        return AjaxResult.success(dsBoatCrewService.updateById(dsBoatCrew));
    }

    /**
     * 删除船员信息
     *
     * @param dsBoatCrewDTO: 船员档案信息数据传输对象
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/3 10:41
     */
    @ApiOperation(value = "删除船员信息")
    @PostMapping("/delete")
    @Log(title = "删除船员信息", businessType = BusinessType.DELETE)
    public AjaxResult delete(@Validated(Detail.class) @RequestBody DsBoatCrewDTO dsBoatCrewDTO) {
        return AjaxResult.success(dsBoatCrewService.removeById(dsBoatCrewDTO.getId()));
    }

    /**
     * 船员信息导出
     *
     * @param response:
     * @param dsBoatCrewDTO:
     * @author Qi ChengBin
     * @date 2024/12/3 13:49
     */
    @Log(title = "船员信息导出", businessType = BusinessType.EXPORT)
    @ApiOperation("船员信息导出")
    @PostMapping("/export")
    public void export(HttpServletResponse response, DsBoatCrewDTO dsBoatCrewDTO) throws UnsupportedEncodingException {
        DsBoatCrew dsBoatCrew = getDsBoatCrew(dsBoatCrewDTO);

        String startTime = dsBoatCrewDTO.getStartTime();
        String endTime = dsBoatCrewDTO.getEndTime();

        boolean timeNoteBlank = StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime);

        LambdaQueryWrapper<DsBoatCrew> dsBoatCrewLambdaQueryWrapper = new LambdaQueryWrapper<>(dsBoatCrew);
        dsBoatCrewLambdaQueryWrapper.between(timeNoteBlank, DsBoatCrew::getUpdateAt, startTime, endTime);
        List<DsBoatCrew> dsBoatCrewList = dsBoatCrewService.list(dsBoatCrewLambdaQueryWrapper);

        List<DsBoatCrewVO> dsBoatCrewVOList = dsBoatCrewList.stream().map(dsBoatCrewData -> {
            DsBoatCrewVO vo = new DsBoatCrewVO();
            BeanUtils.copyProperties(dsBoatCrewData, vo);
            if (ObjectUtils.isNotEmpty(dsBoatCrewData.getSex()))
                vo.setSex(SexTypeEnums.getMessage(dsBoatCrewData.getSex()));
            return vo;
        }).collect(Collectors.toList());

        ExcelUtil<DsBoatCrewVO> util = new ExcelUtil<>(DsBoatCrewVO.class);
        util.exportExcel(response, dsBoatCrewVOList, "船员信息");
    }

    /**
     * 船员信息导入
     *
     * @param file: 导入文件
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/3 14:05
     */
    @RepeatSubmit(message = "请勿重复提交")
    @Log(title = "船员信息导入", businessType = BusinessType.IMPORT)
    @ApiOperation("船员信息导入")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 校验是否为 Excel 格式
        ExcelUtil.checkExcelFile(file);

        // updateSupport 为是否 存在则覆盖
        ExcelUtil<DsBoatCrewVO> util = new ExcelUtil<>(DsBoatCrewVO.class);
        List<DsBoatCrewVO> dsBoatCrewVOList = util.importExcel(file.getInputStream());
        if (CollectionUtils.isEmpty(dsBoatCrewVOList)
                || dsBoatCrewVOList.stream().allMatch(Objects::isNull)
                || dsBoatCrewVOList.stream().noneMatch(crew -> StringUtils.isNotBlank(crew.getCrewName()))) {
            return AjaxResult.error("导入数据为空或模板格式有误！");
        }

        Set<String> areaNameList = dsBoatCrewVOList.stream().map(DsBoatCrewVO::getAreaName).collect(Collectors.toSet());

        List<SysAreaInfo> areaInfoList = sysAreaInfoService.findAreaInfoByAreaNameSet(areaNameList);
        Map<String, String> areaMap = areaInfoList.stream().collect(Collectors.toMap(SysAreaInfo::getAreaName, SysAreaInfo::getAreaCode));

        //处理数据
        List<DsBoatCrew> dsBoatCrewAddList = new ArrayList<>();
        List<DsBoatCrew> dsBoatCrewUpdateList = new ArrayList<>();
        for (DsBoatCrewVO dsBoatCrewVO : dsBoatCrewVOList) {
            DsBoatCrew item = new DsBoatCrew();
            BeanUtils.copyProperties(dsBoatCrewVO, item);
            LambdaQueryWrapper<DsBoatCrew> query = new LambdaQueryWrapper<>();
            query.eq(DsBoatCrew::getIdCardNo, item.getIdCardNo());
            query.last("limit 1");
            DsBoatCrew one = dsBoatCrewService.getOne(query);
            if (one == null) {
                // 根据行政区域名称设置行政区域编码，如果行政区域名称不存在或者是填错的情况，默认设置玉环市的行政区域编码
                item.setAreaCode(areaMap.getOrDefault(item.getAreaName(), "331083"))
                        .setDelFlag(Constants.FLAG_FALSE)
                        .setCreateBy(user.getNickName())
                        .setCreateAt(new Date())
                        .setUpdateBy(user.getNickName())
                        .setUpdateAt(new Date());
                dsBoatCrewAddList.add(item);
            } else {
                item.setId(one.getId())
                        .setUpdateBy(user.getNickName())
                        .setUpdateAt(new Date());
                dsBoatCrewUpdateList.add(item);
            }
        }
        //处理数据
        boolean update = false;
        boolean insert = false;
        if (CollectionUtils.isNotEmpty(dsBoatCrewUpdateList)) {
            update = dsBoatCrewService.updateBatchById(dsBoatCrewUpdateList);
        }
        if (CollectionUtils.isNotEmpty(dsBoatCrewAddList)) {
            insert = dsBoatCrewService.saveBatch(dsBoatCrewAddList);
        }
        return toAjax(update || insert);
    }

    /**
     * 船员信息导入模板导出
     *
     * @param response:
     * @author Qi ChengBin
     * @date 2024/12/3 14:15
     */
    @Log(title = "船员信息导入模板导出", businessType = BusinessType.EXPORT)
    @ApiOperation("船员信息导入模板导出")
    @GetMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<DsBoatCrewVO> util = new ExcelUtil<>(DsBoatCrewVO.class);
        util.importTemplateExcel(response, "船员信息导入模板");
    }

    /**
     * 一人一档
     *
     * @param dsBoatCrewDTO: 船员查询对象
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/6 14:48
     */
    @Log(title = "船员一人一档", businessType = BusinessType.QUERY)
    @ApiOperation("船员一人一档")
    @PostMapping("/getBoatCrewMessage")
    public AjaxResult getBoatCrewMessage(@Validated(Detail.class) @RequestBody DsBoatCrewDTO dsBoatCrewDTO) {
        DsBoatCrew dsBoatCrew = getDsBoatCrew(dsBoatCrewDTO);
        return dsBoatCrewService.getBoatCrewMessage(dsBoatCrew);
    }

    /**
     * 根据船员信息数据传输对象转换成船员信息实体对象
     *
     * @param dsBoatCrewDTO: 船员档案信息数据传输对象
     * @return com.ltgk.crew.domain.entity.DsBoatCrew
     * @author Qi ChengBin
     * @date 2024/12/23 16:03
     */
    private static DsBoatCrew getDsBoatCrew(DsBoatCrewDTO dsBoatCrewDTO) {
        dsBoatCrewDTO.queryCheck();
        DsBoatCrew dsBoatCrew = new DsBoatCrew();
        BeanUtils.copyProperties(dsBoatCrewDTO, dsBoatCrew);
        return dsBoatCrew;
    }
}
