import { useSelector } from "react-redux";

import {
  AbilityUtils as abilityUtils,
  AccessUtils as accessUtils,
  ActionUtils as actionUtils,
  ActivationUtils as activationUtils,
  ApiAdapterUtils as apiAdapterUtils,
  BackgroundUtils as backgroundUtils,
  CampaignUtils as campaignUtils,
  CampaignSettingUtils as campaignSettingUtils,
  CharacterUtils as characterUtils,
  ChoiceUtils as choiceUtils,
  ClassFeatureUtils as classFeatureUtils,
  ClassUtils as classUtils,
  ConditionUtils as conditionUtils,
  ConditionLevelUtils as conditionLevelUtils,
  ContainerUtils as containerUtils,
  CoreUtils as coreUtils,
  CreatureUtils as creatureUtils,
  CreatureRuleUtils as creatureRuleUtils,
  DataOriginUtils as dataOriginUtils,
  DecorationUtils as decorationUtils,
  DefinitionUtils as definitionUtils,
  DefinitionPoolUtils as definitionPoolUtils,
  DiceUtils as diceUtils,
  DurationUtils as durationUtils,
  EntityUtils as entityUtils,
  ExtraUtils as extraUtils,
  FeatUtils as featUtils,
  FeatureFlagInfoUtils as featureFlagInfoUtils,
  FeatureUtils as featureUtils,
  FormatUtils as formatUtils,
  HelperUtils as helperUtils,
  InfusionChoiceUtils as infusionChoiceUtils,
  InfusionUtils as infusionUtils,
  ItemUtils as itemUtils,
  KnownInfusionUtils as knownInfusionUtils,
  LimitedUseUtils as limitedUseUtils,
  ModifierUtils as modifierUtils,
  NoteUtils as noteUtils,
  OptionalClassFeatureUtils as optionalClassFeatureUtils,
  OptionalOriginUtils as optionalOriginUtils,
  OptionUtils as optionUtils,
  OrganizationUtils as organizationUtils,
  PdfUtils as pdfUtils,
  PrerequisiteUtils as prerequisiteUtils,
  RaceUtils as raceUtils,
  RacialTraitUtils as racialTraitUtils,
  RuleDataUtils as ruleDataUtils,
  RuleDataPoolUtils as ruleDataPoolUtils,
  SkillUtils as skillUtils,
  SnippetUtils as snippetUtils,
  SourceUtils as sourceUtils,
  SpellUtils as spellUtils,
  StartingEquipmentUtils as startingEquipmentUtils,
  ValueUtils as valueUtils,
  VehicleUtils as vehicleUtils,
  VehicleComponentUtils as vehicleComponentUtils,
  apiCreatorSelectors as api,
  rulesEngineSelectors as s,
  FeatList,
  characterSelectors as char,
  characterActions,
  serviceDataSelectors as sds,
  serviceDataActions,
} from "@dndbeyond/character-rules-engine";

/**
 * A hook that provides access to the character rules engine state without
 * having to import rules engine all over the place in your components. This
 * reduces touchpoints to the rules engine and makes it easier to refactor the
 * rules engine in the future.
 */
