import { Box, Typography } from '@mui/material'
import { useWidgetSelector } from '../stores/use-widget-selector'
import type { WidgetNoDataProps } from './types'
import { styles } from './style'

/**
 * NoData wrapper component that displays empty state UI when widget has no data
 *
 * Integrates with widget store to check loading/fetching state and source data availability.
 * Uses `sourceData` (pre-pipeline data) instead of `data` (post-pipeline) to distinguish
 * "API returned nothing" from "pipeline tools filtered everything out".
 *
 * @example Basic usage
 * ```tsx
 * <NoData id="my-widget">
 *   <WidgetContent id="my-widget" />
 * </NoData>
 * ```
 *
 * @example With SkeletonLoader
 * ```tsx
 * <SkeletonLoader id="my-widget" Skeleton={MySkeleton}>
 *   <NoData id="my-widget">
 *     <WidgetContent id="my-widget" />
 *   </NoData>
 * </SkeletonLoader>
 * ```
 *
 * @example With custom messages
 * ```tsx
 * <NoData
 *   id="my-widget"
 *   title="No results found"
 *   description="Try adjusting your filters"
 * >
 *   <WidgetContent id="my-widget" />
 * </NoData>
 * ```
 */
export function WidgetNoData({
  id,
  children,
  title = 'No data available',
  description = 'There are no results for the combination of filters applied to your data. Try tweaking your filters, or zoom and pan the map to adjust filters',
  isEmpty = defaultIsEmpty,
}: WidgetNoDataProps) {
  // Single consolidated subscription instead of 3 separate ones.
  // Reads sourceData (pre-pipeline) to check emptiness, not data (post-pipeline).
  const { isLoading, isFetching, sourceData } = useWidgetSelector(id, (w) => ({
    isLoading: w?.isLoading,
    isFetching: w?.isFetching,
    sourceData: w?.sourceData,
  }))

  // If loading or fetching, show children
  // SkeletonLoader handles loading state, this allows proper composition
  if (isLoading || isFetching) {
    return children
  }

  // Check if data is empty
  if (isEmpty(sourceData)) {
    return (
      <Box sx={styles.root}>
        <Typography variant='body2' color='text.primary'>
          {title}
        </Typography>
        <Typography variant='caption' color='text.secondary'>
          {description}
        </Typography>
      </Box>
    )
  }

  // Data exists, render children
  return children
}

/**
 * Default function to determine if data is empty
 * Handles various data structures commonly used in widgets
 */
function defaultIsEmpty(data: unknown): boolean {
  // Null or undefined
  if (data == null) {
    return true
  }

  // Arrays (most common case)
  if (Array.isArray(data)) {
    // Empty array
    if (data.length === 0) {
      return true
    }

    // Array of arrays (CategoryWidget pattern: [[],[]])
    // Check if all inner arrays are empty
    if (data.every((item) => Array.isArray(item) && item.length === 0)) {
      return true
    }

    return false
  }

  // Objects
  if (typeof data === 'object') {
    return Object.keys(data).length === 0
  }

  // Primitives (numbers, strings, booleans) are considered valid data
  return false
}
