import { Gitlab, GitlabService } from "@egg/net-tool"
import PocketBase, { RecordModel } from "pocketbase"
import { Logger } from "winston"

import { Context } from "../../types"
import PbToolBase from "../base"

const DB_NAME = "gitlabProject"

/**
 * Gitlab项目接口定义
 * 描述Gitlab项目的基本属性和配置
 */
export interface GitlabProject {
  /** Gitlab项目ID */
  projectId: number
  /** 项目名称 */
  name: string
  /** 项目描述 */
  desc: string
  /** 带命名空间的项目路径 */
  pathWithNamespace: string
  /** 项目网页URL */
  webUrl: string
  /** 是否开启CI/CD通知 */
  openCICDNotify: boolean
  /** 是否开启合并请求总结 */
  openMRSummary: boolean
}

/**
 * Gitlab项目模型类型
 * 将Gitlab项目接口与PocketBase记录模型合并
 */
export type GitlabProjectModel = GitlabProject & RecordModel

/**
 * GitlabProject数据库操作类
 * 提供Gitlab项目相关的数据库操作方法，继承自PbToolBase
 */
class GitlabProjectDB extends PbToolBase<GitlabProjectModel> {
  /**
   * 创建GitlabProjectDB实例
   *
   * @param pbClient - PocketBase客户端实例
   * @param logger - 日志记录器实例
   */
  constructor(pbClient: PocketBase, logger: Logger) {
    super(DB_NAME, pbClient, logger)
  }

  /**
   * 根据项目ID获取Gitlab项目
   *
   * @param projectId - Gitlab项目ID
   * @returns 成功时返回项目记录，失败时返回null
   *
   * @example
   * ```typescript
   * const project = await gitlabProjectDB.getByProjectId(12345);
   * ```
   */
  public getByProjectId = (projectId: number) => {
    return this.getFirstOne(`projectId = "${projectId}"`)
  }

  /**
   * 获取项目信息，如不存在则从Gitlab获取并创建
   *
   * @param projectId - Gitlab项目ID
   * @param gitlabService - Gitlab服务实例
   * @returns 成功时返回项目记录，失败时返回null
   *
   * @example
   * ```typescript
   * const project = await gitlabProjectDB.getAndCreate(12345, gitlabService);
   * ```
   */
  public getAndCreate = async (
    projectId: number,
    gitlabService: GitlabService
  ) => {
    const project = await this.getByProjectId(projectId)
    if (project) return project
    gitlabService.setProjectId(projectId)
    const projectInfo = await gitlabService.project.getDetail()
    if (!projectInfo) return null
    const { name, description, path_with_namespace, web_url } = projectInfo
    const newProject = {
      projectId,
      name,
      desc: description,
      pathWithNamespace: path_with_namespace,
      webUrl: web_url,
      openCICDNotify: false,
      openMRSummary: false,
    }
    return await this.create(newProject)
  }

  /**
   * 从上下文获取Gitlab项目信息
   * 解析请求上下文中的项目ID，获取或创建项目记录
   *
   * @param context - 请求上下文，包含请求体和Gitlab服务
   * @returns 成功时返回项目记录，失败时返回null
   *
   * @example
   * ```typescript
   * const project = await gitlabProjectDB.getByCtx(ctx);
   * ```
   */
  public getByCtx = async ({ body: rawBody, gitlabService }: Context) => {
    const body = rawBody as Gitlab.PipelineEvent | Gitlab.MergeRequestEvent
    const projectId = body.project.id
    if (!projectId) return null
    return await this.getAndCreate(projectId, gitlabService)
  }
}

export default GitlabProjectDB