export const useCharacterEngine = () => ({
  // Character Actions
  characterActions,
  serviceDataActions,
  // Character Selectors that aren't passed thru to Rules Engine Selectors
  characterStatusSlug: useSelector(char.getStatusSlug),
  // Rules Engine Selector Values
  abilities: useSelector(s.getAbilities),
  abilityLookup: useSelector(s.getAbilityLookup),
  abilityKey: useSelector(s.getAbilityKeyLookup),
  actionLookup: useSelector(s.getActionLookup),
  acAdjustments: useSelector(s.getAcAdjustments),
  acSuppliers: useSelector(s.getArmorClassSuppliers),
  acTotal: useSelector(s.getAcTotal),
  actions: useSelector(s.getActions),
  activatables: useSelector(s.getActivatables),
  activeCharacterSpells: useSelector(s.getActiveCharacterSpells),
  activeClassSpells: useSelector(s.getActiveClassSpells),
  activeConditions: useSelector(s.getActiveConditions),
  activeGroupedImmunities: useSelector(s.getActiveGroupedImmunities),
  activeGroupedResistances: useSelector(s.getActiveGroupedResistances),
  activeGroupedVulnerabilities: useSelector(s.getActiveGroupedVulnerabilities),
  activeImmunities: useSelector(s.getActiveImmunities),
  activeResistances: useSelector(s.getActiveResistances),
  activeVulnerabilities: useSelector(s.getActiveVulnerabilities),
  activeSource: useSelector(s.getActiveSourceLookup),
  activeSourceCategories: useSelector(s.getActiveSourceCategories),
  activeSources: useSelector(s.getActiveSources),
  activeSpellAttackList: useSelector(s.getActiveSpellAttackList),
  advantageSavingThrowModifiers: useSelector(
    s.getAdvantageSavingThrowModifiers
  ),
  alignment: useSelector(s.getAlignment),
  allInventoryItems: useSelector(s.getAllInventoryItems),
  armorSpeedAdjustmentAmount: useSelector(s.getArmorSpeedAdjustmentAmount),
  attacks: useSelector(s.getAttacks),
  attacksPerActionInfo: useSelector(s.getAttacksPerActionInfo),
  attunedItems: useSelector(s.getAttunedItems),
  attunedItemCountMax: useSelector(s.getAttunedItemCountMax),
  attunedSlots: useSelector(s.getAttunedSlots),
  availableInfusionChoices: useSelector(s.getAvailableInfusionChoices),
  availablePactMagicSlotLevels: useSelector(s.getAvailablePactMagicSlotLevels),
  availableSpellSlotLevels: useSelector(s.getAvailableSpellSlotLevels),
  backgroundChoice: useSelector(s.getBackgroundChoiceLookup),
  backgroundInfo: useSelector(s.getBackgroundInfo),
  backgroundModifier: useSelector(s.getBackgroundModifierLookup),
  backgroundModifiers: useSelector(s.getBackgroundModifiers),
  baseClass: useSelector(s.getBaseClassLookup),
  baseFeat: useSelector(s.getBaseFeatLookup),
  baseFeats: useSelector(s.getBaseFeats),
  bonusSavingThrowModifiers: useSelector(s.getBonusSavingThrowModifiers),
  campaign: useSelector(s.getCampaign),
  campaignSettings: useSelector(sds.getCampaignSettings),
  carryingCapacity: useSelector(s.getCarryCapacity),
  castableSpellSlotLevels: useSelector(s.getCastableSpellSlotLevels),
  castablePactMagicSlotLevels: useSelector(s.getCastablePactMagicSlotLevels),
  characterConfig: useSelector(s.getCharacterConfiguration),
  characterGender: useSelector(s.getGender),
  characterId: useSelector(s.getId),
  characterInventoryContainers: useSelector(s.getCharacterInventoryContainers),
  characterName: useSelector(s.getName),
  characterNotes: useSelector(s.getCharacterNotes),
  characterSpells: useSelector(s.getCharacterSpells),
  characterTheme: useSelector(s.getCharacterTheme),
  characterTraits: useSelector(s.getCharacterTraits),
  choiceInfo: useSelector(s.getChoiceInfo),
  classAction: useSelector(s.getClassActionLookup),
  classAlwaysKnownSpells: useSelector(sds.getClassAlwaysKnownSpells),
  classAlwaysPreparedSpells: useSelector(sds.getClassAlwaysPreparedSpells),
  classChoice: useSelector(s.getClassChoiceLookup),
  classCreatureRules: useSelector(s.getClassCreatureRules),
  classFeature: useSelector(s.getClassFeatureLookup),
  classMappingId: useSelector(s.getClassMappingIdLookupByActiveId),
  classModifier: useSelector(s.getClassModifierLookup),
  classOption: useSelector(s.getClassOptionLookup),
  classSpell: useSelector(s.getClassSpellLookup),
  classSpells: useSelector(s.getClassSpells),
  classSpellInfo: useSelector(s.getClassSpellInfoLookup),
  classSpellLists: useSelector(s.getClassSpellLists),
  classSpellListSpells: useSelector(s.getClassSpellListSpellsLookup),
  classes: useSelector(s.getClasses),
  classesModifiers: useSelector(s.getClassesModifiers),
  combinedMaxSpellSlotLevel: useSelector(s.getCombinedMaxSpellSlotLevel),
  combinedSpellSlots: useSelector(s.getCombinedSpellSlots),
  conModifier: useSelector(s.getConModifier),
  conditionImmunityData: useSelector(s.getConditionImmunityData),
  conditionModifier: useSelector(s.getConditionModifierLookup),
  conditionModifiers: useSelector(s.getConditionModifiers),
  container: useSelector(s.getContainerLookup),
  containerCoinWeight: useSelector(s.getCointainerCoinWeight),
  containerItemWeight: useSelector(s.getContainerItemWeight),
  containerLookup: useSelector(s.getContainerLookup),
  creature: useSelector(s.getCreatureLookup),
  creatureGroupRules: useSelector(s.getCreatureGroupRulesLookup),
  creatureInfusion: useSelector(s.getCreatureInfusionLookup),
  creatureOwnerData: useSelector(s.getCreatureOwnerData),
  creatureRules: useSelector(s.getCreatureRules),
  creatures: useSelector(s.getCreatures),
  currentCarriedWeightSpeed: useSelector(s.getCurrentCarriedWeightSpeed),
  currentCarriedWeightType: useSelector(s.getCurrentCarriedWeightType),
  currentLevel: useSelector(s.getCurrentLevel),
  currentXp: useSelector(s.getCurrentXp),
  currentLevelRacialTraits: useSelector(s.getCurrentLevelRacialTraits),
  customActions: useSelector(s.getCustomActions),
  customConditionAdjustments: useSelector(s.getCustomConditionAdjustments),
  customDamageAdjustments: useSelector(s.getCustomDamageAdjustments),
  customItems: useSelector(s.getCustomItems),
  customImmunityDamageAdjustments: useSelector(
    s.getCustomImmunityDamageAdjustments
  ),
  customResistanceDamageAdjustments: useSelector(
    s.getCustomResistanceDamageAdjustments
  ),
  customVulnerabilityDamageAdjustments: useSelector(
    s.getCustomVulnerabilityDamageAdjustments
  ),
  customSkills: useSelector(s.getCustomSkills),
  customSkillProficiencies: useSelector(s.getCustomSkillProficiencies),
  damageImmunityData: useSelector(s.getDamageImmunityData),
  deathSaveInfo: useSelector(s.getDeathSaveInfo),
  deathCause: useSelector(s.getDeathCause),
  decorationInfo: useSelector(s.getDecorationInfo),
  dedicatedWeaponEnabled: useSelector(s.getDedicatedWeaponEnabled),
  definitionPool: useSelector(sds.getDefinitionPool),
  dexModifier: useSelector(s.getDexModifier),
  disadvantageSavingThrowModifiers: useSelector(
    s.getDisadvantageSavingThrowModifiers
  ),
  encumberedWeight: useSelector(s.getEncumberedWeight),
  entityRestrictionData: useSelector(s.getEntityRestrictionData),
  entityValueLookup: useSelector(s.getCharacterValueLookupByEntity),
  equippedItems: useSelector(s.getEquippedItems),
  experienceInfo: useSelector(s.getExperienceInfo),
  expertiseModifiers: useSelector(s.getExpertiseModifiers),
  extras: useSelector(s.getExtras),
  featLookup: useSelector(s.getFeatLookup),
  feats: useSelector(s.getFeats),
  featAction: useSelector(s.getFeatActionLookup),
  featCreatureRules: useSelector(s.getFeatCreatureRules),
  featModifier: useSelector(s.getFeatModifierLookup),
  featModifiers: useSelector(s.getFeatModifiers),
  featOption: useSelector(s.getFeatOptionLookup),
  featChoice: useSelector(s.getFeatChoiceLookup),
  gearWeaponItems: useSelector(s.getGearWeaponItems),
  hasInitiativeAdvantage: useSelector(s.getHasInitiativeAdvantage),
  hasMaxAttunedItems: useSelector(s.hasMaxAttunedItems),
  hasSpells: useSelector(s.hasSpells),
  heavilyEncumberedWeight: useSelector(s.getHeavilyEncumberedWeight),
  hexWeaponEnabled: useSelector(s.getHexWeaponEnabled),
  highestEquippedArmorAC: useSelector(s.getHighestAcEquippedArmor),
  highestEquippedShieldAC: useSelector(s.getHighestAcEquippedShield),
  hpInfo: useSelector(s.getHitPointInfo),
  improvedPactWeaponEnabled: useSelector(s.getImprovedPactWeaponEnabled),
  infusions: useSelector(s.getInfusions),
  infusionChoices: useSelector(s.getInfusionChoices),
  infusionChoiceLookup: useSelector(s.getInfusionChoiceLookup),
  infusionChoiceInfusion: useSelector(s.getInfusionChoiceInfusionLookup),
  infusionMappings: useSelector(sds.getInfusionsMappings),
  innateNaturalActions: useSelector(s.getInnateNaturalActions),
  inventory: useSelector(s.getInventory),
  inventoryContainers: useSelector(s.getInventoryContainers),
  inventoryLookup: useSelector(s.getInventoryLookup),
  inventoryInfusion: useSelector(s.getInventoryInfusionLookup),
  isSheetReady: useSelector(s.isCharacterSheetReady),
  isDead: useSelector(s.isDead),
  isMulticlassCharacter: useSelector(s.isMulticlassCharacter),
  itemAttacks: useSelector(s.getItemAttacks),
  itemModifier: useSelector(s.getItemModifierLookup),
  itemSpell: useSelector(s.getItemSpellLookup),
  kenseiModifiers: useSelector(s.getKenseiModifiers),
  knownInfusion: useSelector(s.getKnownInfusionLookup),
  knownInfusionByChoice: useSelector(s.getKnownInfusionLookupByChoiceKey),
  knownInfusions: useSelector(s.getKnownInfusions),
  knownInfusionMappings: useSelector(sds.getKnownInfusionsMappings),
  knownReplicatedItems: useSelector(s.getKnownReplicatedItems),
  languages: useSelector(s.getLanguages),
  languageModifiers: useSelector(s.getLanguageModifiers),
  levelSpells: useSelector(s.getLevelSpells),
  lifestyle: useSelector(s.getLifestyle),
  loadSpecies: useSelector(api.makeLoadAvailableRaces),
  maxPactMagicSlotLevel: useSelector(s.getMaxPactMagicSlotLevel),
  maxSpellSlotLevel: useSelector(s.getMaxSpellSlotLevel),
  miscModifiers: useSelector(s.getMiscModifiers),
  modifierData: useSelector(s.getModifierData),
  optionalClassFeature: useSelector(s.getOptionalClassFeatureLookup),
  optionalClassFeatures: useSelector(s.getOptionalClassFeatures),
  optionalOrigin: useSelector(s.getOptionalOriginLookup),
  optionalOrigins: useSelector(s.getOptionalOrigins),
  originRef: useSelector(s.getDataOriginRefData),
  originRefBackground: useSelector(s.getDataOriginRefBackgroundData),
  originRefClass: useSelector(s.getDataOriginRefClassData),
  originRefCondition: useSelector(s.getDataOriginRefConditionData),
  originRefFeat: useSelector(s.getDataOriginRefFeatData),
  originRefFeatList: useSelector(s.getDataOriginRefFeatListData),
  originRefItem: useSelector(s.getDataOriginRefItemData),
  originRefRace: useSelector(s.getDataOriginRefRaceData),
  originRefVehicle: useSelector(s.getDataOriginRefVehicleData),
  overallSpellInfo: useSelector(s.getOverallSpellInfo),
  overridePassiveInsight: useSelector(s.getOverridePassiveInsight),
  overridePassiveInvestigation: useSelector(s.getOverridePassiveInvestigation),
  overridePassivePerception: useSelector(s.getOverridePassivePerception),
  pactMagicConditiones: useSelector(s.getPactMagicClasses),
  pactMagicSlots: useSelector(s.getPactMagicSlots),
  pactWeaponEnabled: useSelector(s.getPactWeaponEnabled),
  partyInfo: useSelector(sds.getPartyInfo),
  partyInventory: useSelector(s.getPartyInventory),
  partyInventoryContainers: useSelector(s.getPartyInventoryContainers),
  partyInventoryItem: useSelector(s.getPartyInventoryLookup),
  passiveInsight: useSelector(s.getPassiveInsight),
  passiveInvestigation: useSelector(s.getPassiveInvestigation),
  passivePerception: useSelector(s.getPassivePerception),
  pdfBucket1: useSelector(s.getPdfDataBucket1),
  pdfBucket2: useSelector(s.getPdfDataBucket2),
  pdfBucket3: useSelector(s.getPdfDataBucket3),
  pdfBucket4: useSelector(s.getPdfDataBucket4),
  pdfBucket5: useSelector(s.getPdfDataBucket5),
  pdfBucket6: useSelector(s.getPdfDataBucket6),
  pdfExportData: useSelector(s.getPdfExportData),
  playerId: useSelector(s.getUserId),
  playerName: useSelector(s.getUsername),
  preferences: useSelector(s.getCharacterPreferences),
  prerequisiteData: useSelector(s.getPrerequisiteData),
  processedInitiative: useSelector(s.getProcessedInitiative),
  proficiency: useSelector(s.getProficiencyLookup),
  proficiencyBonus: useSelector(s.getProficiencyBonus),
  proficiencyGroups: useSelector(s.getProficiencyGroups),
  proficiencyModifiers: useSelector(s.getProficiencyModifiers),
  protectionSuppliers: useSelector(s.getProtectionSuppliers),
  pushDragLiftWeight: useSelector(s.getPushDragLiftWeight),
  race: useSelector(s.getRace),
  raceAction: useSelector(s.getRaceActionLookup),
  raceChoice: useSelector(s.getRaceChoiceLookup),
  raceCreatureRules: useSelector(s.getRaceCreatureRules),
  raceModifier: useSelector(s.getRaceModifierLookup),
  raceModifiers: useSelector(s.getRaceModifiers),
  raceOption: useSelector(s.getRaceOptionLookup),
  raceSpell: useSelector(s.getRaceSpellLookup),
  requiredCharacterServiceParams: useSelector(
    s.getRequiredCharacterServiceParams
  ),
  requiredGameDataServiceParams: useSelector(
    s.getRequiredGameDataServiceParams
  ),
  resistanceData: useSelector(s.getResistanceData),
  restrictedBonusSavingThrowModifiers: useSelector(
    s.getRestrictedBonusSavingThrowModifiers
  ),
  ritualSpells: useSelector(s.getRitualSpells),
  ruleData: useSelector(s.getRuleData),
  ruleDataPool: useSelector(sds.getRuleDataPool),
  savingThrowDiceAdjustments: useSelector(s.getSavingThrowDiceAdjustments),
  senseInfo: useSelector(s.getSenseInfo),
  situationalBonusSavingThrowsLookup: useSelector(
    s.getSituationalBonusSavingThrowsLookup
  ),
  situationalBonusSavingThrows: useSelector(s.getSituationalBonusSavingThrows),
  size: useSelector(s.getSize),
  skill: useSelector(s.getSkillLookup),
  skills: useSelector(s.getSkills),
  snippetData: useSelector(s.getSnippetData),
  socialImageData: useSelector(s.getSocialImageData),
  specialWeaponPropertiesEnabled: useSelector(
    s.hack__getSpecialWeaponPropertiesEnabled
  ),
  speeds: useSelector(s.getSpeeds),
  spellClasses: useSelector(s.getSpellClasses),
  spellcasterInfo: useSelector(s.getSpellCasterInfo),
  spellcastingClasses: useSelector(s.getSpellcastingClasses),
  spellListDataOrigin: useSelector(s.getSpellListDataOriginLookup),
  spellSlots: useSelector(s.getSpellSlots),
  startingClass: useSelector(s.getStartingClass),
  strScore: useSelector(s.getStrScore),
  totalCarriedWeight: useSelector(s.getTotalCarriedWeight),
  totalClassLevel: useSelector(s.getTotalClassLevel),
  uniqueProficiencyModifiers: useSelector(s.getUniqueProficiencyModifiers),
  validEquipmentModifiers: useSelector(s.getValidEquipmentModifiers),
  validGlobalModifiers: useSelector(s.getValidGlobalModifiers),
  validImmunityModifiers: useSelector(s.getValidImmunityModifiers),
  validResistanceModifiers: useSelector(s.getValidResistanceModifiers),
  validVulnerabilityModifiers: useSelector(s.getValidVulnerabilityModifiers),
  valueLookup: useSelector(s.getCharacterValueLookup),
  vehicle: useSelector(s.getVehicleLookup),
  vehicles: useSelector(s.getVehicles),
  vehicleComponent: useSelector(s.getVehicleComponentLookup),
  vehicleComponentMappings: useSelector(sds.getVehicleComponentMappings),
  vehicleMappings: useSelector(sds.getVehicleMappings),
  vulnerabilityData: useSelector(s.getVulnerabilityData),
  weaponSpellDamageGroups: useSelector(s.getWeaponSpellDamageGroups),
  weightSpeeds: useSelector(s.getWeightSpeeds),

  // Utility Functions
  abilityUtils,
  accessUtils,
  actionUtils,
  activationUtils,
  apiAdapterUtils,
  backgroundUtils,
  campaignUtils,
  campaignSettingUtils,
  characterUtils,
  choiceUtils,
  classFeatureUtils,
  classUtils,
  conditionUtils,
  conditionLevelUtils,
  containerUtils,
  coreUtils,
  creatureUtils,
  creatureRuleUtils,
  dataOriginUtils,
  decorationUtils,
  definitionUtils,
  definitionPoolUtils,
  diceUtils,
  durationUtils,
  entityUtils,
  extraUtils,
  featUtils,
  featureFlagInfoUtils,
  featureUtils,
  formatUtils,
  helperUtils,
  infusionChoiceUtils,
  infusionUtils,
  itemUtils,
  knownInfusionUtils,
  limitedUseUtils,
  modifierUtils,
  noteUtils,
  optionalClassFeatureUtils,
  optionalOriginUtils,
  optionUtils,
  organizationUtils,
  pdfUtils,
  prerequisiteUtils,
  raceUtils,
  racialTraitUtils,
  ruleDataUtils,
  ruleDataPoolUtils,
  skillUtils,
  snippetUtils,
  sourceUtils,
  spellUtils,
  startingEquipmentUtils,
  valueUtils,
  vehicleUtils,
  vehicleComponentUtils,

  // Misc
  FeatList,
});
