package jnpf.personnels.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jnpf.base.entity.SuperBaseEntity;
import jnpf.model.personnels.dto.employeetype.FtbEmployeeTypeAddDTO;
import jnpf.model.personnels.dto.employeetype.FtbEmployeeTypeEditDTO;
import jnpf.model.personnels.po.FtbPersonnelsRegistrationFormFieldOption;
import jnpf.model.personnels.po.FtbPersonnelsStaffRoster;
import jnpf.model.personnels.vo.employeetype.FtbPersonnelsEmployeeTypeVO;
import jnpf.personnels.mapper.FtbPersonnelsRegistrationFormFieldOptionMapper;
import jnpf.personnels.mapper.FtbPersonnelsStaffRosterMapper;
import jnpf.personnels.service.FtbPersonnelsEmployeeTypeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class FtbPersonnelsEmployeeTypeServiceImpl implements FtbPersonnelsEmployeeTypeService {

    @Resource
    private FtbPersonnelsRegistrationFormFieldOptionMapper formFieldOptionMapper;

    @Resource
    private FtbPersonnelsStaffRosterMapper staffRosterMapper;

    private final static String WORKER_TYPE = "workerType";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEmployeeType(FtbEmployeeTypeAddDTO employeeType) {
        // 类型数量上限20个
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormFieldOption> query = new LambdaQueryWrapper<>();
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId, WORKER_TYPE);
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 0);
        if (formFieldOptionMapper.selectCount(query) > 20) {
            throw new RuntimeException("类型数量上限20个");
        }
        // 类型名称不能重复
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getName, employeeType.getName());
        if (formFieldOptionMapper.selectCount(query) > 0) {
            throw new RuntimeException("类型名称不能重复");
        }
        FtbPersonnelsRegistrationFormFieldOption option = new FtbPersonnelsRegistrationFormFieldOption();
        option.setName(employeeType.getName());
        option.setFormFieldId(WORKER_TYPE);
        option.setEnabledMark(0);
        formFieldOptionMapper.insert(option);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editEmployeeType(FtbEmployeeTypeEditDTO employeeType) {
        // 类型名称不能重复
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormFieldOption> query = new LambdaQueryWrapper<>();
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getName, employeeType.getName());
        query.ne(SuperBaseEntity.SuperIBaseEntity::getId, employeeType.getId());
        if (formFieldOptionMapper.selectCount(query) > 0) {
            throw new RuntimeException("类型名称不能重复");
        }
        LambdaUpdateWrapper<FtbPersonnelsRegistrationFormFieldOption> update = new LambdaUpdateWrapper<>();
        update.eq(SuperBaseEntity.SuperIBaseEntity::getId, employeeType.getId());
        update.set(FtbPersonnelsRegistrationFormFieldOption::getName, employeeType.getName());
        formFieldOptionMapper.update(new FtbPersonnelsRegistrationFormFieldOption(), update);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEmployeeType(String id) {
        // 校验该类型是否已关联员工，提示语:该类型已绑定员工，不可删除！
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> query = new LambdaQueryWrapper<>();
        query.eq(FtbPersonnelsStaffRoster::getWorkerType, id);
        query.eq(FtbPersonnelsStaffRoster::getEnabledMark, 0);
        if (staffRosterMapper.selectCount(query) > 0) {
            throw new RuntimeException("该类型已绑定员工，不可删除！");
        }
        LambdaUpdateWrapper<FtbPersonnelsRegistrationFormFieldOption> update = new LambdaUpdateWrapper<>();
        update.eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId, WORKER_TYPE);
        update.eq(SuperBaseEntity.SuperIBaseEntity::getId, id);
        update.set(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 1);
        formFieldOptionMapper.update(new FtbPersonnelsRegistrationFormFieldOption(), update);
    }

    @Override
    public List<FtbPersonnelsEmployeeTypeVO> employeeList() {
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormFieldOption> query = new LambdaQueryWrapper<>();
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 0);
        query.eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId, WORKER_TYPE);
        query.orderByAsc(SuperBaseEntity.SuperCBaseEntity::getCreatorTime);
        List<FtbPersonnelsRegistrationFormFieldOption> ftbPersonnelsRegistrationFormFieldOptions = formFieldOptionMapper.selectList(query);
        return ftbPersonnelsRegistrationFormFieldOptions
                .stream()
                .map(FtbPersonnelsEmployeeTypeVO::convert)
                .collect(Collectors.toList());
    }

    @Override
    public Map<String, FtbPersonnelsEmployeeTypeVO> getEmployeeTypeByUserIds(List<String> userIds) {
        LambdaQueryWrapper<FtbPersonnelsStaffRoster> query = new LambdaQueryWrapper<>();
        query.in(FtbPersonnelsStaffRoster::getUserId, userIds);
        List<FtbPersonnelsStaffRoster> ftbPersonnelsStaffRosters = staffRosterMapper.selectList(query);
        List<FtbPersonnelsEmployeeTypeVO> emtbPersonnelsEmployeeTypes = employeeList();
        Map<String, FtbPersonnelsEmployeeTypeVO> emtbPersonnelsEmployeeTypeMap = emtbPersonnelsEmployeeTypes
                .stream()
                .collect(Collectors.toMap(FtbPersonnelsEmployeeTypeVO::getId, a -> a));
        return ftbPersonnelsStaffRosters
                .stream()
                .collect(Collectors.toMap(FtbPersonnelsStaffRoster::getUserId,
                        a -> emtbPersonnelsEmployeeTypeMap.getOrDefault(a.getWorkerType(), new FtbPersonnelsEmployeeTypeVO())));
    }

}
