import { connect } from 'react-redux'
import { bindActionCreators, Dispatch } from 'redux'

import { AuthenticationContext } from '@agiliza/api/domain'
import { StoreState } from '@agiliza/redux'
import * as entAuthentication from '@agiliza/redux/entities/authentication'
import * as uiLogin from '@agiliza/redux/ui/login'
import * as ucAuthentication from '@agiliza/redux/useCases/authentication'

export interface ConnectedProps {
  fetching: boolean
  sendingCode: boolean
  context: AuthenticationContext
  getContext: typeof ucAuthentication.actions.getContext
  verifyCPF: typeof ucAuthentication.actions.verifyCPF
  createCustomer: typeof ucAuthentication.actions.createCustomer
  sendCode: typeof ucAuthentication.actions.sendCode
  verifyCode: typeof ucAuthentication.actions.verifyCode
  createPassword: typeof ucAuthentication.actions.createPassword
  login: typeof uiLogin.actions.login
}

type StateProps = Pick<ConnectedProps, 'fetching' | 'context' | 'sendingCode'>
type DispatchProps = Pick<ConnectedProps, 'getContext' | 'verifyCPF' | 'createCustomer' | 'verifyCode' | 'createPassword' | 'sendCode' | 'login'>

const mapStateToProps = (state: StoreState): StateProps => ({
  fetching: ucAuthentication.selectors.isFetching(state.useCases.authentication),
  context: entAuthentication.selectors.getContextEntities(state.entities.authentication),
  sendingCode: ucAuthentication.selectors.isSendingCode(state.useCases.authentication),
})

const mapDispatchToProps = (dispatch: Dispatch): DispatchProps =>
  bindActionCreators(
    {
      getContext: ucAuthentication.actions.getContext,
      verifyCPF: ucAuthentication.actions.verifyCPF,
      createCustomer: ucAuthentication.actions.createCustomer,
      sendCode: ucAuthentication.actions.sendCode,
      verifyCode: ucAuthentication.actions.verifyCode,
      createPassword: ucAuthentication.actions.createPassword,
      login: uiLogin.actions.login,
    },
    dispatch
  )

export const connected = connect(mapStateToProps, mapDispatchToProps)
