import * as React from 'react'
import { ThemedCssFunction } from 'styled-components'
import { Highlight, Input, Label as StyledLabel, Wrapper } from './styles'

export type RenderProps = {
  invalid?: boolean
  placeholder?: string
  value?: any
  labelCss?: ThemedCssFunction<any> | string
  inputCss?: ThemedCssFunction<any> | string
  highlightCss?: ThemedCssFunction<any> | string
  highlightProps: HighlightProps
  inputProps: InputProps
  labelProps: LabelProps
}

export type InputProps = {
  invalid?: boolean
  name?: string
  value?: number | string

  css?: ThemedCssFunction<any> | string

  onChange?: (e: React.SyntheticEvent) => void
}

export type HighlightProps = {
  invalid?: boolean
  css?: ThemedCssFunction<any> | string
}

export type LabelProps = {
  isEmpty?: boolean
  children: React.ReactNode
  css?: ThemedCssFunction<any> | string
}

export type WrapperProps = {
  onClick?: (e: React.SyntheticEvent) => void
  css?: ThemedCssFunction<WrapperProps> | string
  className?: string
  style?: React.CSSProperties
  value?: any
  invalid?: boolean
  isEmpty?: boolean
  id?: string
}

type TextInputProps = {
  className?: string
  id?: string
  invalid?: boolean
  name?: string
  placeholder?: string
  readOnly?: boolean
  style?: React.CSSProperties
  value?: any

  css?: ThemedCssFunction<WrapperProps> | string
  highlightCss?: ThemedCssFunction<any> | string
  inputCss?: ThemedCssFunction<any> | string
  labelCss?: ThemedCssFunction<any> | string

  renderHighlight?: React.SFC<RenderProps>
  renderInput?: React.SFC<RenderProps>
  renderLabel?: React.SFC<RenderProps>

  onChange?: (e: React.SyntheticEvent) => void
  onClick?: (e: React.SyntheticEvent) => void
}

const defaultRenderInput: React.SFC<RenderProps> = ({ inputProps, ...rest }) => (
  <Input {...inputProps} {...rest} />
)

const defaultRenderHighlight: React.SFC<RenderProps> = ({ highlightProps }) => (
  <Highlight {...highlightProps} />
)

const defaultRenderLabel: React.SFC<RenderProps> = ({ labelProps }) => (
  <StyledLabel {...labelProps} />
)

export class TextInput extends React.PureComponent<TextInputProps> {
  static defaultProps = {
    type: 'text',
    invalid: false,
    placeholder: '',
    renderInput: defaultRenderInput,
    renderHighlight: defaultRenderHighlight,
    renderLabel: defaultRenderLabel,
  }

  static Input = Input
  static Highlight = Highlight
  static Label = StyledLabel

  render() {
    const {
      placeholder,
      onChange,
      onClick,
      value,
      invalid,
      id,
      name,
      className,
      style,
      renderInput,
      renderHighlight,
      renderLabel,
      css,
      labelCss,
      inputCss,
      highlightCss,
      children,
      ...rest
    } = this.props
    const isEmpty = !value

    const renderProps = {
      placeholder,
      value,
      invalid,
      labelCss,
      inputCss,
      highlightCss,
      isEmpty,
      ...rest,
    }
    const wrapperProps: WrapperProps = {
      value,
      invalid,
      isEmpty,
      id,
      css,
      className,
      style,
      onClick,
    }
    const highlightProps = {
      invalid,
      css: highlightCss,
    }
    const inputProps = {
      name,
      value,
      invalid,
      onChange,
      css: inputCss,
    }
    const labelProps = {
      isEmpty,
      css: labelCss,
      children: placeholder,
    }
    const allCollected = {
      inputProps,
      highlightProps,
      labelProps,
      ...renderProps,
    }
    return (
      <Wrapper {...wrapperProps}>
        {renderInput!(allCollected)}
        {renderHighlight!(allCollected)}
        {renderLabel!(allCollected)}
      </Wrapper>
    )
  }
}
