import * as React from "react"
import { useDispatch } from "react-redux"
import { ident } from "../../../Data/Function"
import { fmap } from "../../../Data/Functor"
import { consF, find, List, map, notNull } from "../../../Data/List"
import { bind, ensure, join, Just, liftM2, Maybe, maybe } from "../../../Data/Maybe"
import { Record } from "../../../Data/Record"
import { selectProfessionVariant } from "../../Actions/ProfessionVariantActions"
import { Sex } from "../../Models/Hero/heroTypeHelpers"
import { ProfessionCombined, ProfessionCombinedA_ } from "../../Models/View/ProfessionCombined"
import { ProfessionVariantCombined, ProfessionVariantCombinedA_ } from "../../Models/View/ProfessionVariantCombined"
import { RadioOption } from "../../Models/View/RadioOption"
import { StaticDataRecord } from "../../Models/Wiki/WikiModel"
import { translate, translateP } from "../../Utilities/I18n"
import { pipe, pipe_ } from "../../Utilities/pipe"
import { getNameBySex } from "../../Utilities/rcpUtils"
import { sortRecordsByName } from "../../Utilities/sortBy"
import { RadioButtonGroup } from "../Universal/RadioButtonGroup"

export interface ProfessionVariantsProps {
  currentProfessionId: Maybe<string>
  currentProfessionVariantId: Maybe<string>
  staticData: StaticDataRecord
  professions: Maybe<List<Record<ProfessionCombined>>>
  sex: Maybe<Sex>
}

const PCA = ProfessionCombined.A
const PCA_ = ProfessionCombinedA_
const PVCA_ = ProfessionVariantCombinedA_

export const ProfessionVariants: React.FC<ProfessionVariantsProps> = props => {
  const {
    currentProfessionId,
    currentProfessionVariantId,
    staticData,
    professions,
    sex: msex,
  } = props

  const dispatch = useDispatch ()

  const handleProfessionVariantSelect =
    React.useCallback (
      (id: Maybe<string>) => dispatch (selectProfessionVariant (id)),
      [ dispatch ]
    )

  const mvars =
    liftM2 ((sex: Sex) => (prof: Record<ProfessionCombined>) =>
             pipe_ (
               prof,
               PCA.mappedVariants,
               ensure (notNull),
               fmap (pipe (
                 map ((prof_var: Record<ProfessionVariantCombined>) => {
                   const name = getNameBySex (sex) (PVCA_.name (prof_var))
                   const ap = Maybe.sum (PCA_.ap (prof)) + PVCA_.ap (prof_var)

                   return RadioOption ({
                     name: translateP (staticData)
                                      ("general.withapvalue")
                                      (List<string | number> (name, ap)),
                     value: Just (PVCA_.id (prof_var)),
                   })
                 }),
                 sortRecordsByName (staticData),
                 PCA_.isVariantRequired (prof)
                   ? ident
                   : consF (RadioOption ({
                              name: translate (staticData) ("profession.variants.novariant"),
                            }))
               ))
             ))
           (msex)
           (bind (professions) (find (pipe (PCA_.id, Maybe.elemF (currentProfessionId)))))

  return maybe (<></>)
               ((vars: List<Record<RadioOption<string>>>) => (
                 <RadioButtonGroup
                   active={currentProfessionVariantId}
                   onClick={handleProfessionVariantSelect}
                   array={vars}
                   />
               ))
               (join (mvars))
}
