import { Request } from "express";
import { Repository, getConnection } from "typeorm";
import { filterObjEmptyVal } from "@/util/globalMethods";
import dayjs from "dayjs";
import pagination from "../pagination/pagination";
import { BaseEntity } from "@/abstrClass/BaseEntity";
import getBuilderPagination from "../pagination/builderPagination";

interface CurdOptions<T> {
  entity: { new (): T } & typeof BaseEntity; // 确保实体继承 BaseEntity
  req: Request;
  params?: Partial<T>;
}
class Curd<T extends BaseEntity> {
  private entity: { new (): T };
  private req: Request;
  private queryParams?: { [key: string]: any };
  private repositrory: Repository<unknown>;
  private params?: Partial<T>;

  constructor(options: CurdOptions<T> & { repository?: Repository<T> }) {
    if (!options.entity) throw Error("请传入实体类");
    if (!options.req)
      throw Error("请传express的Request参数，一般在中间件回调中的第一个参数");
    // if (!options.params) throw Error("请传入需要操作的条件对象，用于sql查询");
    this.req = options.req;
    this.entity = options.entity;

    this.repositrory =
      options.repository || getConnection().getRepository(options.entity);
    this.queryParams =
      this.req.method === "GET" ? this.req.query : this.req.body;

    this.params = options.params;
  }

  async add() {
    let addData = { ...new this.entity(), ...this.queryParams };

    addData.updateDate = new Date();
    addData.createDate = new Date();

    return await this.repositrory.save(addData);
  }

  async delete() {
    if (!this.queryParams?.id)
      return {
        code: 500,
        msg: "没有传入需要删除数据的ID",
      };
    let queryData = await this.repositrory.findOne({
      where: { id: this.queryParams.id },
    });
    if (!queryData) return { code: 500, msg: "删除的数据不存在" };
    await this.repositrory.remove(queryData);
    return {
      code: 200,
      msg: "删除成功",
    };
  }

  async update() {
    let body = this.queryParams;
    await this.repositrory.update(
      { id: body.id },
      { ...this.queryParams, updateDate: new Date() }
    );

    return await this.repositrory.findOne(this.queryParams.id);
  }

  async query() {
    return await this.repositrory.find({
      where: filterObjEmptyVal({ ...this.queryParams, ...this.params }),
      order: {
        createDate: "DESC",
      },
    });
  }
  async queryList() {
    return await pagination(
      this.entity,
      this.req,
      filterObjEmptyVal({ ...this.queryParams, ...this.params })
    );
  }
  async queryBuilderList() {
    return await getBuilderPagination(
      this.entity,
      this.req,
      filterObjEmptyVal({ ...this.queryParams, ...this.params })
    );
  }
}

export default function curd<T extends BaseEntity>(
  options: CurdOptions<T>
): Curd<T> {
  return new Curd(options);
}
