package com.keyware.shandan.browser.service;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.keyware.shandan.bianmu.entity.DataLabelsVo;
import com.keyware.shandan.bianmu.entity.DirectoryResource;
import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.mapper.DirectoryResourceMapper;
import com.keyware.shandan.bianmu.service.DataLabelsService;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.browser.entity.PageVo;
import com.keyware.shandan.browser.entity.SearchConditionVo;
import com.keyware.shandan.browser.entity.SearchResultSort;
import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
public class MetadataSearchService {

    @Autowired
    private DirectoryService directoryService;

    @Autowired
    private DirectoryResourceMapper directoryResourceMapper;

    @Autowired
    private DataLabelsService labelsService;

    public PageVo<DirectoryResource> searchByCondition(String directoryId, SearchConditionVo condition) {
        DirectoryVo parent = directoryService.getById(directoryId);
        Assert.notNull(parent, "资源目录未找到");
        QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(parent, condition);
        List<DataLabelsVo> labels = new ArrayList<>();
        condition.getConditions().stream().filter(item -> "markTag".equals(item.getFieldName())).findFirst().ifPresent(item -> {
            String tagIds = item.getFieldValue();
            labels.addAll(labelsService.listByIds(Arrays.asList(tagIds.split(","))));
        });
        labels.forEach(label -> label.setIdPath(label.getIdPath() + label.getId() + "/"));
        Page<DirectoryResource> page = directoryResourceMapper.customSelectPage(new Page<>(condition.getPage(), condition.getSize()), parent.getDirectoryPath() + "/", labels, queryWrapper);
        return PageVo.pageConvert(page);
    }

    public List<DirectoryResource> searchAllListByCondition(String directoryId, SearchConditionVo condition) {
        DirectoryVo parent = directoryService.getById(directoryId);
        Assert.notNull(parent, "资源目录未找到");
        QueryWrapper<DirectoryResource> queryWrapper = buildQueryWrapper(parent, condition);
        List<DataLabelsVo> labels = new ArrayList<>();
        condition.getConditions().stream().filter(item -> "markTag".equals(item.getFieldName())).findFirst().ifPresent(item -> {
            String tagIds = item.getFieldValue();
            labels.addAll(labelsService.listByIds(Arrays.asList(tagIds.split(","))));
        });
        labels.forEach(label -> label.setIdPath(label.getIdPath() + label.getId() + "/"));
        return directoryResourceMapper.customSelectList(parent.getDirectoryPath() + "/", labels, queryWrapper);
    }

    public QueryWrapper<DirectoryResource> buildQueryWrapper(DirectoryVo dir, SearchConditionVo condition) {
        QueryWrapper<DirectoryResource> queryWrapper = new QueryWrapper<>();

        queryWrapper.and(!condition.getConditions().isEmpty(), wrapper -> {
            StreamUtil.as(condition.getConditions()).forEach(item -> {
                switch (item.getFieldName()) {
                    case "inputDate":
                        if (StringUtils.hasText(item.getFieldValue())) {
                            String[] dates = item.getFieldValue().split("至");
                            wrapper.between("TASK_TIME", dates[0].trim(), dates[1].trim());
                        }
                        break;
                    case "dataFrom":
                        if ("nq".equals(item.getLogicJudgement())) {
                            wrapper.ne("DATA_SOURCE", item.getFieldValue());
                        } else {
                            wrapper.eq("DATA_SOURCE", item.getFieldValue());
                        }
                        break;
                    case "dataType":
                        if ("nq".equals(item.getLogicJudgement())) {
                            wrapper.ne("DATA_TYPE", item.getFieldValue());
                        } else {
                            wrapper.eq("DATA_TYPE", item.getFieldValue());
                        }
                        break;
                    case "metadataName":
                        if (StringUtils.hasText(item.getFieldValue())) {
                            for (String value : item.getFieldValue().split(" ")) {
                                wrapper.and(StringUtils.hasText(value.trim()), qw -> {
                                    if ("eq".equals(item.getLogicJudgement())) {
                                        qw.eq("RESOURCE_NAME", value.trim())/*.or().eq("RESOURCE_COMMENT", value.trim())*/;
                                    } else {
                                        qw.like("RESOURCE_NAME", value.trim())/*.or().like("RESOURCE_COMMENT", value.trim())*/;
                                    }
                                });
                            }
                        }
                        break;
                    default:
                }
            });
        });

        // 排序设置
        SearchResultSort sort = condition.getSort();
        if (sort != null && sort.getSort() != null) {
            // 通过反射获取资源类字段注解中的数据库表相关的列名
            Field field = ReflectUtil.getField(DirectoryResource.class, sort.getField().trim());
            if (field != null) {
                TableField tableField = field.getAnnotation(TableField.class);
                if (tableField != null && StringUtils.hasText(tableField.value())) {
                    //没有过滤条件时，order by前面会拼接and，导致查询报错  update by xiongcl  2024/04/10
                    if(condition.getConditions().size()<=0){
                        queryWrapper.last("1=1 ORDER BY "+ tableField.value() + (sort.getSort().equalsIgnoreCase("asc") ? " ASC " :" DESC "));
                    }else {
                        queryWrapper.orderBy(true, sort.getSort().equalsIgnoreCase("asc"), tableField.value());
                    }
                }
            }
        }
        return queryWrapper;
    }
}
