package com.yeejoin.amos.boot.module.common.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.module.common.api.dto.DutyCarDto;
import com.yeejoin.amos.boot.module.common.api.dto.LinkageUnitZhDto;
import com.yeejoin.amos.boot.module.common.api.dto.RequestData;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormColumn;
import com.yeejoin.amos.boot.module.common.api.entity.DynamicFormInstance;
import com.yeejoin.amos.boot.module.common.api.entity.LinkageUnit;
import com.yeejoin.amos.boot.module.common.api.entity.SourceFile;
import com.yeejoin.amos.boot.module.common.api.mapper.DynamicFormInstanceMapper;
import com.yeejoin.amos.boot.module.common.api.mapper.LinkageUnitMapper;
import com.yeejoin.amos.boot.module.common.api.service.ILinkageUnitService;
import com.yeejoin.amos.boot.module.common.api.dto.LinkageUnitDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 联动单位服务实现类
 *
 * @author system_generator
 * @date 2021-07-16
 */
@Service
public class LinkageUnitServiceImpl extends BaseService<LinkageUnitDto, LinkageUnit, LinkageUnitMapper> implements ILinkageUnitService {

    @Autowired
    DynamicFormInstanceServiceImpl dynamicFormInstanceService;

    @Resource
    LinkageUnitMapper linkageUnitMapper;
    @Autowired
    DynamicFormColumnServiceImpl dynamicFormColumnService;
    @Autowired
    SourceFileServiceImpl sourceFileServiceImpl;

    public String getGroupCode() {
        return "linkageUnit";
    }

    /**
     * 分页查询
     */
    @Override
    public Page<LinkageUnitDto> queryForLinkageUnitPage(Page<LinkageUnitDto> page,
                                                        @Condition(Operator.eq) Boolean isDelete,
                                                        @Condition(Operator.like) String unitName,
                                                        @Condition(Operator.eq) String linkageUnitType) {
        return this.queryForPage(page, null, false, isDelete, unitName, linkageUnitType);
    }

    /**
     * 列表查询 示例
     */
    public List<LinkageUnitDto> queryForLinkageUnitList(@Condition(Operator.eq) Boolean isDelete) {
        return this.queryForList("", false, isDelete);
    }

    /**
     * 保存联动单位
     *
     * @param linkageUnitDto 对象
     * @return List<LinkageUnitDto>
     */
    @Transactional
    public LinkageUnitDto saveModel(LinkageUnitDto linkageUnitDto) {
        //1.保存行数据
        String groupCode = this.getGroupCode();
        Map<String, Object> map = Bean.BeantoMap(linkageUnitDto);
        Long instanceId = dynamicFormInstanceService.commonSave(groupCode, map);
        linkageUnitDto.setInstanceId(instanceId);
        //2.保存基本信息
        linkageUnitDto.setUnitCode(getUnitCodeStr());
        LinkageUnitDto model = createWithModel(linkageUnitDto);
        //3.保存照片信息
        sourceFileServiceImpl.saveSourceFile(model.getSequenceNbr(), model.getImage());
        //3.返回保存后的数据
        return model;
    }

    @Override
    public LinkageUnitDto queryOne(Long sequenceNbr) {
        String groupCode = getGroupCode();
        List<DynamicFormColumn> columns =
                dynamicFormColumnService.list(new LambdaQueryWrapper<DynamicFormColumn>().eq(DynamicFormColumn::getGroupCode, groupCode));
        Map<String, Object> fieldCodes = Bean.listToMap(columns, "fieldCode", "queryStrategy", DynamicFormColumn.class);
        LinkageUnitDto linkageUnitDto = linkageUnitMapper.selectOne(false, fieldCodes, groupCode, sequenceNbr);
        List<SourceFile> sourceFiles = sourceFileServiceImpl.findBySourceId(linkageUnitDto.getSequenceNbr());
        linkageUnitDto.setImage(sourceFiles);
        return linkageUnitDto;
    }

    @Transactional
    public Boolean deleteById(Long sequenceNbr) {
        // 删除基本信息
        LinkageUnit linkageUnit = getById(sequenceNbr);
        linkageUnit.setIsDelete(true);
        updateById(linkageUnit);
        // 删除行
        Long instanceId = linkageUnit.getInstanceId();
        List<DynamicFormInstance> dynamicFormInstanceList =
                dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
        dynamicFormInstanceList.forEach(item -> item.setIsDelete(true));
        boolean update = dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
        // 删除照片
        sourceFileServiceImpl.saveSourceFile(sequenceNbr, new ArrayList<>());
        return update;
    }

    @Transactional
    public LinkageUnitDto updateById(LinkageUnitDto linkageUnitDto) {
        // 修改基本信息
        updateWithModel(linkageUnitDto);
        // 修改行信息
        Long instanceId = linkageUnitDto.getInstanceId();
        List<DynamicFormInstance> dynamicFormInstanceList =
                dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().eq(DynamicFormInstance::getInstanceId, instanceId));
        Map<String, Object> objectMap = Bean.BeantoMap(linkageUnitDto);
        dynamicFormInstanceList.forEach(item -> item.setFieldValue(objectMap.get(item.getFieldCode()) != null ?
                objectMap.get(item.getFieldCode()).toString() : item.getFieldValue()));
        dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
        // 修改照片信息
        sourceFileServiceImpl.saveSourceFile(linkageUnitDto.getSequenceNbr(), linkageUnitDto.getImage());
        return linkageUnitDto;
    }

    public static String getUnitCodeStr() {
        int length = 6;
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(str.charAt(number));
        }
        return sb.toString();
    }

    @Override
    public List<LinkageUnitZhDto> listLinkageUnitZhDto(Integer pageNum, Integer pageSize, RequestData par) {
        if (null == pageNum || null == pageSize) {
            pageNum = 1;
            pageSize = Integer.MAX_VALUE;
        } else {
            pageNum = (pageNum - 1) * pageSize;
        }
        return linkageUnitMapper.listLinkageUnitZhDto(pageNum, pageSize, par);
    }

    @Override
    public Integer listLinkageUnitZhDtoCount(RequestData par) {
        return linkageUnitMapper.listLinkageUnitZhDtoCount(par);
    }

    /**
     * 批量删除
     *
     * @param sequenceNbrList
     * @return
     */
    public Boolean batchDelete(List<Long> sequenceNbrList) {
        // 删除基本信息
        List<LinkageUnit> linkageUnitList = list(new LambdaQueryWrapper<LinkageUnit>().in(LinkageUnit::getSequenceNbr,
                sequenceNbrList));
        List<Long> instanceIdList = Lists.newArrayList();
        linkageUnitList.forEach(item -> {
            instanceIdList.add(item.getInstanceId());
            item.setIsDelete(true);
        });
        updateBatchById(linkageUnitList);
        // 删除行信息
        List<DynamicFormInstance> dynamicFormInstanceList =
                dynamicFormInstanceService.list(new LambdaQueryWrapper<DynamicFormInstance>().in(DynamicFormInstance::getInstanceId, instanceIdList));
        dynamicFormInstanceList.forEach(item -> item.setIsDelete(true));
        boolean update = dynamicFormInstanceService.updateBatchById(dynamicFormInstanceList);
        // 删除照片
        sourceFileServiceImpl.getBaseMapper().delete(new LambdaQueryWrapper<SourceFile>().in(SourceFile::getSourceId,
                sequenceNbrList));
        return update;
    }
}