import { ToolingError } from '../../../../../../types'
import type { ExecutionContext } from '../../../../../../../base/types'

/**
 * Dropbox credentials for API calls
 */
interface DropboxCredentials {
  accessToken: string
}

/**
 * Parameters for creating a folder
 */
export interface CreateFolderParams {
  path: string
  autorename?: boolean
}

/**
 * Result of folder creation
 */
export interface CreateFolderResult {
  metadata: {
    id: string
    name: string
    path_lower: string
    path_display: string
  } | null
}

/**
 * Create a folder in Dropbox
 *
 * Uses the RPC endpoint for folder creation.
 * Returns null metadata if folder already exists (409 path/conflict).
 *
 * @param credentials - Dropbox access token
 * @param params - Folder creation parameters
 * @param context - Execution context for logging
 * @returns Folder metadata, or null metadata if folder already exists
 *
 * @see https://www.dropbox.com/developers/documentation/http/documentation#files-create_folder_v2
 */
export async function createFolder(
  credentials: DropboxCredentials,
  params: CreateFolderParams,
  context?: ExecutionContext
): Promise<CreateFolderResult> {
  context?.logger?.debug(`Creating folder in Dropbox: ${params.path}`)

  const response = await fetch('https://api.dropboxapi.com/2/files/create_folder_v2', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${credentials.accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      path: params.path,
      autorename: params.autorename ?? false
    })
  })

  // Handle 409 Conflict - folder already exists
  if (response.status === 409) {
    const errorData = (await response.json()) as { error_summary?: string }
    if (errorData.error_summary?.startsWith('path/conflict')) {
      context?.logger?.debug(`Folder already exists: ${params.path}`)
      return { metadata: null }
    }
    // Other 409 errors are actual errors
    throw new ToolingError('api_error', `Dropbox API error: ${errorData.error_summary}`, {
      status: 409,
      error_summary: errorData.error_summary
    })
  }

  if (!response.ok) {
    await handleDropboxError(response, context)
  }

  const result = (await response.json()) as CreateFolderResult

  context?.logger?.info(`Folder created in Dropbox: ${result.metadata?.path_display}`)

  return result
}

/**
 * Handle Dropbox API errors
 */
async function handleDropboxError(response: Response, context?: ExecutionContext): Promise<never> {
  let errorMessage = `Dropbox API error: ${response.status}`
  let errorDetails: Record<string, unknown> = { status: response.status }

  try {
    const errorData = (await response.json()) as { error_summary?: string; error?: Record<string, unknown> }
    if (errorData.error_summary) {
      errorMessage = `Dropbox API error: ${errorData.error_summary}`
      errorDetails = { ...errorDetails, ...errorData }
    }
  } catch {
    errorMessage += ` - ${response.statusText}`
  }

  context?.logger?.error(errorMessage)

  if (response.status === 401) {
    throw new ToolingError('credentials_invalid', 'Dropbox access token expired or invalid', errorDetails)
  }
  if (response.status === 429) {
    throw new ToolingError('rate_limit_exceeded', errorMessage, errorDetails)
  }
  throw new ToolingError('api_error', errorMessage, errorDetails)
}
