import { getConnection, Between, Brackets } from "typeorm";
import { Request } from "express";

type paginationType<T> = {
  list: T[];
  total: number;
  pageSize: number;
  pageNumber: number;
};

const filterKeys = ["pwd"];
const DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;

export default async function getBuilderPagination<T>(
  entity: Function,
  req: Request,
  queryParams?: { [key: string]: any }
): Promise<paginationType<T>> {
  try {
    // 获取分页参数
    const { pageSize, pageNumber } = getPaginationParams(req);
    const repository = getConnection().manager.getRepository(entity);
    const alias = "entity";

    // 创建 QueryBuilder
    const queryBuilder = repository.createQueryBuilder(alias);
    // 处理查询参数
    if (queryParams) {
      Object.entries(queryParams).forEach(([key, value]) => {
        if (!["pageSize", "pageNumber"].includes(key)) {
          // 新增非空条件处理
          if (value === "NOT_EMPTY") {
            queryBuilder.andWhere(
              new Brackets((qb) => {
                qb.where(`${alias}.${key} IS NOT NULL`).andWhere(
                  `${alias}.${key} != ''`
                );
              })
            );
          }
          // 处理日期范围
          else if (typeof value === "string" && DATE_REGEX.test(value)) {
            const start = new Date(`${value}T00:00:00`);
            const end = new Date(`${value}T23:59:59`);
            queryBuilder.andWhere(
              new Brackets((qb) =>
                qb
                  .where(`${alias}.${key} >= :start`, { start })
                  .andWhere(`${alias}.${key} <= :end`, { end })
              )
            );
          }
          // 处理普通参数
          else if (value !== undefined) {
            // 处理数组参数（如?status=1,2,3）
            if (typeof value === "string" && value.includes(",")) {
              queryBuilder.andWhere(`${alias}.${key} IN (:...${key})`, {
                [key]: value.split(","),
              });
            }
            // 处理普通值
            else {
              queryBuilder.andWhere(`${alias}.${key} = :${key}`, {
                [key]: value,
              });
            }
          }
        }
      });
    }

    // 添加排序
    queryBuilder.orderBy(`${alias}.createDate`, "DESC");

    // 执行分页查询
    const [list, total] = await queryBuilder
      .skip((pageNumber - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();

    // 过滤敏感字段
    const filteredList = list.map((item: any) => {
      const filtered = { ...item };
      filterKeys.forEach((key) => delete filtered[key]);
      return filtered;
    });

    return {
      list: filteredList,
      total,
      pageSize,
      pageNumber,
    };
  } catch (err) {
    throw new Error(`分页查询出错: ${err.message}`);
  }
}

/**
 * 获取分页参数
 */
function getPaginationParams(req: Request): {
  pageSize: number;
  pageNumber: number;
} {
  const { pageSize = 10, pageNumber = 1 } =
    req.method === "GET" ? req.query : req.body;

  return {
    pageSize: Math.max(1, parseInt(pageSize as string, 10)),
    pageNumber: Math.max(1, parseInt(pageNumber as string, 10)),
  };
}
