import { getConnection } from "typeorm";
import { Request } from "express";

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

const filterKeys = ["pwd"];

/**
 *
 * @param entites 传入实体类数组以供查询（支持多表）
 * @param req express的Request请求体
 * @param queryParams 查询参数
 * @param aliasMap 表别名映射，键为实体类名，值为别名
 * @returns
 */
export default async function MultPagination<T>(
  entites: Function[],
  req: Request,
  queryParams?: { [key: string]: any },
  aliasMap: { [key: string]: string } = {}
): Promise<paginationType<T>> {
  const { pageSize, pageNumber } = getPaginationParams(req);

  // 获取 QueryBuilder
  const queryBuilder = getConnection().createQueryBuilder();

  // 构造 FROM 部分，支持多表
  entites.forEach((entite, index) => {
    const alias = aliasMap[entite.name] || `alias${index}`;
    if (index === 0) {
      queryBuilder.from(entite, alias); // 主表
    } else {
      queryBuilder.leftJoinAndSelect(entite, alias); // 关联表
    }
  });

  // 构造 WHERE 条件
  if (queryParams) {
    Object.entries(queryParams).forEach(([key, value]) => {
      queryBuilder.andWhere(`${getWhereKey(key, aliasMap)} = :${key}`, {
        [key]: value,
      });
    });
  }

  // 构造排序
  queryBuilder.orderBy("alias0.createDate", "ASC");

  // 分页处理
  queryBuilder.skip((pageNumber - 1) * pageSize).take(pageSize);

  try {
    const [list, total] = await queryBuilder.getManyAndCount();

    // 过滤敏感数据
    list.forEach((item) => {
      filterKeys.forEach((key) => {
        delete item[key];
      });
    });

    return {
      list,
      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;
  const realPageSize = Math.max(1, parseInt(pageSize as string, 10));
  const realPageNumber = Math.max(1, parseInt(pageNumber as string, 10));
  return { pageSize: realPageSize, pageNumber: realPageNumber };
}

// 获取WHERE条件时自动识别别名
function getWhereKey(key: string, aliasMap: { [key: string]: string }) {
  for (const alias in aliasMap) {
    if (key.startsWith(alias + ".")) {
      return key; // 已包含别名
    }
  }
  return `alias0.${key}`; // 默认主表
}
