/**
 * API client utilities for making API calls in tests
 * Provides type-safe wrappers around common API operations
 */

import { Page, APIResponse } from '@playwright/test';
import { API_ENDPOINTS } from '../core/constants';

// ============================================================================
// Types
// ============================================================================

export interface WorktreeInfo {
  path: string;
  branch: string;
  isNew?: boolean;
  hasChanges?: boolean;
  changedFilesCount?: number;
}

export interface WorktreeListResponse {
  success: boolean;
  worktrees: WorktreeInfo[];
  error?: string;
}

export interface WorktreeCreateResponse {
  success: boolean;
  worktree?: WorktreeInfo;
  error?: string;
}

export interface WorktreeDeleteResponse {
  success: boolean;
  error?: string;
}

export interface CommitResult {
  committed: boolean;
  branch?: string;
  commitHash?: string;
  message?: string;
}

export interface CommitResponse {
  success: boolean;
  result?: CommitResult;
  error?: string;
}

export interface SwitchBranchResult {
  previousBranch: string;
  currentBranch: string;
  message: string;
}

export interface SwitchBranchResponse {
  success: boolean;
  result?: SwitchBranchResult;
  error?: string;
  code?: string;
}

export interface BranchInfo {
  name: string;
  isCurrent: boolean;
}

export interface ListBranchesResult {
  currentBranch: string;
  branches: BranchInfo[];
}

export interface ListBranchesResponse {
  success: boolean;
  result?: ListBranchesResult;
  error?: string;
}

// ============================================================================
// Worktree API Client
// ============================================================================

export class WorktreeApiClient {
  constructor(private page: Page) {}

  /**
   * Create a new worktree
   */
  async create(
    projectPath: string,
    branchName: string,
    baseBranch?: string
  ): Promise<{ response: APIResponse; data: WorktreeCreateResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.create, {
      data: {
        projectPath,
        branchName,
        baseBranch,
      },
    });
    const data = await response.json();
    return { response, data };
  }

  /**
   * Delete a worktree
   */
  async delete(
    projectPath: string,
    worktreePath: string,
    deleteBranch: boolean = true
  ): Promise<{ response: APIResponse; data: WorktreeDeleteResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.delete, {
      data: {
        projectPath,
        worktreePath,
        deleteBranch,
      },
    });
    const data = await response.json();
    return { response, data };
  }

  /**
   * List all worktrees
   */
  async list(
    projectPath: string,
    includeDetails: boolean = true
  ): Promise<{ response: APIResponse; data: WorktreeListResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.list, {
      data: {
        projectPath,
        includeDetails,
      },
    });
    const data = await response.json();
    return { response, data };
  }

  /**
   * Commit changes in a worktree
   */
  async commit(
    worktreePath: string,
    message: string
  ): Promise<{ response: APIResponse; data: CommitResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.commit, {
      data: {
        worktreePath,
        message,
      },
    });
    const data = await response.json();
    return { response, data };
  }

  /**
   * Switch branches in a worktree
   */
  async switchBranch(
    worktreePath: string,
    branchName: string
  ): Promise<{ response: APIResponse; data: SwitchBranchResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.switchBranch, {
      data: {
        worktreePath,
        branchName,
      },
    });
    const data = await response.json();
    return { response, data };
  }

  /**
   * List all branches
   */
  async listBranches(
    worktreePath: string
  ): Promise<{ response: APIResponse; data: ListBranchesResponse }> {
    const response = await this.page.request.post(API_ENDPOINTS.worktree.listBranches, {
      data: {
        worktreePath,
      },
    });
    const data = await response.json();
    return { response, data };
  }
}

// ============================================================================
// Factory Functions
// ============================================================================

/**
 * Create a WorktreeApiClient instance
 */
export function createWorktreeApiClient(page: Page): WorktreeApiClient {
  return new WorktreeApiClient(page);
}

// ============================================================================
// Convenience Functions (for direct use without creating a client)
// ============================================================================

/**
 * Create a worktree via API
 */
export async function apiCreateWorktree(
  page: Page,
  projectPath: string,
  branchName: string,
  baseBranch?: string
): Promise<{ response: APIResponse; data: WorktreeCreateResponse }> {
  return new WorktreeApiClient(page).create(projectPath, branchName, baseBranch);
}

/**
 * Delete a worktree via API
 */
export async function apiDeleteWorktree(
  page: Page,
  projectPath: string,
  worktreePath: string,
  deleteBranch: boolean = true
): Promise<{ response: APIResponse; data: WorktreeDeleteResponse }> {
  return new WorktreeApiClient(page).delete(projectPath, worktreePath, deleteBranch);
}

/**
 * List worktrees via API
 */
export async function apiListWorktrees(
  page: Page,
  projectPath: string,
  includeDetails: boolean = true
): Promise<{ response: APIResponse; data: WorktreeListResponse }> {
  return new WorktreeApiClient(page).list(projectPath, includeDetails);
}

/**
 * Commit changes in a worktree via API
 */
export async function apiCommitWorktree(
  page: Page,
  worktreePath: string,
  message: string
): Promise<{ response: APIResponse; data: CommitResponse }> {
  return new WorktreeApiClient(page).commit(worktreePath, message);
}

/**
 * Switch branches in a worktree via API
 */
export async function apiSwitchBranch(
  page: Page,
  worktreePath: string,
  branchName: string
): Promise<{ response: APIResponse; data: SwitchBranchResponse }> {
  return new WorktreeApiClient(page).switchBranch(worktreePath, branchName);
}

/**
 * List branches via API
 */
export async function apiListBranches(
  page: Page,
  worktreePath: string
): Promise<{ response: APIResponse; data: ListBranchesResponse }> {
  return new WorktreeApiClient(page).listBranches(worktreePath);
}
