/**
 * Figma-like React components
 *
 * API inspired by react-figma but outputs JSON instead of Figma nodes
 */

import * as React from 'react'

// Re-export defineVars for use in .figma.tsx files
export {
  defineVars,
  figmaVar,
  isVariable,
  loadVariablesIntoRegistry,
  isRegistryLoaded,
  type FigmaVariable
} from './vars.ts'

// Component registry - tracks defined components and their instances
interface ComponentDef {
  name: string
  element: React.ReactElement
  guid?: string // Set after first render creates the component
}

const componentRegistry = new Map<symbol, ComponentDef>()

export function resetComponentRegistry() {
  componentRegistry.clear()
}

export function getComponentRegistry() {
  return componentRegistry
}

/**
 * Define a reusable Figma component
 *
 * @example
 * const Button = defineComponent('Button',
 *   <Frame style={{ padding: 12, backgroundColor: "#3B82F6" }}>
 *     <Text style={{ color: "#FFF" }}>Click</Text>
 *   </Frame>
 * )
 *
 * export default () => (
 *   <Frame>
 *     <Button />
 *     <Button />
 *   </Frame>
 * )
 */
export function defineComponent<P extends BaseProps = BaseProps>(
  name: string,
  element: React.ReactElement
): React.FC<P> {
  const sym = Symbol(name)
  componentRegistry.set(sym, { name, element })

  // Return a component that renders as a special marker
  const ComponentInstance: React.FC<P> = (props) => {
    return React.createElement('__component_instance__', {
      __componentSymbol: sym,
      __componentName: name,
      ...props
    })
  }
  ComponentInstance.displayName = name

  return ComponentInstance
}

// Style types - use StyleProps from shorthands which includes both full and shorthand names
import type { StyleProps } from './shorthands.ts'

type Style = StyleProps
type TextStyle = StyleProps

interface BaseProps {
  name?: string
  style?: Style
  children?: React.ReactNode
}

interface TextProps extends Omit<BaseProps, 'style'> {
  style?: TextStyle
}

interface StarProps extends BaseProps {
  pointCount?: number
}

interface PolygonProps extends BaseProps {
  pointCount?: number
}

interface InstanceProps extends BaseProps {
  componentId?: string
}

interface IconProps extends BaseProps {
  /** Icon name in format "prefix:name" (e.g., "mdi:home", "lucide:star") */
  icon: string
  /** Icon size in pixels (default: 24) */
  size?: number
  /** Icon color (hex) */
  color?: string
}

// Component factory - creates intrinsic element wrapper
const c =
  <T extends BaseProps>(type: string): React.FC<T> =>
  (props) =>
    React.createElement(type, props)

// Components
export const Frame = c<BaseProps>('frame')
export const Rectangle = c<BaseProps>('rectangle')
export const Ellipse = c<BaseProps>('ellipse')
export const Text = c<TextProps>('text')
export const Line = c<BaseProps>('line')
export const Star = c<StarProps>('star')
export const Polygon = c<PolygonProps>('polygon')
export const Vector = c<BaseProps>('vector')
export const Component = c<BaseProps>('component')
export const Instance = c<InstanceProps>('instance')
export const Group = c<BaseProps>('group')
export const Page = c<BaseProps>('page')
export const View = Frame
export const Icon = c<IconProps>('icon')

// All component names for JSX transform
export const INTRINSIC_ELEMENTS = [
  'Frame',
  'Rectangle',
  'Ellipse',
  'Text',
  'Line',
  'Star',
  'Polygon',
  'Vector',
  'Component',
  'Instance',
  'Group',
  'Page',
  'View',
  'Icon'
] as const
