import type { IconProps } from '@based/ui'
import type { CSSProperties } from 'react'
import type { ComponentDoc } from 'react-docgen-typescript'

export declare global {
  namespace Based {
    namespace UI {
      namespace Extractor {
        type FilterProps = {
          filterBy: string
          block?: string
        }

        type Context = {
          meta: MetaResult
          blocks: BlocksResult
        }

        type PluginOptions = {
          storiesDir: string
          virtualModuleId?: string
          packageName?: string
          cacheSize?: number
          debug?: boolean
        }

        type CacheEntry = {
          mtimeMs: number
          meta: MetaDescriptorResult | null
          blocks: BlocksDescriptorResult[] | null
        }

        type Cache = Map<string, CacheEntry>

        type MetaComponent = (props?: any) => JSX.Element | ReactNode | null

        type MetaResult = {
          [key: string]: {
            file: string
            meta: MetaDescriptorResult
          }
        }

        type MetaDescriptorResult = MetaDescriptor & {
          exportType: 'named' | 'default'
          packageName: string
          component: ComponentDoc
          id: string
        }

        type MetaDescriptor =
          | (MetaDescriptorBase & {
              component: MetaComponent
              showApi: boolean
              showUsage: boolean
              section: 'components'
            })
          | (MetaDescriptorBase & {
              section: 'typography' | 'colors'
              showApi?: never
              showUsage?: never
              component?: never
            })

        type MetaDescriptorBase = {
          name: string
          icon?: IconProps['variant']
          group?: string
          id?: string
          subtitle?: string
          buttons?: MetaButtons[]
          features?: string[]
        }

        type MetaButtons = {
          label: string
          icon?: IconProps['variant']
          url?: string
          goTo?: string
        }

        type BlocksResult = {
          [key: string]: {
            file: string
            blocks: BlocksDescriptorResult[]
          }
        }

        type BlocksDescriptorResult = BlocksDescriptor & { id: string }

        type BlocksDescriptorBase = {
          name: string
          id?: string
          type: 'component' | 'color' | 'typography'
          description: string
          render: MetaComponent
          style?: {
            frame?: boolean
            theme?: 'dark' | 'light'
            size?: 'small' | 'medium' | 'big' | string | number
            flex?: {
              justifyContent?: CSSProperties['justifyContent']
              alignItems?: CSSProperties['alignItems']
            }
            badge?: 'invertable' | 'dynamic' | 'static' | string
          }
        }

        type BlocksDescriptor =
          | (BlocksDescriptorBase & {
              type: 'typography'
              code?: never
            })
          | (BlocksDescriptorBase & {
              type: 'color'
              code?: never
            })
          | (BlocksDescriptorBase & {
              type: 'component'
              code?: string
            })
      }
    }
  }
}
