package com.malk.base;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.Entity;
import javax.persistence.Id;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 查询map [不指定表名]
 * 通过Map实现, 无需定义实体, 主键设置Long即可: public interface HSViewDao extends CrudRepository<JpaMap, Long>
 * -
 * 使用native查询，返回Map. 直接查询表名 + 列名 + 条件, 可不做实体映射场景
 * 时间的时区处理: 方法1见BasePo, @Temporal & @JsonFormat 注解; 方法2见BaseDto, jsonFormatDateTime
 * 空条件jpa实现, 查询全部数据, 通过 like LTRIM('%' + ?x + '%') 进行实现 [dsl适用于复杂场景, Specification谓词需要依赖于实体]
 * -
 * 多条件查询
 * 1. sql + if [SqlServer不支持if条件]
 * * @Query(value = "select * from vwpbCommonDataOrderPlan where if (?1 is not null, dPlanDate >= ?1, 1=1) and if (?2 is not null, dPlanDate <= ?2, 1=1) and sOrderNo like LTRIM('%' + ?3 + '%')", nativeQuery = true)
 * * Page<Map> queryOrderPlan(Date start, Date end, String sOrderNo, Pageable pageable);
 * 2. Specification, 谓词需要依赖于实体 [参考示例, 如下 test 方法实现]
 * - 说明
 * 1. @Query: nativeQuery查询使用表名, 不能使用对象名
 * 2. ppExt: 现有表如u8, 不继承 BaseDto, 避免默认id与时间字段匹配异常
 */

@Entity
public class JpaMap {

    @Id
    private String id;

    /**
     * 时间的时区处理
     */
    public static final List<Map> jsonFormatDateTime(List<Map> data) {
        return JSON.parseArray(JSON.toJSONString(data, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteDateUseDateFormat), Map.class);
    }

    // 示例: Specification, 谓词需要依赖于实体
    private void test() {
        //Page<Map> findAll (Specification < T > spec, Pageable pageable);

        String sOrderNo = "";
        Date sTime = null;
        Date eTime = null;

        Specification spec = (root, criteriaQuery, criteriaBuilder) -> {
            List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(sOrderNo)) {
                javax.persistence.criteria.Predicate predicate = criteriaBuilder.like(root.get("sOrderNo"), "%" + sOrderNo + "%");
                predicates.add(predicate);
            }

            if (ObjectUtil.isNotNull(sTime)) {
//            javax.persistence.criteria.Predicate predicate = criteriaBuilder.greaterThanOrEqualTo(root.getDefault("dPlanDate").as(String.class), "2023-06-03 00:00:00");
                javax.persistence.criteria.Predicate predicate = criteriaBuilder.greaterThanOrEqualTo(root.get("dPlanDate"), sTime);
                predicates.add(predicate);
            }

            if (ObjectUtil.isNotNull(eTime)) {
                javax.persistence.criteria.Predicate predicate = criteriaBuilder.lessThanOrEqualTo(root.get("dPlanDate"), eTime);
                predicates.add(predicate);
            }
            return criteriaBuilder.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
            /// 或
            ///return criteriaQuery.where(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()])).getRestriction();
        };
    }
}
