import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import {
  migrateProperty
} from './dbv1.js';
import {
  assert
} from 'chai';
import LibraryNodes from '/imports/api/library/LibraryNodes.js';

const exampleAction = {
  '_id': 'hY5MKZ4ivaoTRpNWy',
  'actionType': 'bonus',
  'target': 'singleTarget',
  'tags': [],
  'resources': {
    'itemsConsumed': [],
    'attributesConsumed': [{
      '_id': 'FaK6jXEj3pSe7mNuu',
      'quantity': '1',
      'variableName': 'HunterTech',
      'statName': 'Hunter\'s Technique',
      'available': 5
    }],
  },
  'type': 'action',
  'name': 'Hexblade\\\'s Curse',
  'parent': {
    'id': 'JqtDmqa5Zd3xpts5G',
    'collection': 'creatureProperties'
  },
  'ancestors': [{
    'collection': 'creatures',
    'id': 'X9rzFhsgFhodYfHmG'
  },],
  'order': 315,
  'summary': 'Curse a creature for 1 minute. The curse ends early if {warlock.level >14 ? "" : "the target dies, or"} you are incapacitated. \nGain the following benefits:  \n- *Bonus to damage rolls against the cursed target of* **+{proficiencyBonus}**. \n- Any attack roll you make against the cursed target is a **critical hit on a roll of 19 or 20**. \n- If the cursed target dies, you **regain {warlock.level+charisma.modifier} hit points**.  \n{warlock.level <9 ? "" : "- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses."}',
  'uses': '1',
  'usesResult': 1,
  'reset': 'shortRest',
  'usesUsed': 0,
  'description': 'Starting at 1st level, you gain the ability to place a baleful curse on someone. As a bonus action, choose one creature you can see within 30 feet of you. The target is cursed for 1 minute. The curse ends early if the target dies, you die, or you are incapacitated. Until the curse ends, you gain the following benefits:\n\n- You gain a bonus to damage rolls against the cursed target. The bonus equals your proficiency bonus.\n- Any attack roll you make against the cursed target is a critical hit on a roll of 19 or 20 on the d20.\n- If the cursed target dies, you regain hit points equal to your warlock level + your Charisma modifier (minimum of 1 hit point).  \n{warlock.level <10 ? "" :"- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses."}  \nYou can\\\'t use this feature again until you finish a short or long rest.',
  'color': '#8e24aa',
  'descriptionCalculations': [{
    'calculation': 'warlock.level <10 ? "" :"- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses."',
    'result': '- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses.'
  }],
  'summaryCalculations': [{
    'calculation': 'warlock.level >14 ? "" : "the target dies, or"',
    'result': 'the target dies, or'
  },
  {
    'calculation': 'proficiencyBonus',
    'result': '4'
  },
  {
    'calculation': 'warlock.level+charisma.modifier',
    'result': '15'
  },
  {
    'calculation': 'warlock.level <9 ? "" : "- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses."',
    'result': '- If you are hit with an attack by your cursed target, use your reaction to roll a d6. On a 4 or higher, the attack instead misses.'
  }
  ]
};

const exampleAttribute = {
  _id: 'idRWyoj5oxCv73feM',
  name: 'Hit Dice',
  variableName: 'clericHitDice',
  attributeType: 'hitDice',
  type: 'attribute',
  hitDiceSize: 'd8',
  baseValueCalculation: 'cleric.level',
  parent: {
    'id': '8jSWKxvgQyKbunFtD',
    'collection': 'creatureProperties'
  },
  ancestors: [{
    'collection': 'creatures',
    'id': 'm9sdCvs6iDf7qRaGv'
  },
  {
    'id': '8jSWKxvgQyKbunFtD',
    'collection': 'creatureProperties'
  }
  ],
  order: 84,
  value: 20,
  tags: [],
  baseValue: 20,
  damage: 3,
  currentValue: 17,
  constitutionMod: 2,
  dependencies: ['8jSWKxvgQyKbunFtD', 'qPP5yQXPxS7uhuXo3']
};

