import {
  Accordion,
  AccordionDetails,
  AccordionSummary,
  LinearProgress,
} from '@mui/material'
import { styles } from './styles'
import { Title } from './components/title'
import type { WrapperState, WrapperUIProps } from './types'
import { Options } from './components/options'
import { Actions } from './components/actions'
import { useWidgetSelector } from '../stores/use-widget-selector'

const EMPTY_ACTIONS: NonNullable<WrapperUIProps['actions']> = []
const EMPTY_OPTIONS: NonNullable<WrapperUIProps['options']> = []

/**
 * Presentational wrapper component that renders the widget accordion UI with title, actions, options menu, and loading indicator. For uncontrolled usage without automatic widget store synchronization, use this instead of WidgetWrapper.
 *
 * @example
 * ```tsx
 * <WrapperUI
 *   id="my-widget"
 *   actions={[<Download key="download" id="my-widget" />]}
 *   onChangeCollapsed={(e, collapsed) => console.log(collapsed)}
 * >
 *   <div>Content</div>
 * </WrapperUI>
 * ```
 */
export function WrapperUI({
  children,
  id,
  actions = EMPTY_ACTIONS,
  sx,
  labels,
  options = EMPTY_OPTIONS,
  onChangeCollapsed,
}: WrapperUIProps) {
  // Single consolidated subscription instead of 4 separate ones.
  const { title, collapsed, disabled, isFetching } = useWidgetSelector(
    id,
    (w) => {
      return {
        title: (w as WrapperState | undefined)?.title,
        collapsed: (w as WrapperState | undefined)?.collapsed,
        disabled: (w as WrapperState | undefined)?.disabled,
        isFetching: w?.isFetching,
      }
    },
  )

  return (
    <Accordion
      className={collapsed ? 'collapsed' : ''}
      sx={{ ...styles.root, ...sx }}
      expanded={!collapsed}
      onChange={onChangeCollapsed}
      disabled={disabled}
    >
      <AccordionSummary sx={styles.summary}>
        {isFetching && <LinearProgress sx={styles.loading} color='primary' />}
        <Title>{title}</Title>
        {!!actions.length && <Actions actions={actions} />}
        {!!options.length && (
          <Options labels={labels?.options} options={options} />
        )}
      </AccordionSummary>
      <AccordionDetails sx={styles.detail}>{children}</AccordionDetails>
    </Accordion>
  )
}
