import type { ComponentType } from 'react'

export interface EditorPart {
  category: 'fields' | 'actions'
  section: string                       // palette section title, e.g. 'Payments'
  label: string
  icon: ComponentType
  Field: ComponentType<any>             // canvas preview
  Settings: ComponentType<any>          // settings sidebar
  defaults: { properties: Record<string, unknown>, layout?: Record<string, unknown> }
  maxPerForm?: number
  exclusiveGroup?: string               // at most one component per group per form
  validate?: ( form: unknown ) => string | null   // non-null blocks Publish with that message
  Response?: ComponentType<any>         // dashboard: full response row
  Summary?: ComponentType<any>          // dashboard: submissions list cell
  Badge?: ComponentType<{ field: any, fields: Record<string, any> }>   // dashboard: submission card badge (e.g. amount paid); return null to hide
}

export interface BotLock {
  show: boolean
  score: number
  threshold: number
}

export interface SubmitContext {
  submissionToken: string
}

export interface PublicPart {
  Field?: ComponentType<any>
  Action?: unknown
  initialValue?: unknown                // react-hook-form default for this component
  recordsPendingValues?: boolean        // value holds server-recorded items (uploads)
  beforeSubmit?: ( form: unknown, setLock: ( lock: BotLock ) => void, ctx: SubmitContext ) => void | Promise<void>
  afterSuccess?: ( form: unknown, action: unknown ) => boolean   // true = handled (e.g. redirected)
}

export interface AdminPage {
  path: string
  title: string
  Component: ComponentType<any>
}

export interface AdminSettingsSection {
  id: string
  title: string
  Component: ComponentType<any>
}

// Props core hands an editor panel. One panel is open at a time, and opening
// one closes the Fields/Actions/Settings sidebar (and vice versa).
export interface EditorPanelProps {
  isOpen: boolean
  open: () => void
  close: () => void
  form: any                             // the form being edited
  replaceForm: ( form: any ) => void    // swaps in a whole form; the edited form keeps its id
}

// A panel docked to the right of the form editor. The component renders both
// its own launcher (shown while closed) and the panel itself.
export interface EditorPanel {
  id: string
  Component: ComponentType<EditorPanelProps>
}

export interface AdminParts {
  headerItems?: ComponentType<any>[]
  settingsSections?: AdminSettingsSection[]
  pages?: AdminPage[]
  editorPanels?: EditorPanel[]
}

export interface RegisteredAddon {
  name: string
  component: PublicPart
  editor?: Record<string, EditorPart>   // keyed by component name
  admin?: AdminParts
}
