package com.ruoyi.common.utils.sql;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

public final class DBUtil
{
    public static void transaction(Runnable runnable)
    {
        PlatformTransactionManager manager = SpringUtils.getBean(PlatformTransactionManager.class);
        TransactionDefinition definition = SpringUtils.getBean(TransactionDefinition.class);
        TransactionStatus transaction = manager.getTransaction(definition);
        try
        {
            runnable.run();
            manager.commit(transaction);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            manager.rollback(transaction);
            throw new RuntimeException(e);
        }
    }

    public static <T> T transaction(Supplier<T> runnable, T...ifExceptRet)
    {
        PlatformTransactionManager manager = SpringUtils.getBean(PlatformTransactionManager.class);
        TransactionDefinition definition = SpringUtils.getBean(TransactionDefinition.class);
        TransactionStatus transaction = manager.getTransaction(definition);
        try
        {
            T res = runnable.get();
            manager.commit(transaction);
            return res;
        }
        catch(Exception e)
        {
            e.printStackTrace();
            manager.rollback(transaction);
            if(null != ifExceptRet && ifExceptRet.length > 0)
                return ifExceptRet[0];
            else
                throw new RuntimeException(e);
        }
    }

    public static void orderBy(String...args)
    {
        if(null == args || args.length == 0)
            PageHelper.clearPage();
        else
            PageHelper.orderBy(String.join(" ", args));
    }

    public static void limit(int num)
    {
        if(num <= 0)
            PageHelper.clearPage();
        else
            PageHelper.startPage(1, num);
    }

    public static void page(int pageNo, int pageSize, String...orderBy)
    {
        if(null == orderBy || orderBy.length == 0)
            PageHelper.startPage(pageNo, pageSize);
        else
            PageHelper.startPage(pageNo, pageSize, String.join(" ", orderBy));
    }

    public static void startPage()
    {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    // startPage(() -> deptService.selectDeptList(new SysDept()));
    public static <T> List<T> startPage(Function<T, List<T>> selector, T cond)
    {
        startPage();
        return selector.apply(cond);
    }

    // startPage(() -> deptService.selectDeptList(new SysDept()));
    public static  <T> List<T> startPage(Supplier<List<T>> runnable)
    {
        startPage();
        return runnable.get();
    }

    private DBUtil() {}
}
