import type {
  TimeSeriesRequestOptions,
  TimeSeriesResponse,
} from '@carto/api-client'
import { createModel, type ModelQueryFactory } from './utils/create-model'
import { getModelQueryOptions } from './utils/get-model-query-options'
import { useSourceSlices } from './utils/use-source-slices'
import type {
  ModelComponentProps,
  ModelHookResponse,
  ModelProps,
  TimeSeriesWidgetProps,
} from './types'

export const getTimeSeries: ModelQueryFactory<
  TimeSeriesWidgetProps,
  TimeSeriesResponse
> = (args) =>
  getModelQueryOptions<TimeSeriesWidgetProps, TimeSeriesResponse>({
    queryKeyPrefix: ['timeSeries'],
    getWidgetMethod: (widgetModel) => (params) =>
      widgetModel.getTimeSeries(params as TimeSeriesRequestOptions),
    ...args,
  })

const { useModelHook: useTimeSeriesQuery } = createModel<
  TimeSeriesWidgetProps,
  TimeSeriesResponse
>({ buildQuery: getTimeSeries })

/**
 * `useTimeSeries` is a hook that analyzes time-based data with configurable time intervals for temporal visualizations.
 * `TimeSeriesModel` is the render-props component equivalent.
 *
 * @example
 * ```tsx
 * <TimeSeriesModel
 *   accessToken={token}
 *   sourceId="my_source"
 *   widgetProps={{ column: 'created_at', stepSize: 'month', operation: 'count' }}
 * >
 *   {({ data }) => <TimeSeriesChart data={data} />}
 * </TimeSeriesModel>
 * ```
 */
function useTimeSeries<
  P extends ModelProps<TimeSeriesWidgetProps, TimeSeriesResponse>,
>(props: P): ModelHookResponse<P, TimeSeriesResponse> {
  const { sourceId, sourcesId } = props
  const slices = useSourceSlices(sourceId ? [sourceId] : (sourcesId ?? []))
  return useTimeSeriesQuery(props, slices)
}

function TimeSeriesModel<
  P extends ModelProps<TimeSeriesWidgetProps, TimeSeriesResponse>,
>(
  props: ModelComponentProps<TimeSeriesWidgetProps, TimeSeriesResponse, P>,
): React.ReactElement {
  return props.children(useTimeSeries(props)) as React.ReactElement
}

export { useTimeSeries, TimeSeriesModel }
