import { Plugin } from 'vite';
import { Faker } from '@faker-js/faker';

/**
 * Options for acceptable values to be parsed by the Faker library.
 */
type FakerDefinition =
  | string
  | ((faker: Faker) => unknown)
  | FakerDefinition[]
  | { [key: string]: FakerDefinition }

/**
 *
 */
interface ConditionalResponse {
  when: { headers?: Record<string, string>; query?: Record<string, string> }
  status?: number
  responseProps?: FakerDefinition
  staticResponse?: Record<string, any>
}

/**
 * Ascending or descending order for sorting.
 */
type SortOrder = 'asc' | 'desc'

/**
 * Customizable query parameters for an endpoint.
 */
type QueryParams = {
  search?: string
  sort?: string
  order?: SortOrder
  filter?: string
  per_page?: string
  total?: string
}

/**
 * Configuration options for a single endpoint.
 */
interface EndpointConfig {
  url: string
  seed?: number
  singular?: boolean
  pagination?: boolean
  perPage?: number
  total?: number
  responseProps: FakerDefinition
  status?: number
  delay?: number
  staticResponse?: Record<string, any>
  errorRate?: number
  responseFormat?: (data: any) => any
  conditions?: ConditionalResponse[]
  cache?: boolean
  methods?: ('GET' | 'POST' | 'PUT' | 'DELETE')[]
  logRequests?: boolean
  queryParams?: QueryParams
}

/**
 * Options for the Vite plugin.
 */
interface FakeryPluginOptions {
  endpoints: EndpointConfig[]
}

/**
 * Vite plugin to register mock API endpoints using data from Faker.js.
 *
 * @param optionsOrPath - Either an object with plugin options or a path to a JSON file
 * @returns A configured Vite plugin
 * @throws If the configuration is invalid or missing required fields
 */
declare const vitePluginFakery: (optionsOrPath: string | FakeryPluginOptions) => Plugin;

export { vitePluginFakery as default };
export type { FakeryPluginOptions };
