import type { ReactNode } from 'react'

import {
  Box,
  Center,
  Flex,
  type FlexProps,
  Paper,
  Stack,
  Title,
  type TitleProps,
  Tooltip,
  useMantineColorScheme,
} from '@mantine/core'
import React from 'react'

import classes from './InlineWapper.module.css'

interface InlineWrapperCallbackProps extends Partial<InlineWrapperPropsOnly> {
  classNames: React.CSSProperties
  dataCssProps?: Record<string, any>
  size: string
}

interface InlineWrapperProps extends InlineWrapperPropsOnly{
  children?: ((props: InlineWrapperCallbackProps) => ReactNode) | ReactNode
}
interface InlineWrapperPropsOnly {
  error?: ReactNode | string
  flexProps?: FlexProps
  label: ReactNode | string
  labelProps?: TitleProps
  promptArea?: ((props: InlineWrapperCallbackProps) => ReactNode) | ReactNode
  promptWidth?: FlexProps['w']
  required?: boolean
  rightSection?: ((props: InlineWrapperCallbackProps) => ReactNode) | ReactNode
  styles?: React.CSSProperties
  tooltip?: string
  value?: any
}

function InlineWrapper(props: InlineWrapperProps) {
  return (
    <Stack gap={0}>
      <Flex
        gap={0}
        h={undefined}
        m={0}
        mb={0}
        p={0}
        w={undefined}
        wrap='nowrap'
        {...props.flexProps}
        bg={'var(--input-background)'}
      >
        {props.promptWidth && props.promptWidth !== 0 ? <Prompt {...props} /> : null}
        <div
          style={{
            borderRadius: 0,
            flex: 10,
          }}
        >
          {typeof props.children === 'function' ? (
            props.children({ ...props, classNames: classes, size: 'xs' })
          ) : typeof props.children === 'object' && React.isValidElement(props.children) ? (
            <props.children.type classNames={classes} size='xs' {...(typeof props.children.props === "object" ? props.children.props : {})} />
          ) : (
            props.children
          )}
        </div>

        {!props.rightSection ? undefined : typeof props.rightSection === 'function' ? (
          props.rightSection({
            ...props,
            classNames: classes,
            size: 'xs',
          })
        ) : typeof props.rightSection === 'object' && React.isValidElement(props.rightSection) ? (
          <props.rightSection.type classNames={classes} size='xs' {...(typeof props.rightSection.props === "object" ? props.rightSection.props : {})} />
        ) : (
          props.rightSection
        )}
      </Flex>
      {/* <ErrorComponent {...props} /> */}
    </Stack>
  )
}

function isValueEmpty(inputValue: any) {
  if (inputValue === null || inputValue === undefined) return true
  if (typeof inputValue === 'number') {
    if (inputValue === 0) return false
  } else if (typeof inputValue === 'string' || inputValue === '') {
    return inputValue.trim() === ''
  } else if (inputValue instanceof File) {
    return inputValue.size === 0
  } else if (inputValue.target) {
    return isValueEmpty(inputValue.target?.value)
  } else if (inputValue.constructor?.name === 'Date') {
    return false
  }
}

function Prompt(props: Partial<InlineWrapperProps>) {
  return (
    <>
      {props.tooltip ? (
        <Tooltip label={props.tooltip}>
          <PromptDetail {...props} />
        </Tooltip>
      ) : (
        <PromptDetail {...props} />
      )}
    </>
  )
}

function PromptDetail(props: Partial<InlineWrapperProps>) {
  const colors = useColors(props)
  return props.promptArea ? (
    <Box maw={props.promptWidth} w={'100%'}>
      {!props.promptArea ? undefined : typeof props.promptArea === 'function' ? (
        props.promptArea({
          ...props,
          classNames: classes,
          dataCssProps: { 'data-promptArea': true },
          size: 'xs',
        })
      ) : typeof props.rightSection === 'object' && React.isValidElement(props.promptArea) ? (
        <props.promptArea.type
          classNames={classes}
          data-promptArea='true'
          size='xs'
          {...(typeof props.promptArea?.props === "object" ? props.promptArea.props : {})}
        />
      ) : (
        props.promptArea
      )}
    </Box>
  ) : (
    <Paper
      bg={colors.paperColor}
      className={classes.prompt}
      px='md'
      w={props.promptWidth}
      withBorder
    >
      <Center h='100%' style={{ justifyContent: 'start' }} w='100%'>
        <Title c={colors.titleColor} fz='xs' order={6} {...props.labelProps}>
          {props.label}
          {props.required && isValueEmpty(props.value) && <span style={{ color: 'red' }}>*</span>}
        </Title>
      </Center>
    </Paper>
  )
}

function useColors(props: Partial<InlineWrapperProps>) {
  const { colorScheme } = useMantineColorScheme()

  let titleColor = colorScheme === 'dark' ? 'dark.0' : 'gray.8'
  let paperColor = colorScheme === 'dark' ? 'dark.7' : 'gray.1'

  if (props.required && isValueEmpty(props.value)) {
    paperColor = colorScheme === 'dark' ? '#413012e7' : 'yellow.1'
  }

  if (props.error) {
    paperColor = colorScheme === 'dark' ? 'red.7' : 'red.0'
    titleColor = colorScheme === 'dark' ? 'red.0' : 'red.9'
  }
  return { paperColor, titleColor }
}

export { InlineWrapper }
export type { InlineWrapperProps }
