package jnpf.personnels.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import jnpf.model.enums.FormFieldType;
import jnpf.model.personnels.dto.staff.field.EditFormFieldDto;
import jnpf.model.personnels.dto.staff.field.FtbPersonnelsRegistrationFormFieldDto;
import jnpf.model.personnels.dto.staff.field.FtbPersonnelsRegistrationFormFieldOptionDto;
import jnpf.model.personnels.dto.staff.field.FtbPersonnelsRegistrationFormTypeDto;
import jnpf.model.personnels.po.FtbPersonnelsRegistrationFormField;
import jnpf.model.personnels.po.FtbPersonnelsRegistrationFormFieldOption;
import jnpf.model.personnels.po.FtbPersonnelsRegistrationFormType;
import jnpf.model.personnels.po.FtbPersonnelsStaffRegistrationFormData;
import jnpf.model.personnels.req.field.QueryRegistrationFormFieldListReq;
import jnpf.model.personnels.req.field.SaveRegistrationFormFieldOptionReq;
import jnpf.model.personnels.req.field.SaveRegistrationFormFieldReq;
import jnpf.personnels.mapper.FtbPersonnelsRegistrationFormFieldMapper;
import jnpf.personnels.mapper.FtbPersonnelsStaffRegistrationFormDataMapper;
import jnpf.personnels.service.FtbPersonnelsRegistrationFormFieldOptionService;
import jnpf.personnels.service.FtbPersonnelsRegistrationFormFieldService;
import jnpf.personnels.service.FtbPersonnelsRegistrationFormTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class FtbPersonnelsRegistrationFormFieldServiceImpl extends ServiceImpl<FtbPersonnelsRegistrationFormFieldMapper, FtbPersonnelsRegistrationFormField> implements FtbPersonnelsRegistrationFormFieldService {

    @Autowired
    private FtbPersonnelsRegistrationFormFieldOptionService fieldOptionService;

    @Autowired
    private FtbPersonnelsRegistrationFormTypeService formTypeService;

    @Autowired
    private FtbPersonnelsStaffRegistrationFormDataMapper ftbPersonnelsStaffRegistrationFormDataMapper;

    @Override
    public PageInfo<FtbPersonnelsRegistrationFormFieldDto> getPageList(QueryRegistrationFormFieldListReq req) {
        Page<FtbPersonnelsRegistrationFormFieldDto> queryPage = baseMapper.pagingQuery(Page.of(req.getCurrentPage(), req.getPageSize()), req);
        List<FtbPersonnelsRegistrationFormFieldDto> records = queryPage.getRecords();
        if (CollectionUtil.isNotEmpty(records)) {
            List<FtbPersonnelsRegistrationFormTypeDto> formTypeDtoList = formTypeService.listAll(null);
            if (CollectionUtil.isNotEmpty(formTypeDtoList)) {
                Map<String, FtbPersonnelsRegistrationFormTypeDto> formTypeMap = formTypeDtoList.stream().collect(Collectors.toMap(FtbPersonnelsRegistrationFormTypeDto::getId, Function.identity()));
                for (FtbPersonnelsRegistrationFormFieldDto record : records) {
                    FtbPersonnelsRegistrationFormTypeDto formTypeDto = formTypeMap.get(record.getFormTypeId());
                    if (null != formTypeDto) {
                        record.setFormTypeName(formTypeDto.getName());
                    }
                }
            }

        }
        //构建分页返回数据
        PageInfo<FtbPersonnelsRegistrationFormFieldDto> pageInfo = new PageInfo<>();
        pageInfo.setList(records);
        pageInfo.setPageSize((int) queryPage.getSize());
        pageInfo.setPageNum((int) queryPage.getCurrent());
        pageInfo.setTotal((int) queryPage.getTotal());
        return pageInfo;
    }

    @Override
    public EditFormFieldDto getInfo(String id) {
        FtbPersonnelsRegistrationFormFieldDto dto = queryAndCheckFormField(id);
        //查询字段类别名称
        EditFormFieldDto fieldDto = BeanUtil.copyProperties(dto, EditFormFieldDto.class);
        //查询类别名称
        FtbPersonnelsRegistrationFormType typeEntity = formTypeService.getById(dto.getFormTypeId());
        if (null != typeEntity) {
            fieldDto.setFieldTypeName(typeEntity.getName());
        }
        //查询选项
        if (fieldDto.getType().equals(2) || fieldDto.getType().equals(3)) {
            QueryWrapper<FtbPersonnelsRegistrationFormFieldOption> wrapper = new QueryWrapper<>();
            wrapper.lambda()
                    .eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId, dto.getId())
                    .eq(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 0).orderByAsc(FtbPersonnelsRegistrationFormFieldOption::getId);
            List<FtbPersonnelsRegistrationFormFieldOption> optionList = fieldOptionService.list(wrapper);
            if (CollectionUtil.isNotEmpty(optionList)) {
                List<FtbPersonnelsRegistrationFormFieldOptionDto> optionDtoList = BeanUtil.copyToList(optionList, FtbPersonnelsRegistrationFormFieldOptionDto.class);
                fieldDto.setOptionDtoList(optionDtoList);
            }
        }
        return fieldDto;
    }

    private FtbPersonnelsRegistrationFormFieldDto queryAndCheckFormField(String id) {

        FtbPersonnelsRegistrationFormField entity = baseMapper.selectById(id);
        if (entity == null) {
            throw new RuntimeException("该字段不存在");
        }
        if (entity.getEnabledMark().equals(1)) {
            throw new RuntimeException("该字段已经删除");
        }
        FtbPersonnelsRegistrationFormFieldDto dto = BeanUtil.copyProperties(entity, FtbPersonnelsRegistrationFormFieldDto.class);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insertData(SaveRegistrationFormFieldReq req) {
        //检测名称是否重复
        QueryWrapper<FtbPersonnelsRegistrationFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsRegistrationFormField::getName, req.getName())
                .eq(FtbPersonnelsRegistrationFormField::getEnabledMark, 0);
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("字段名称已经存在");
        }
        //添加
        FtbPersonnelsRegistrationFormField entity = BeanUtil.copyProperties(req, FtbPersonnelsRegistrationFormField.class);
        entity.setIsUpdateManager(0);
        entity.setAllowNeedFill(0);
        entity.setSystemType(1);//0、系统类型 1、自定义类型
        entity.setIsAllowStop(0);
        entity.setIsRegisterFormShow(0);
        entity.setSorts(System.currentTimeMillis() / 1000);
        // 类型：0、单行文本 1、多行文本 2、单选  3、多选 4、日期 5、附件  6、图片  7、整数 8、小数
        // 单行文本上限20字  多行文本上限500字   附件上限10个单个不超过500m   图片上限10张单个不超过500m
        if (req.getType() == 2 || req.getType() == 3) {
            entity.setOptionType(1);
        }
        if (req.getType() == 0) {
            entity.setLimits(20L);
        } else if (req.getType() == 1) {
            entity.setLimits(500L);
        } else if (req.getType() == 5 || req.getType() == 6) {
            entity.setLimits(10L);
            entity.setFileSize(500);
        }
        baseMapper.insert(entity);

        //如果是单选和多选 就写入选项
        FormFieldType formFieldType = FormFieldType.fromCode(req.getType());
        if (FormFieldType.RADIO_BUTTON == formFieldType || FormFieldType.CHECK_BOX == formFieldType) {
            List<SaveRegistrationFormFieldOptionReq> optionList = req.getOptionList();
            if(CollectionUtil.isEmpty(optionList)){
                throw new RuntimeException("选择类型的字段的选项不能为空");
            }
            if (CollectionUtil.isNotEmpty(optionList)) {
                List<FtbPersonnelsRegistrationFormFieldOption> optionEntityList = new ArrayList<>();
                for (SaveRegistrationFormFieldOptionReq option : optionList) {
                    FtbPersonnelsRegistrationFormFieldOption optionEntity = new FtbPersonnelsRegistrationFormFieldOption();
                    optionEntity.setFormFieldId(entity.getId());
                    optionEntity.setName(option.getName());
                    optionEntity.setEnabledMark(0);
                    optionEntityList.add(optionEntity);
                }
                if (CollectionUtil.isNotEmpty(optionEntityList)) {
                    fieldOptionService.saveBatch(optionEntityList);
                }
            }
        }

        return entity.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateData(SaveRegistrationFormFieldReq req) {

        //检测重复
        QueryWrapper<FtbPersonnelsRegistrationFormField> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbPersonnelsRegistrationFormField::getName, req.getName())
                .ne(FtbPersonnelsRegistrationFormField::getId, req.getId())
                .eq(FtbPersonnelsRegistrationFormField::getEnabledMark, 0);
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("字段名称已经存在");
        }

        FtbPersonnelsRegistrationFormFieldDto dto = queryAndCheckFormField(req.getId());
        if (dto.getSystemType().equals(0)) {
            throw new RuntimeException("系统字段不能够编辑");
        }

        //修改
        FtbPersonnelsRegistrationFormField entity = BeanUtil.copyProperties(req, FtbPersonnelsRegistrationFormField.class);
        entity.setId(req.getId());
        // 类型：0、单行文本 1、多行文本 2、单选  3、多选 4、日期 5、附件  6、图片  7、整数 8、小数
        // 单行文本上限20字  多行文本上限500字   附件上限10个单个不超过500m   图片上限10张单个不超过500m
        if (req.getType() == 2 || req.getType() == 3) {
            entity.setOptionType(1);
        }
        if (req.getType() == 0) {
            entity.setLimits(20L);
        } else if (req.getType() == 1) {
            entity.setLimits(500L);
        } else if (req.getType() == 5 || req.getType() == 6) {
            entity.setLimits(10L);
            entity.setFileSize(500);
        }
        baseMapper.updateById(entity);

        //修改选项
        FormFieldType formFieldType = FormFieldType.fromCode(req.getType());
        if (FormFieldType.RADIO_BUTTON == formFieldType || FormFieldType.CHECK_BOX == formFieldType) {
            //查询已经存在的选项
            List<FtbPersonnelsRegistrationFormFieldOption> exiestOptionList = fieldOptionService.queryOptionsByFieldId(req.getId());

            List<SaveRegistrationFormFieldOptionReq> optionList = req.getOptionList();
            if(CollectionUtil.isEmpty(optionList)){
                throw new RuntimeException("选择类型的字段的选项不能为空");
            }
            //修改的idlist
            Set<String> editSet = new HashSet<>();
            //添加的列表
            List<FtbPersonnelsRegistrationFormFieldOption> addAndUpdateList = new ArrayList<>();
            for (SaveRegistrationFormFieldOptionReq optionReq : optionList) {
                FtbPersonnelsRegistrationFormFieldOption optionEntity = new FtbPersonnelsRegistrationFormFieldOption();
                optionEntity.setName(optionReq.getName());
                optionEntity.setFormFieldId(req.getId());
                if (StringUtils.isNotEmpty(optionReq.getId())) {
                    optionEntity.setId(optionReq.getId());
                    editSet.add(optionReq.getId());
                }
                addAndUpdateList.add(optionEntity);
            }
            //删除已经存在但是没有在请求列表中的
            if (CollectionUtil.isNotEmpty(exiestOptionList)) {
                List<String> delList = new ArrayList<>();
                exiestOptionList.forEach(exiestOption -> {
                    if (!editSet.contains(exiestOption.getId())) {
                        delList.add(exiestOption.getId());
                    }
                });
                if (CollectionUtil.isNotEmpty(delList)) {
                    deleteFieldOptionByIds(delList);
                }

            }
            //添加修改
            fieldOptionService.saveOrUpdateBatch(addAndUpdateList);
        }
        //如果字段类型发送变化就清除已有数据
        if(!dto.getType().equals(req.getType())){
            UpdateWrapper<FtbPersonnelsStaffRegistrationFormData> formDataWrapper = new UpdateWrapper<>();
            formDataWrapper.lambda().set(FtbPersonnelsStaffRegistrationFormData::getValue, "")
                    .eq(FtbPersonnelsStaffRegistrationFormData::getFormFieldId, dto.getId());
            ftbPersonnelsStaffRegistrationFormDataMapper.update(null,formDataWrapper);
        }
    }

    private void deleteFieldOptionByIds(List<String> delList) {
        UpdateWrapper<FtbPersonnelsRegistrationFormFieldOption> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 1)
                .in(FtbPersonnelsRegistrationFormFieldOption::getId, delList);
        fieldOptionService.update(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteData(String id) {
        FtbPersonnelsRegistrationFormFieldDto dto = queryAndCheckFormField(id);
        if (dto.getSystemType().equals(0)) {
            throw new RuntimeException("系统字段不允许删除");
        }
        if (dto.getStatus().equals(0)) {
            throw new RuntimeException("该字段启用中,不能删除");
        }
        //删除字段
        FtbPersonnelsRegistrationFormField entity = new FtbPersonnelsRegistrationFormField();
        entity.setId(id);
        entity.setEnabledMark(1);
        baseMapper.updateById(entity);
        //删除字段选项
        FormFieldType formFieldType = FormFieldType.fromCode(dto.getType());
        if (FormFieldType.RADIO_BUTTON == formFieldType || FormFieldType.CHECK_BOX == formFieldType) {
            deleteFieldOptionByFieldId(id);
        }
    }

    /**
     * 根据字段ID 删除字段选项
     *
     * @param fieldId
     */
    private void deleteFieldOptionByFieldId(String fieldId) {
        UpdateWrapper<FtbPersonnelsRegistrationFormFieldOption> wrapper = new UpdateWrapper<>();
        wrapper.lambda().set(FtbPersonnelsRegistrationFormFieldOption::getEnabledMark, 1)
                .eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId, fieldId);
        fieldOptionService.update();
    }

    @Override
    public void switchStatus(String id, Integer status) {
        FtbPersonnelsRegistrationFormFieldDto dto = queryAndCheckFormField(id);
        if (dto.getIsAllowStop().equals(1)) {
            if (status == 1) {
                throw new RuntimeException("该字段不允许被停用");
            }
        }
        FtbPersonnelsRegistrationFormField entity = new FtbPersonnelsRegistrationFormField();
        entity.setId(id);
        entity.setStatus(status);
        baseMapper.updateById(entity);
    }

    @Override
    public void switchNeedFill(String id, Integer status) {
        FtbPersonnelsRegistrationFormFieldDto dto = queryAndCheckFormField(id);
        if (dto.getAllowNeedFill().equals(1)) {
            if (status == 0) {
                throw new RuntimeException("该字段不允许切换成选填");
            }
        }
        FtbPersonnelsRegistrationFormField entity = new FtbPersonnelsRegistrationFormField();
        entity.setId(id);
        entity.setIsNeedFill(status);
        baseMapper.updateById(entity);
    }

    /**
     * 查询字段类型下的所有字段数量
     *
     * @param typeId 字段类型
     * @return
     */
    @Override
    public Long queryAllFieldNumForType(String typeId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<FtbPersonnelsRegistrationFormField>()
                .eq(FtbPersonnelsRegistrationFormField::getFormTypeId, typeId)
                .eq(FtbPersonnelsRegistrationFormField::getEnabledMark, 0));
    }

    /**
     * 查询字段类型下的可用字段数量
     *
     * @param typeId 字段类型
     * @return
     */
    @Override
    public Long queryEnableFieldNumForType(String typeId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<FtbPersonnelsRegistrationFormField>()
                .eq(FtbPersonnelsRegistrationFormField::getFormTypeId, typeId)
                .eq(FtbPersonnelsRegistrationFormField::getStatus, 0)
                .eq(FtbPersonnelsRegistrationFormField::getEnabledMark, 0));
    }

    @Override
    public FtbPersonnelsRegistrationFormField queryOneField(String field) {
        return baseMapper.selectById(field);
    }

    @Override
    @Transactional
    public void switchVisible(String id, Integer status) {
        LambdaUpdateWrapper<FtbPersonnelsRegistrationFormField> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(FtbPersonnelsRegistrationFormField::getId, id);
        updateWrapper.set(FtbPersonnelsRegistrationFormField::getIsVisibleWorker, status);
        baseMapper.update(new FtbPersonnelsRegistrationFormField(), updateWrapper);
    }

    @Override
    public List<Map<String,String>> queryFieldValue(String field, String workType) {
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormFieldOption> queryWrapper = Wrappers.lambdaQuery();
        LambdaQueryWrapper<FtbPersonnelsRegistrationFormField> query = Wrappers.lambdaQuery();
        query.eq(FtbPersonnelsRegistrationFormField::getName,field);
        queryWrapper.eq(FtbPersonnelsRegistrationFormFieldOption::getFormFieldId,baseMapper.selectOne(query).getId());
        List<FtbPersonnelsRegistrationFormFieldOption> list = fieldOptionService.list(queryWrapper);
        if("员工状态".equals(field)){
            // 试用和正式
            return list.stream().filter(v->v.getName().equals("正式")||v.getName().equals("试用"))
                    .map(v->{
                        Map<String,String> map = new HashMap<>();
                        map.put("name",v.getName());
                        map.put("id",v.getId());
                        return map;
                    }).collect(Collectors.toList());
        }
        if ("试用期".equals(field) && "303".equals(workType)){
            return  list.stream().filter(v->v.getName().equals("无试用期")).map(v->{
                Map<String,String> map = new HashMap<>();
                map.put("name",v.getName());
                map.put("id",v.getId());
                return map;
            }).collect(Collectors.toList());
        }
        if ("试用期".equals(field)){
            return  list.stream().filter(v->!v.getName().equals("无试用期")).map(v->{
                Map<String,String> map = new HashMap<>();
                map.put("name",v.getName());
                map.put("id",v.getId());
                return map;
            }).collect(Collectors.toList());
        }
        return list.stream().map(v->{
            Map<String,String> map = new HashMap<>();
            map.put("name",v.getName());
            map.put("id",v.getId());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void toggleWhetherYouCanModifyYourProfile(String id, Integer status) {
        LambdaUpdateWrapper<FtbPersonnelsRegistrationFormField> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(FtbPersonnelsRegistrationFormField::getId, id);
        updateWrapper.set(FtbPersonnelsRegistrationFormField::getIsUpdateWorker, status);
        baseMapper.update(new FtbPersonnelsRegistrationFormField(), updateWrapper);
    }

}
