export interface ApiError {
  code: string
  message: string
  fields?: Record<string, unknown>
  request_id?: string
}

export class ApiException extends Error {
  status: number
  body: ApiError

  constructor(status: number, body: ApiError) {
    super(body.message || `HTTP ${status}`)
    this.status = status
    this.body = body
  }
}

export type SyncStatus = 'cloning' | 'idle' | 'syncing' | 'error'
export type WorktreeStatus = 'idle' | 'active' | 'pruning'
export type CredentialKind = 'pat' | 'ssh_key' | 'none'

export interface Workspace {
  id: string
  project_id: string
  slug: string
  name: string
  description: string
  git_remote_url: string
  default_branch: string
  sync_status: SyncStatus
  last_synced_at: string | null
  last_sync_error: string
  created_at: string
  updated_at: string
}

export interface Worktree {
  id: string
  workspace_id: string
  branch: string
  path: string
  status: WorktreeStatus
  active_holder: string
  acquired_at: string | null
  last_used_at: string
  created_at: string
}

export interface CredentialMeta {
  kind: CredentialKind
  username: string
  fingerprint: string
}

export interface CredentialUpsertBody {
  kind: CredentialKind
  username?: string
  secret?: string
}

export interface FileStatus {
  path: string
  index_x: string
  worktree_y: string
}

export interface CreateWorkspaceBody {
  slug: string
  name: string
  description?: string
  git_remote_url: string
  default_branch?: string
  credential: CredentialUpsertBody
}

export interface UpdateWorkspaceBody {
  name?: string
  description?: string
  default_branch?: string
}

export interface CreateWorktreeBody {
  branch: string
  base_branch?: string
}

export interface CommitBody {
  message: string
  push?: boolean
  add_all?: boolean
}

export interface CommitResp {
  sha: string
}

export interface CommitLog {
  hash: string
  author: string
  email: string
  date: string
  subject: string
}

export interface DiffResp {
  diff: string
  truncated: boolean
}

export interface DiffParams {
  ref?: string
  against?: string
  staged?: boolean
  paths?: string
  context?: number
}

export interface ChangeRequest {
  id: string
  project_id: string
  workspace_id: string
  requirement_id: string | null
  issue_id: string | null
  number: number
  title: string
  description: string
  source_branch: string
  target_branch: string
  state: 'open' | 'merged' | 'closed'
  review_verdict: 'pending' | 'approved' | 'changes_requested' | 'rejected'
  ci_state: 'unknown' | 'pending' | 'success' | 'failure'
  provider: string
  external_id: number | null
  external_url: string
  merge_commit_sha: string
  reviewed_by: string | null
  reviewed_at: string | null
  created_by: string
  merged_at: string | null
  created_at: string
  updated_at: string
}

export interface CreateChangeRequestBody {
  source_branch: string
  target_branch?: string
  title: string
  description?: string
  requirement_id?: string | null
  issue_id?: string | null
}

export interface ReviewChangeRequestBody {
  verdict: 'approved' | 'changes_requested' | 'rejected'
  note?: string
}

export interface MergeChangeRequestBody {
  method?: 'merge' | 'squash' | 'rebase'
}
