package com.njyunzhi.pet_identity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.njyunzhi.pet_identity.service.IBaseService;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements IBaseService<T> {
    @Override
    public boolean removeLogicById(Serializable id) {

        TableInfo tableInfo = SqlHelper.table(currentModelClass());
        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", -1)
                .eq(tableInfo.getKeyColumn(), id);

        return update(updateWrapper);
    }

    @Override
    public boolean removeLogicByUser(Serializable id, String userId, String userType) {

        TableInfo tableInfo = SqlHelper.table(currentModelClass());
        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("status", -1)
                .set("delete_user_type", userType)
                .set("delete_user", userId)
                .set("delete_date", LocalDateTime.now())
                .eq(tableInfo.getKeyColumn(), id);

        return update(updateWrapper);
    }

    @Override
    public boolean removeBy(String column, Object value, boolean notDelete) {
        if (notDelete) {
            UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
            updateWrapper.set("status", -1);
            updateWrapper.eq(column, value);
            return update(updateWrapper);
        } else {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(column, value);
            return remove(queryWrapper);
        }
    }

    @Override
    public boolean canAccessData(Serializable id, String userId) {
        TableInfo tableInfo = SqlHelper.table(currentModelClass());

        String t = tableInfo.getTableName();
//        String k = tableInfo.getKeyColumn();
        String kAlias = t + ".org_id";

        String joinSQL = "INNER JOIN sys_user_data_scope s ON ( "+ kAlias +" = s.org_id OR "+t+".create_user = s.user_id )";
        String whereSQL = "WHERE " + kAlias + " = '"+ id +"' AND s.user_id = '" + userId + "'";

        String sql = joinSQL + " " + whereSQL;

        QueryWrapper<T> wrapper = new QueryWrapper<>();
        wrapper.last(sql);
        return count(wrapper) > 0;
    }

    @Override
    public boolean remvoeWithDataScope(Serializable id, String userId) {
        TableInfo tableInfo = SqlHelper.table(currentModelClass());

        String t = tableInfo.getTableName();
        String k = tableInfo.getKeyColumn();
        String kAlias = t + "." + k;

        String joinSQL = "INNER JOIN sys_user_data_scope s ON ( "+ kAlias +" = s.org_id OR "+t+".create_user = s.user_id )";
        String setSQL = "SET status = -1";
        String whereSQL = "WHERE " + kAlias + " = '"+ id +"' AND s.user_id = '" + userId + "'";

        String sql = joinSQL + " " + setSQL + " " + whereSQL;

        UpdateWrapper<T> wrapper = new UpdateWrapper<>();
        wrapper.last(sql);
        return update(wrapper);
    }

    @Override
    public int countBy(String column, Object value, boolean notDelete) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(column, value);
        queryWrapper.gt(notDelete, "status", -1);

        return count(queryWrapper);
    }

    @Override
    public T getByButNot(String column, Object value, String col, Object val, boolean notDelete) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(column, value);
        queryWrapper.ne(col, val);
        queryWrapper.gt(notDelete, "status", -1);
        queryWrapper.last("limit 1");

        return getOne(queryWrapper);
    }

    @Override
    public T getExistBy(String column, Object value, boolean normal, boolean notDelete) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(column, value);
        queryWrapper.eq(normal, "status", 1);
        queryWrapper.gt(notDelete, "status", -1);
        queryWrapper.last("limit 1");
        return getOne(queryWrapper);
    }

    @Override
    public List<T> getListBy(String column, Object value, boolean normal, boolean notDelete) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(column, value);
        queryWrapper.eq(normal, "status", 1);
        queryWrapper.gt(notDelete, "status", -1);
        return list(queryWrapper);
    }
}
