import React, { SetStateAction } from 'react'
import styled from 'styled-components'
import {  TextInput } from '../TextInput/TextInput'
import { PasswordInput } from '../PasswordInput/PasswordInput'
import { NumberInput } from '../NumberInput/NumberInput'
import { Checkbox } from '../Checkbox/Checkbox'
import { DatePicker } from '../DatePicker/DatePicker'
import { SelectInput } from '../SelectInput/SelectInput'
import { TextArea } from '../TextArea/TextArea'
import { TimePicker } from '../TimePicker/TimePicker'
import { Toggle } from '../Toggle/Toggle'
import { IJsonSchema } from '../../types/IJsonSchema'
import { PercentageInput } from '../PercentageInput/PercentageInput'

export type FormProps = {
  /**
   * schema for validation
   */
  jsonSchema?: IJsonSchema
  /**
   * values for form 
   */
  values: Record<string,unknown>
  /**
   * handling values for form
   */
  setValues: React.Dispatch<SetStateAction<{[key: string]: unknown}>>
  /**
   * custom styling
   */
   onEnterKeyDown?: () => void
  css?: string
}

export const Form = ({ jsonSchema,values,css,setValues,onEnterKeyDown }: FormProps):JSX.Element => {

  const handleKeyDown = (event:React.KeyboardEvent<HTMLFormElement>) => {
    if (event.key === 'Enter') 
      if(onEnterKeyDown) onEnterKeyDown()
  }

  return (
    <StyledForm onKeyDown={handleKeyDown} css={css}>
      {jsonSchema?.properties &&
        Object.entries(jsonSchema?.properties).map(([key, jsonSchema]) =>{
          if(values) {
            const inputValue = values[key]
            const { type, format } = jsonSchema
      
            const defaultProps = {
              name: key,
              key,
              label: key,
              jsonSchema,
              onChange: (change:unknown) => {
                if(values[key]!==change) setValues({ ...values,[key]:change })
              },
            }
            if (jsonSchema.enum?.length) 
              return (
                <SelectInput 
                  {...defaultProps}
                  options={(jsonSchema.enum).map(value=>({ value,label:String(value) }))}
                  placeholder="Select your option"
                  value={inputValue as string | number}
                />
              )
              
            else if (format === 'time') 
              return (
                <TimePicker
                  {...defaultProps}
                  value={inputValue as string}
                />
              )
              
            else if (format === 'password') 
              return (
                <PasswordInput
                  {...defaultProps}
                  value={inputValue as string}
                  placeholder={key}
                />
              )
            else if (type === 'string') 
              if (format === 'multi') 
                return (
                  <TextArea
                    {...defaultProps}
                    value={inputValue as string}
                    placeholder={key}
                  />
                )
              else 
                return (
                  <TextInput
                    {...defaultProps}
                    value={inputValue as string}
                    placeholder={key}
                  />
                )
              
            else if (type === 'number') 
              return (
                <NumberInput
                  {...defaultProps}
                  value={inputValue as number}
                  placeholder={key}
                />
              )
            else if (type === 'percentage')
              return (
                <PercentageInput 
                  {...defaultProps}
                  value={inputValue as number}
                  placeholder={key}
                />
              )
            
            else if (type === 'boolean') 
              if (format === 'switch') 
                return (
                  <Toggle
                    {...defaultProps}
                    value={inputValue as boolean}
                  />
                )
              
              else 
                return (
                  <Checkbox
                    {...defaultProps}
                    value={inputValue as boolean}
                  />
                )
              
            else if (type === 'date') 
              return (
                <DatePicker
                  {...defaultProps}
                  value={inputValue as string}
                />
              )
            
            throw new Error('type not recognised')
          }
      
        })}
    </StyledForm>
  )
}


export const StyledForm = styled.form<{css?:string}>`
  display:flex;
  flex-direction:column;
  gap:15px;
  width: 100%;
  ${(p) => p.css}
`
