package com.xjrsoft.module.material.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.enums.MaterialCategoryEnum;
import com.xjrsoft.common.page.ConventPage;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.form.entity.FormRelease;
import com.xjrsoft.module.form.entity.FormTemplate;
import com.xjrsoft.module.form.service.IFormTemplateService;
import com.xjrsoft.module.material.dto.MaterialTypePageDto;
import com.xjrsoft.module.material.entity.MaterialType;
import com.xjrsoft.module.material.entity.MaterialTypeAssign;
import com.xjrsoft.module.material.mapper.MaterialTypeAssignMapper;
import com.xjrsoft.module.material.mapper.MaterialTypeMapper;
import com.xjrsoft.module.material.service.IMaterialTypeService;
import com.xjrsoft.module.material.vo.MaterialTaskAssignListVo;
import com.xjrsoft.module.material.vo.MaterialTypePageVo;
import com.xjrsoft.module.material.vo.MaterialTypeVo;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.system.service.IFileService;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* @title: 材料提交任务类型
* @Author baicai
* @Date: 2023-10-31
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class MaterialTypeServiceImpl extends MPJBaseServiceImpl<MaterialTypeMapper, MaterialType> implements IMaterialTypeService {
    private final MaterialTypeMapper materialTypeMaterialTypeMapper;

    private final MaterialTypeAssignMapper materialTypeMaterialTypeAssignMapper;

    private final IFileService fileService;

    private final IFormTemplateService formTemplateService;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(MaterialType materialType) {
        materialTypeMaterialTypeMapper.insert(materialType);
//        for (MaterialTypeAssign materialTypeAssign : materialType.getMaterialTypeAssignList()) {
//            materialTypeAssign.setMaterialTypeId(materialType.getId());
//            materialTypeMaterialTypeAssignMapper.insert(materialTypeAssign);
//        }

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(MaterialType materialType) {
        materialTypeMaterialTypeMapper.updateById(materialType);
        //********************************* MaterialTypeAssign  增删改  开始 *******************************************/
//        {
            // 查出所有子级的id
//            List<MaterialTypeAssign> materialTypeAssignList = materialTypeMaterialTypeAssignMapper.selectList(Wrappers.lambdaQuery(MaterialTypeAssign.class).eq(MaterialTypeAssign::getMaterialTypeId, materialType.getId()).select(MaterialTypeAssign::getId));
//            List<Long> materialTypeAssignIds = materialTypeAssignList.stream().map(MaterialTypeAssign::getId).collect(Collectors.toList());
//            //原有子表单 没有被删除的主键
//            List<Long> materialTypeAssignOldIds = materialType.getMaterialTypeAssignList().stream().map(MaterialTypeAssign::getId).filter(Objects::nonNull).collect(Collectors.toList());
//            //找到需要删除的id
//            List<Long> materialTypeAssignRemoveIds = materialTypeAssignIds.stream().filter(item -> !materialTypeAssignOldIds.contains(item)).collect(Collectors.toList());
//
//            for (MaterialTypeAssign materialTypeAssign : materialType.getMaterialTypeAssignList()) {
//                //如果不等于空则修改
//                if (materialTypeAssign.getId() != null) {
//                    materialTypeMaterialTypeAssignMapper.updateById(materialTypeAssign);
//                }
//                //如果等于空 则新增
//                else {
//                    //已经不存在的id 删除
//                    materialTypeAssign.setMaterialTypeId(materialType.getId());
//                    materialTypeMaterialTypeAssignMapper.insert(materialTypeAssign);
//                }
//            }
//            //已经不存在的id 删除
//            if(materialTypeAssignRemoveIds.size() > 0){
//                materialTypeMaterialTypeAssignMapper.deleteBatchIds(materialTypeAssignRemoveIds);
//            }
//        }
        //********************************* MaterialTypeAssign  增删改  结束 *******************************************/

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> ids) {
        materialTypeMaterialTypeMapper.deleteBatchIds(ids);
        materialTypeMaterialTypeAssignMapper.delete(Wrappers.lambdaQuery(MaterialTypeAssign.class).in(MaterialTypeAssign::getMaterialTypeId, ids));

        return true;
    }

    @Override
    public PageOutput<MaterialTypePageVo> getPage(MaterialTypePageDto dto) {
        LambdaQueryWrapper<MaterialType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .orderByDesc(MaterialType::getId)
                .select(MaterialType.class,x -> VoToColumnUtil.fieldsToColumns(MaterialTypePageVo.class).contains(x.getProperty()))
                .like(dto.getName() != null && !dto.getName().equals(""), MaterialType::getName, dto.getName())
                .eq(dto.getMaterialCategory() != null && !dto.getMaterialCategory().equals(""), MaterialType::getMaterialCategory, dto.getMaterialCategory());
        IPage<MaterialType> page = this.page(ConventPage.getPage(dto), queryWrapper);
        PageOutput<MaterialTypePageVo> pageOutput = ConventPage.getPageOutput(page, MaterialTypePageVo.class);

        for (MaterialTypePageVo materialTypePageVo : pageOutput.getList()){
            String materialCategoryStr = materialTypePageVo.getMaterialCategory();
            String[] materialCategoryStrArr = materialCategoryStr.split(",");

            for (String category : materialCategoryStrArr) {
                if (category != null) {
                    String categoryValue = MaterialCategoryEnum.getValue(category);
                    if (categoryValue != null) {
                        if (materialTypePageVo.getMaterialCategoryCn() != null && materialTypePageVo.getMaterialCategoryCn().length() > 0) {
                            materialTypePageVo.setMaterialCategoryCn(materialTypePageVo.getMaterialCategoryCn() + "，" + categoryValue);
                        } else {
                            materialTypePageVo.setMaterialCategoryCn(categoryValue);
                        }
                        handleFileAndTemplate(materialTypePageVo, category);
                    }
                }
            }
        }
        return pageOutput;
    }

    @Override
    public MaterialTypeVo getInfoById(Long id) {
        LambdaQueryWrapper<MaterialType> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .orderByDesc(MaterialType::getId)
                .select(MaterialType.class,x -> VoToColumnUtil.fieldsToColumns(MaterialTypeVo.class).contains(x.getProperty()))
                .eq(MaterialType::getId, id);
        MaterialType materialType = this.getOne(queryWrapper);

        MaterialTypeVo materialTypeVo = BeanUtil.toBean(materialType, MaterialTypeVo.class);

        String materialCategoryStr = materialTypeVo.getMaterialCategory();
        String[] materialCategoryStrArr = materialCategoryStr.split(",");

        for (String category : materialCategoryStrArr) {
            if (category != null) {
                String categoryValue = MaterialCategoryEnum.getValue(category);
                if (categoryValue != null) {
                    if (materialTypeVo.getMaterialCategoryCn() != null && materialTypeVo.getMaterialCategoryCn().length() > 0) {
                        materialTypeVo.setMaterialCategoryCn(materialTypeVo.getMaterialCategoryCn() + "，" + categoryValue);
                    } else {
                        materialTypeVo.setMaterialCategoryCn(categoryValue);
                    }

                    if (MaterialCategoryEnum.MT0001.getCode().equals(category) && materialTypeVo.getFolderId() != null) {
                        List<File> files = getFileListByFolderId(materialTypeVo.getFolderId());
                        if (!files.isEmpty()) {
                            materialTypeVo.setFiles(files);
                            materialTypeVo.setFolderIdCn(files.get(0).getFileName());
                            if (materialTypeVo.getTemplatePreview() != null && materialTypeVo.getTemplatePreview().length() > 0) {
                                materialTypeVo.setTemplatePreview(materialTypeVo.getTemplatePreview() + "，" + files.get(0).getFileName());
                            } else {
                                materialTypeVo.setTemplatePreview(files.get(0).getFileName());
                            }
                        }
                    } else if (MaterialCategoryEnum.MT0002.getCode().equals(category) && materialTypeVo.getFormReleaseId() != null) {
                        FormTemplate formTemplate = getFormTemplateById(materialTypeVo.getFormReleaseId());
                        if (formTemplate != null) {
                            String templateName = formTemplate.getName();
                            materialTypeVo.setFormReleaseIdCn(templateName);
                            if (materialTypeVo.getTemplatePreview() != null && materialTypeVo.getTemplatePreview().length() > 0) {
                                materialTypeVo.setTemplatePreview(materialTypeVo.getTemplatePreview() + "，" + templateName);
                            } else {
                                materialTypeVo.setTemplatePreview(templateName);
                            }
                        }
                    }
                }
            }
        }

        return materialTypeVo;
    }

    @Override
    public List<MaterialTypeVo> listMaterialTypeVo() {
        List<MaterialTypeVo> pageOutput = this.selectJoinList(MaterialTypeVo.class, new MPJLambdaWrapper<MaterialType>()
                        .disableSubLogicDel()
                        //.eq(MaterialTypeAssign::getUserId, StpUtil.getLoginIdAsLong())
                        .select(MaterialType::getId)
                        .select(MaterialType.class,x -> VoToColumnUtil.fieldsToColumns(MaterialTypeVo.class).contains(x.getProperty()))
                //.innerJoin(MaterialTypeAssign.class, MaterialTypeAssign::getMaterialTypeId, MaterialType::getId)
        );

        for(MaterialTypeVo materialTypeVo : pageOutput){
            String materialCategoryStr = materialTypeVo.getMaterialCategory();
            if(StrUtil.isEmpty(materialCategoryStr)){
                continue;
            }
            String[] materialCategoryStrArr = materialCategoryStr.split(",");

            for (String category : materialCategoryStrArr) {
                if (category != null) {
                    String categoryValue = MaterialCategoryEnum.getValue(category);
                    if (categoryValue != null) {
                        if (materialTypeVo.getMaterialCategoryCn() != null && materialTypeVo.getMaterialCategoryCn().length() > 0) {
                            materialTypeVo.setMaterialCategoryCn(materialTypeVo.getMaterialCategoryCn() + "，" + categoryValue);
                        } else {
                            materialTypeVo.setMaterialCategoryCn(categoryValue);
                        }

                        handleFileAndTemplate(materialTypeVo, category);
                    }
                }
            }
        }
        return pageOutput;
    }

    private void handleFileAndTemplate(MaterialTypeVo materialTypeVo, String category) {
        MaterialTypePageVo materialTypePageVo = new MaterialTypePageVo();
        BeanUtils.copyProperties(materialTypeVo, materialTypePageVo);
        handleFileAndTemplate(materialTypePageVo, category);
        BeanUtils.copyProperties(materialTypePageVo, materialTypeVo);
    }

    public void handleFileAndTemplate(MaterialTaskAssignListVo materialTaskAssignListVo, String category) {
        MaterialTypePageVo materialTypePageVo = new MaterialTypePageVo();
        BeanUtils.copyProperties(materialTaskAssignListVo, materialTypePageVo);
        handleFileAndTemplate(materialTypePageVo, category);
        BeanUtils.copyProperties(materialTypePageVo, materialTaskAssignListVo);
    }

    private void handleFileAndTemplate(MaterialTypePageVo materialTypePageVo, String category) {
        if (MaterialCategoryEnum.MT0001.getCode().equals(category) && materialTypePageVo.getFolderId() != null) {
            List<File> files = getFileListByFolderId(materialTypePageVo.getFolderId());
            if (!files.isEmpty()) {
                materialTypePageVo.setFiles(files);
                materialTypePageVo.setFolderIdCn(files.get(0).getFileName());
                if (materialTypePageVo.getTemplatePreview() != null && materialTypePageVo.getTemplatePreview().length() > 0) {
                    materialTypePageVo.setTemplatePreview(materialTypePageVo.getTemplatePreview() + "，" + files.get(0).getFileName());
                } else {
                    materialTypePageVo.setTemplatePreview(files.get(0).getFileName());
                }
            }
        } else if (MaterialCategoryEnum.MT0002.getCode().equals(category) && materialTypePageVo.getFormReleaseId() != null) {
            FormTemplate formTemplate = getFormTemplateById(materialTypePageVo.getFormReleaseId());
            if (formTemplate != null) {
                String templateName = formTemplate.getName();
                materialTypePageVo.setFormReleaseIdCn(templateName);
                if (materialTypePageVo.getTemplatePreview() != null && materialTypePageVo.getTemplatePreview().length() > 0) {
                    materialTypePageVo.setTemplatePreview(materialTypePageVo.getTemplatePreview() + "，" + templateName);
                } else {
                    materialTypePageVo.setTemplatePreview(templateName);
                }
            }
        }
    }

    private List<File> getFileListByFolderId(Long folderId) {
        return fileService.list(Wrappers.<File>query().lambda().eq(File::getFolderId, folderId));
    }

    private FormTemplate getFormTemplateById(Long formReleaseId) {
        LambdaQueryWrapper<FormTemplate> formTemplateLambdaQueryWrapper = new LambdaQueryWrapper<>();
        formTemplateLambdaQueryWrapper
                .orderByDesc(FormTemplate::getSortCode)
                .select(FormTemplate.class, x -> VoToColumnUtil.fieldsToColumns(FormTemplate.class).contains(x.getProperty()))
                .eq(FormTemplate::getId, formReleaseId);
        return formTemplateService.getOne(formTemplateLambdaQueryWrapper);
    }
}
