package com.ltgk.crew.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ltgk.common.constant.Constants;
import com.ltgk.common.constant.SysConstant;
import com.ltgk.common.core.domain.AjaxResult;
import com.ltgk.common.core.domain.entity.SysRole;
import com.ltgk.common.core.domain.entity.SysUser;
import com.ltgk.common.enums.SexTypeEnums;
import com.ltgk.crew.domain.dto.DsBoatCrewDTO;
import com.ltgk.crew.domain.entity.DsBoatCrew;
import com.ltgk.crew.domain.entity.DsCrewCredential;
import com.ltgk.crew.domain.entity.DsCrewEnterCheck;
import com.ltgk.crew.domain.entity.DsCrewOutCheck;
import com.ltgk.crew.domain.vo.DsBoatBindCrewInfoVO;
import com.ltgk.crew.domain.vo.DsBoatCrewArchivesVO;
import com.ltgk.crew.mapper.DsBoatCrewMapper;
import com.ltgk.crew.service.IDsBoatCrewService;
import com.ltgk.crew.service.IDsCrewCredentialService;
import com.ltgk.crew.service.IDsCrewEnterCheckService;
import com.ltgk.crew.service.IDsCrewOutCheckService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ltgk.common.utils.PageUtils.startPage;

/**
 * 船员档案 service 实现
 *
 * @author Qi ChengBin
 * @date 2024-12-06
 */
@Service
public class DsBoatCrewServiceImpl extends ServiceImpl<DsBoatCrewMapper, DsBoatCrew> implements IDsBoatCrewService {

    @Resource
    private IDsCrewCredentialService dsCrewCredentialService;
    @Resource
    private IDsCrewOutCheckService dsCrewOutCheckService;
    @Resource
    private IDsCrewEnterCheckService dsCrewEnterCheckService;

