package com.ruov.common.base;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruov.common.exception.base.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
public class RServiceImpl<D extends REntity.Dto, V extends REntity.Vo, P, M extends BaseMapper<P>>
        extends ServiceImpl<M, P> implements RService<D, V, P> {
    private Class<P> clazz;
    private Class<V> vClazz;
    @Resource
    private HttpServletResponse response;

    public RServiceImpl() {
        Type superClass = getClass().getGenericSuperclass();
        if (superClass instanceof ParameterizedType) {
            Type[] typeArguments = ((ParameterizedType) superClass).getActualTypeArguments();
            this.clazz = (Class<P>) typeArguments[2];
            this.vClazz = (Class<V>) typeArguments[1];
        }
    }

    @Override
    public Page<V> listData(D query) {
        P dbQuery;
        try {
            dbQuery = clazz.newInstance();
            BeanUtil.copyProperties(query, dbQuery);
        } catch (InstantiationException | IllegalAccessException e) {
            log.error("属性获取失败", e);
            throw new BaseException(e.getMessage());
        }
        if (query.getLimit() == null || query.getSize() == null) {
            query.setLimit(1);
            query.setSize(10);
        }
        QueryWrapper<P> queryWrapper = createQueryWrapper(dbQuery);
        Page<P> pageIns = new Page<>(query.getLimit(), query.getSize());
        Page<P> page = page(pageIns, queryWrapper);
        List<V> resultV = page.getRecords().stream().map(e -> {
            try {
                V v = vClazz.newInstance();
                BeanUtil.copyProperties(e, v);
                return v;
            } catch (InstantiationException | IllegalAccessException ex) {
                log.error("属性获取失败", ex);
                throw new BaseException(ex.getMessage());
            }
        }).collect(Collectors.toList());
        Page<V> vPage = new Page<>();
        vPage.setTotal(page.getTotal());
        vPage.setRecords(resultV);
        return vPage;
    }

    @Override
    public boolean inertOrUpdate(D data) {
        P dbData;
        try {
            dbData = clazz.newInstance();
            BeanUtil.copyProperties(data, dbData);
        } catch (InstantiationException | IllegalAccessException e) {
            log.error("属性获取失败", e);
            throw new BaseException(e.getMessage());
        }
        if (data.getId() != null) {
            return updateById(dbData);
        } else {
            return save(dbData);
        }
    }

    @Override
    public boolean delBatch(List<? extends Serializable> id) {
        return false;
    }

    @Override
    public void export(D query) {

    }


    /**
     * 通过PO实体创建QueryWrapper
     *
     * @param po  实体对象
     * @param <T> 实体类型
     * @return QueryWrapper
     */
    public static <T> QueryWrapper<T> createQueryWrapper(T po) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();

        if (po == null) {
            return queryWrapper;
        }

        // 获取PO类的所有字段
        Field[] fields = po.getClass().getDeclaredFields();
        Map<String, Object> conditionMap = new HashMap<>();

        for (Field field : fields) {
            field.setAccessible(true); // 设置可访问性

            try {
                // 获取字段的值
                Object value = field.get(po);
                if (value != null) {
                    // 根据字段类型处理不同的值
                    String fieldName = field.getName();
                    if (value instanceof Date) {
                        // 格式化日期
                        String formattedDate = formatDate((Date) value);
                        conditionMap.put(fieldName, formattedDate);
                    } else {
                        conditionMap.put(fieldName, value);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace(); // 处理异常
            }
        }

        // 将条件添加到QueryWrapper中
        conditionMap.forEach(queryWrapper::eq); // 使用eq方法添加等于条件

        return queryWrapper;
    }

    /**
     * 格式化日期为字符串
     *
     * @param date 日期对象
     * @return 格式化后的字符串
     */
    private static String formatDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 可根据需要调整格式
        return sdf.format(date);
    }

}
