import React from 'react'

import { AuthenticationContext, IPAddress, ProposalDataContext } from '@agiliza/api/domain'
import ImageUpload from '@agiliza/components/organisms/ImageUpload'
import AddressTemplate from '@agiliza/components/templates/Address'
import { ActionType } from '@agiliza/utils/hooks/state'
import { extractNumbers, getBase64FromFile } from '@agiliza/utils/method'
import { SelectField, SelectFieldProps, Switch } from '@curio/components'
import {
  Checkbox,
  CheckboxProps,
  FormControlLabel,
  FormGroup,
  TextField,
  TextFieldProps
} from '@material-ui/core'
import { withStyles, WithStyles } from '@material-ui/core/styles'

import { CDHomeState } from '../state'
import styles from './styles'

type ExtendedProps = WithStyles<typeof styles>

interface Props extends ExtendedProps {
  addressContext: AuthenticationContext
  state: CDHomeState
  actions: ActionType<CDHomeState>
  context: ProposalDataContext
}

const Form = (props: Props) => {
  const { classes, addressContext, context, state, actions } = props
  const { states, cities } = addressContext
  const { resideTime, cityResideTime, address, hasProperty, deed, type, deedRecord, reside, hasOnus } = state

  const handleChangeText =
    (key: keyof CDHomeState): TextFieldProps['onChange'] =>
    (evt) => {
      actions.update({ [key]: evt.target.value })
    }

  const handleChangeProof: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>['onChange'] = async (evt) => {
    const file = evt.target.files && evt.target.files[0]
    if (file) {
      const b64: string = await getBase64FromFile(file)
      actions.update({ deed: b64 })
    }
  }

  const handleChangeSelect =
    (key: keyof CDHomeState): SelectFieldProps['onChange'] =>
    (vl) => {
      actions.update({ [key]: vl })
    }

  const handleChangeCheckbox =
    (key: keyof Pick<CDHomeState, 'reside' | 'hasOnus'>): CheckboxProps['onChange'] =>
    (_, checked) => {
      actions.update({ [key]: checked })
    }

  return (
    <form className={classes.form}>
      <Switch label="Possui imóveis?" value={hasProperty} onChange={(vl) => actions.update({ hasProperty: vl })} required />
      {hasProperty ? (
        <>
          <ImageUpload label="Escritura" image={deed} onChangeImage={handleChangeProof} />
          <SelectField
            id="type-select-field"
            label="Tipo"
            value={type}
            onChange={handleChangeSelect('type')}
            items={context.homeTypes.map((hT) => ({ label: hT.description, value: hT.id }))}
            variant="outlined"
            shrink={false}
          />
          <SelectField
            id="deed-record-select-field"
            label="Registro da escritura"
            value={deedRecord}
            onChange={handleChangeSelect('deedRecord')}
            items={context.deedRecords.map((dR) => ({ label: dR.description, value: dR.id }))}
            variant="outlined"
            shrink={false}
          />
          <FormGroup row className={classes.formGroup}>
            <FormControlLabel
              control={<Checkbox name="reside" checked={reside} onChange={handleChangeCheckbox('reside')} />}
              label="Reside no imóvel?"
            />
            <FormControlLabel
              control={<Checkbox name="reside" checked={hasOnus} onChange={handleChangeCheckbox('hasOnus')} />}
              label="Possui ônus?"
            />
          </FormGroup>
          <TextField
            variant="outlined"
            label="Tempo (no local)"
            value={extractNumbers(resideTime)}
            onChange={handleChangeText('resideTime')}
            type="number"
          />
          <TextField
            variant="outlined"
            label="Tempo (no município)"
            value={extractNumbers(cityResideTime)}
            onChange={handleChangeText('cityResideTime')}
            type="number"
          />
          <AddressTemplate states={states} cities={cities} state={address} onChange={(addrs) => actions.update({ address: addrs as IPAddress })} />
        </>
      ) : null}
    </form>
  )
}

export default withStyles(styles)(Form)
