/**
 * SDK API Client — State management methods.
 * (getState, saveState, deleteState, exportState)
 */

import {
  APIResponse,
  APIError,
  StateResponse,
  FetchContext,
  SDKState,
} from './api-client-types'

/**
 * Load SDK state for the current tenant
 */
export async function getState(ctx: FetchContext): Promise<StateResponse | null> {
  try {
    const params = new URLSearchParams({ tenantId: ctx.tenantId })
    if (ctx.projectId) params.set('projectId', ctx.projectId)
    const response = await ctx.fetchWithRetry<APIResponse<StateResponse>>(
      `${ctx.baseUrl}/state?${params.toString()}`,
      {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
      }
    )

    if (response.success && response.data) {
      return response.data
    }

    return null
  } catch (error) {
    const apiError = error as APIError
    // 404 means no state exists yet - that's okay
    if (apiError.status === 404) {
      return null
    }
    throw error
  }
}

/**
 * Save SDK state for the current tenant.
 * Supports optimistic locking via version parameter.
 */
export async function saveState(
  ctx: FetchContext,
  state: SDKState,
  version?: number
): Promise<StateResponse> {
  const response = await ctx.fetchWithRetry<APIResponse<StateResponse>>(
    `${ctx.baseUrl}/state`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        ...(version !== undefined && { 'If-Match': String(version) }),
      },
      body: JSON.stringify({
        tenantId: ctx.tenantId,
        projectId: ctx.projectId,
        state,
        version,
      }),
    }
  )

  if (!response.success) {
    throw ctx.createError(response.error || 'Failed to save state', 500, true)
  }

  return response.data!
}

/**
 * Delete SDK state for the current tenant
 */
export async function deleteState(ctx: FetchContext): Promise<void> {
  const params = new URLSearchParams({ tenantId: ctx.tenantId })
  if (ctx.projectId) params.set('projectId', ctx.projectId)
  await ctx.fetchWithRetry<APIResponse<void>>(
    `${ctx.baseUrl}/state?${params.toString()}`,
    {
      method: 'DELETE',
      headers: { 'Content-Type': 'application/json' },
    }
  )
}

/**
 * Export SDK state in various formats
 */
export async function exportState(
  ctx: FetchContext,
  format: 'json' | 'pdf' | 'zip'
): Promise<Blob> {
  const response = await ctx.fetchWithTimeout(
    `${ctx.baseUrl}/export?tenantId=${encodeURIComponent(ctx.tenantId)}&format=${format}`,
    {
      method: 'GET',
      headers: {
        'Accept':
          format === 'json'
            ? 'application/json'
            : format === 'pdf'
              ? 'application/pdf'
              : 'application/zip',
      },
    },
    `export-${Date.now()}`
  )

  if (!response.ok) {
    throw ctx.createError(`Export failed: ${response.statusText}`, response.status, true)
  }

  return response.blob()
}
