import { blocksData, metaData } from 'virtual:@based/ui/stories'
import type React from 'react'
import { createContext, useContext } from 'react'

const MetaContext = createContext<Based.UI.Extractor.Context | undefined>(
  undefined,
)

export const MetaProvider: React.FC<{ children: React.ReactNode }> = ({
  children,
}) => (
  <MetaContext.Provider value={{ meta: metaData, blocks: blocksData }}>
    {children}
  </MetaContext.Provider>
)

export function useMeta<K extends keyof Based.UI.Extractor.MetaResult>(
  filterBy: K,
): Based.UI.Extractor.MetaResult[K]
export function useMeta(): Based.UI.Extractor.MetaResult
export function useMeta<K extends keyof Based.UI.Extractor.MetaResult>(
  filterBy?: K,
): Based.UI.Extractor.MetaResult | Based.UI.Extractor.MetaResult[K] {
  const context = useContext(MetaContext)

  if (!context) {
    throw new Error('useMeta must be used within a MetaContextProvider')
  }

  if (filterBy) {
    return context.meta[filterBy]
  }

  return context.meta
}

export function useBlocks<K extends keyof Based.UI.Extractor.BlocksResult>(
  filterBy: K,
): Based.UI.Extractor.BlocksResult[K]
export function useBlocks(): Based.UI.Extractor.BlocksResult
export function useBlocks<K extends keyof Based.UI.Extractor.BlocksResult>(
  filterBy?: K,
): Based.UI.Extractor.BlocksResult | Based.UI.Extractor.BlocksResult[K] {
  const context = useContext(MetaContext)

  if (!context) {
    throw new Error('useBlocks must be used within a MetaContextProvider')
  }

  if (filterBy) {
    return context.blocks[filterBy]
  }

  return context.blocks
}