    /**
     * 分页查询船员档案信息
     *
     * @param dsBoatCrew: 船员档案实体
     * @param beginTime:  开始时间
     * @param endTime:    结束时间
     * @param user:       登录用户信息
     * @param pageNum:    页码
     * @param pageSize:   页长
     * @return java.util.List<com.ltgk.crew.domain.vo.DsBoatBindCrewInfoVO>
     * @author Qi ChengBin
     * @date 2024/12/6 14:07
     */
    @Override
    public List<DsBoatBindCrewInfoVO> selectByPage(DsBoatCrew dsBoatCrew, String beginTime, String endTime, SysUser user, Integer pageNum, Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        // 此处使用角色权限字段来进行判断
        List<String> userRolesStr = user.getRoles().stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        //经营人查询自己渔船绑定的船员
        if (userRolesStr.contains(Constants.OPERATOR)) {
            map.put("ownerPhone", user.getPhonenumber());
        }
        //普通用户查询自己的信息
        if (userRolesStr.contains(SysConstant.GENERAL)) {
            map.put("crewPhone", user.getPhonenumber());
        }
        //街镇管理员
        if (userRolesStr.contains(SysConstant.ROLE_TOWN)) {
            map.put("streets", user.getStreets());
        }
        //村级管理员
        if (userRolesStr.contains(SysConstant.ROLE_VILLAGE)) {
            map.put("villages", user.getVillages());
        }
        map.put("boatName", dsBoatCrew.getBoatName());//渔船名称
        map.put("crewName", dsBoatCrew.getCrewName()); //船员名称
        map.put("boatDutyName", dsBoatCrew.getBoatDutyName());//职务
        map.put("idCardNo", dsBoatCrew.getIdCardNo());//身份证号
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);
        map.put("phone", dsBoatCrew.getPhone());
        startPage(pageNum, pageSize);
        List<DsBoatBindCrewInfoVO> dsBoatBindCrewInfoVOList = baseMapper.selectCrewPage(map);
        // 设置曾服务船舶
        if (CollectionUtils.isNotEmpty(dsBoatBindCrewInfoVOList)) {
            dsBoatBindCrewInfoVOList.forEach(dsBoatBindCrewInfoVO -> {
                String onceBoat = StringUtils.isNotBlank(dsBoatBindCrewInfoVO.getBoatName2()) ? dsBoatBindCrewInfoVO.getBoatName1() + "," + dsBoatBindCrewInfoVO.getBoatName2() : dsBoatBindCrewInfoVO.getBoatName1();
                dsBoatBindCrewInfoVO.setBoatName2(StringUtils.isNotBlank(onceBoat) ? onceBoat : null);
                dsBoatBindCrewInfoVO.setSex(SexTypeEnums.getMessage(dsBoatBindCrewInfoVO.getSex()));
                // 因为此种查询方式添加注解使其数据脱敏方式不好用，故此处手动进行数据脱敏
//                dsBoatBindCrewInfoVO.setIdCardNo(DesensitizedUtil.idCardNum(dsBoatBindCrewInfoVO.getIdCardNo(), 6, 2));
//                dsBoatBindCrewInfoVO.setPhone(DesensitizedUtil.mobilePhone(dsBoatBindCrewInfoVO.getPhone()));
            });
        }
        return dsBoatBindCrewInfoVOList;
    }

    /**
     * 校验船员信息在船员档案中不存在
     *
     * @param crewId:   船员信息id，不能为空
     * @param crewName: 船员名称，不能为空
     * @return boolean
     * @author Qi ChengBin
     * @date 2024/12/5 11:01
     */
    @Override
    public boolean checkCrewNoBeExist(Long crewId, String crewName) {
        LambdaQueryWrapper<DsBoatCrew> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DsBoatCrew::getCrewName, crewName)
                .eq(DsBoatCrew::getId, crewId)
                .eq(DsBoatCrew::getDelFlag, Constants.FLAG_FALSE);
        DsBoatCrew dsBoatCrew = this.getOne(wrapper);
        return Objects.isNull(dsBoatCrew);
    }

    /**
     * 一人一档
     *
     * @param dsBoatCrew:
     * @return com.ltgk.common.core.domain.AjaxResult
     * @author Qi ChengBin
     * @date 2024/12/6 14:51
     */
    @Override
    public AjaxResult getBoatCrewMessage(DsBoatCrew dsBoatCrew) {
        DsBoatCrewArchivesVO dsBoatCrewArchivesVO = new DsBoatCrewArchivesVO();
        // 根据传递的数据获取 船员基本信息
        DsBoatCrew dsBoatCrewData = this.getById(dsBoatCrew.getId());
        // 船员信息不为空
        if (Objects.nonNull(dsBoatCrewData)) {
            dsBoatCrewArchivesVO = BeanUtil.copyProperties(dsBoatCrewData, DsBoatCrewArchivesVO.class);

            String crewId = dsBoatCrewData.getId();

            // 获取 船员证件信息
            LambdaQueryWrapper<DsCrewCredential> dsCrewCredentialWrapper = new LambdaQueryWrapper<>();
            dsCrewCredentialWrapper.eq(DsCrewCredential::getCrewId, crewId)
                    // 按照证书截至日期倒叙排列
                    .orderByDesc(DsCrewCredential::getCertificateExpiredDate);
            List<DsCrewCredential> dsCrewCredentialList = dsCrewCredentialService.list(dsCrewCredentialWrapper);
            if (CollectionUtils.isNotEmpty(dsCrewCredentialList)) {
                dsBoatCrewArchivesVO.setDsCrewCredentialList(dsCrewCredentialList);
            }

            // 船员出港记录
            LambdaQueryWrapper<DsCrewOutCheck> dsCrewOutCheckWrapper = new LambdaQueryWrapper<>();
            dsCrewOutCheckWrapper.eq(DsCrewOutCheck::getCrewId, crewId);
            List<DsCrewOutCheck> dsCrewOutCheckList = dsCrewOutCheckService.list(dsCrewOutCheckWrapper);
            if (CollectionUtils.isNotEmpty(dsCrewOutCheckList)) {
                dsBoatCrewArchivesVO.setDsCrewOutCheckList(dsCrewOutCheckList);
            }
            // 船员入港记录
            LambdaQueryWrapper<DsCrewEnterCheck> dsCrewEnterCheckWrapper = new LambdaQueryWrapper<>();
            dsCrewEnterCheckWrapper.eq(DsCrewEnterCheck::getCrewId, crewId);
            List<DsCrewEnterCheck> dsCrewEnterCheckList = dsCrewEnterCheckService.list(dsCrewEnterCheckWrapper);
            if (CollectionUtils.isNotEmpty(dsCrewEnterCheckList)) {
                dsBoatCrewArchivesVO.setDsCrewEnterCheckList(dsCrewEnterCheckList);
            }
        }
        return AjaxResult.success(dsBoatCrewArchivesVO);
    }

    /**
     * 分页查询船员数据优化
     *
     * @param dto：
     * @return java.util.List<com.ltgk.crew.domain.vo.DsBoatBindCrewInfoVO>
     * @author Qi ChengBin
     * @date 2025/3/4
     */
    @Override
    public List<DsBoatCrew> selectByPageNew(DsBoatCrewDTO dto) {
        dto.queryCheck();
        DsBoatCrew dsBoatCrew = new DsBoatCrew();
        BeanUtils.copyProperties(dto, dsBoatCrew);

        String startTime = dto.getStartTime();
        String endTime = dto.getEndTime();
        boolean timeNoteBlank = StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime);

        LambdaQueryWrapper<DsBoatCrew> wrapper = new LambdaQueryWrapper<>(dsBoatCrew);
        wrapper.between(timeNoteBlank, DsBoatCrew::getUpdateAt, startTime, endTime)
                .orderByDesc(DsBoatCrew::getUpdateAt);
        startPage(dto.getPageNum(), dto.getPageSize());

        return this.list(wrapper);
    }

}