const expectedMigratedAttribute = {
  _id: 'idRWyoj5oxCv73feM',
  name: 'Hit Dice',
  variableName: 'clericHitDice',
  attributeType: 'hitDice',
  type: 'attribute',
  hitDiceSize: 'd8',
  baseValue: {
    calculation: 'cleric.level',
    value: 20
  },
  parent: {
    'id': '8jSWKxvgQyKbunFtD',
    'collection': 'creatureProperties'
  },
  ancestors: [{
    'collection': 'creatures',
    'id': 'm9sdCvs6iDf7qRaGv'
  },
  {
    'id': '8jSWKxvgQyKbunFtD',
    'collection': 'creatureProperties'
  }
  ],
  order: 84,
  total: 20,
  tags: [],
  damage: 3,
  value: 17,
  constitutionMod: 2,
  dirty: true,
}

const exampleAttack = {
  '_id': 'vw23EnJwBRcXEJg7i',
  'actionType': 'attack',
  'target': 'singleTarget',
  'tags': ['attack'],
  'results': {
    'adjustments': [],
    'damages': [{
      '_id': 'RGJMeNJXBeqZsGmAw',
      'damage': '1d4 + strength.modifier',
      'target': 'every',
      'damageType': 'slashing'
    }],
    'buffs': []
  },
  'resources': {
    'itemsConsumed': [],
    'attributesConsumed': []
  },
  'rollBonus': 'dexterity.modifier + proficiencyBonus + 2 - hp.value + hp.currentValue',
  'type': 'attack',
  'name': 'Claws',
  'parent': {
    'id': 'Jpx8q3WjM5SCoGBm8',
    'collection': 'creatureProperties'
  },
  'ancestors': [{
    'collection': 'creatures',
    'id': 'm9sdCvs6iDf7qRaGv'
  }, {
    'id': '3WS2xsSPAqB4eF9YH',
    'collection': 'creatureProperties'
  }, {
    'id': 'rhYLEycvtHjcioaQL',
    'collection': 'creatureProperties'
  }, {
    'id': 'Jpx8q3WjM5SCoGBm8',
    'collection': 'creatureProperties'
  }],
  'order': 56,
  'rollBonusResult': 6,
  'usesUsed': 2,
  'dependencies': ['pg6cK5ghHTFvo8uyK', 'gAJBKYqXz2BPc9Aqf']
}

const expectedMigratedAttack = {
  '_id': 'vw23EnJwBRcXEJg7i',
  'actionType': 'attack',
  'target': 'singleTarget',
  'tags': ['attack'],
  'resources': {
    'itemsConsumed': [],
    'attributesConsumed': []
  },
  'attackRoll': {
    calculation: 'dexterity.modifier + proficiencyBonus + 2 - hp.total + hp.value',
  },
  'type': 'action',
  'name': 'Claws',
  'parent': {
    'id': 'Jpx8q3WjM5SCoGBm8',
    'collection': 'creatureProperties'
  },
  'ancestors': [{
    'collection': 'creatures',
    'id': 'm9sdCvs6iDf7qRaGv'
  }, {
    'id': '3WS2xsSPAqB4eF9YH',
    'collection': 'creatureProperties'
  }, {
    'id': 'rhYLEycvtHjcioaQL',
    'collection': 'creatureProperties'
  }, {
    'id': 'Jpx8q3WjM5SCoGBm8',
    'collection': 'creatureProperties'
  }],
  'order': 56,
  'usesUsed': 2,
}

describe('migrateProperty', function () {
  it('Migrates actions reversibly', function () {
    const action = {
      ...exampleAction
    };
    const newAction = migrateProperty({
      collection: CreatureProperties,
      prop: action
    });
    const reversedAction = migrateProperty({
      collection: CreatureProperties,
      prop: newAction,
      reversed: true,
    });
    delete reversedAction.dirty;
    assert.deepEqual(action, exampleAction, 'action should not be bashed');
    assert.deepEqual(exampleAction, reversedAction, 'operation should be reversible');
  });
  it('Migrates attributes as expected', function () {
    const attribute = {
      ...exampleAttribute
    };
    const newAttribute = migrateProperty({
      collection: CreatureProperties,
      prop: attribute
    });
    assert.deepEqual(newAttribute, expectedMigratedAttribute,
      'Attribute should match the expected result');
  });
  it('Migrates attacks as expected', function () {
    const attribute = {
      ...exampleAttack
    };
    const newAttribute = migrateProperty({
      collection: LibraryNodes,
      prop: attribute
    });
    assert.deepEqual(newAttribute, expectedMigratedAttack,
      'Attribute should match the expected result');
  });
});
