import type * as interfaces from '../../ts_interfaces/index.ts';

export interface ITestConnectionResult {
  ok: boolean;
  error?: string;
}

export interface IListOptions {
  search?: string;
  page?: number;
  perPage?: number;
}

export interface IPipelineListOptions extends IListOptions {
  status?: string;
  ref?: string;
  source?: string;
}

/**
 * Abstract base class for Git provider implementations.
 * Subclasses implement Gitea API v1 or GitLab API v4.
 */
export abstract class BaseProvider {
  public readonly groupFilterId?: string;

  constructor(
    public readonly connectionId: string,
    public readonly baseUrl: string,
    protected readonly token: string,
    groupFilterId?: string,
  ) {
    this.groupFilterId = groupFilterId;
  }

  // Connection
  abstract testConnection(): Promise<ITestConnectionResult>;

  // Projects
  abstract getProjects(opts?: IListOptions): Promise<interfaces.data.IProject[]>;

  // Groups / Orgs
  abstract getGroups(opts?: IListOptions): Promise<interfaces.data.IGroup[]>;

  // Group Projects
  abstract getGroupProjects(groupId: string, opts?: IListOptions): Promise<interfaces.data.IProject[]>;

  // Secrets — project scope
  abstract getProjectSecrets(projectId: string): Promise<interfaces.data.ISecret[]>;
  abstract createProjectSecret(
    projectId: string,
    key: string,
    value: string,
  ): Promise<interfaces.data.ISecret>;
  abstract updateProjectSecret(
    projectId: string,
    key: string,
    value: string,
  ): Promise<interfaces.data.ISecret>;
  abstract deleteProjectSecret(projectId: string, key: string): Promise<void>;

  // Secrets — group scope
  abstract getGroupSecrets(groupId: string): Promise<interfaces.data.ISecret[]>;
  abstract createGroupSecret(
    groupId: string,
    key: string,
    value: string,
  ): Promise<interfaces.data.ISecret>;
  abstract updateGroupSecret(
    groupId: string,
    key: string,
    value: string,
  ): Promise<interfaces.data.ISecret>;
  abstract deleteGroupSecret(groupId: string, key: string): Promise<void>;

  // Branches / Tags
  abstract getBranches(projectFullPath: string, opts?: IListOptions): Promise<interfaces.data.IBranch[]>;
  abstract getTags(projectFullPath: string, opts?: IListOptions): Promise<interfaces.data.ITag[]>;

  // Pipelines / CI
  abstract getPipelines(
    projectId: string,
    opts?: IPipelineListOptions,
  ): Promise<interfaces.data.IPipeline[]>;
  abstract getPipelineJobs(
    projectId: string,
    pipelineId: string,
  ): Promise<interfaces.data.IPipelineJob[]>;
  abstract getJobLog(projectId: string, jobId: string): Promise<string>;
  abstract retryPipeline(projectId: string, pipelineId: string): Promise<void>;
  abstract cancelPipeline(projectId: string, pipelineId: string): Promise<void>;

}
