import KataGroup from './katagroup.js';

export default class Metadata {
  
  static toKataGroups(groupedMetadataJson) {
    return KataGroups.fromObject(fromMetadataJsonToKataGroups(groupedMetadataJson));
  }
}

class KataGroups {
  
  constructor() {
    this.groups = [];
  }

  all() {
    return this.groups;
  }
  
  get length() {
    return this.all().length;
  }
  
  static fromObject(obj) {
    const groups = new KataGroups();
    groups.initializePropertiesFromRawObject(obj);
    groups.sortByNumberOfLinks();
    groups.moveNewestToBeginning();
    return groups;
  }

  initializePropertiesFromRawObject(obj) {
    const allKeys = Object.keys(obj);
    allKeys.forEach(key => this.groups.push(obj[key]));
  }
  
  sortByNumberOfLinks() {
    this.groups.sort(function(group, anotherGroup) {
      var katasCount = group.katas.length;
      var anotherKatasCount = anotherGroup.katas.length;
      if (katasCount === anotherKatasCount) {
        return anotherGroup.name < group.name ? 1 : -1;
      }
      return anotherKatasCount - katasCount;
    });
  }
  
  isNewestKata(kata) {
    const highestId = this.groups
      .map(group => parseInt(group.highestId, 10))
      .sort((one, two) => one < two ? -1 : 1)
      .reverse()
      [0];
    return parseInt(kata.id) === highestId;
  }
  
  moveNewestToBeginning() {
    const groupWithNewestKata = this.groups.reduce((prev, cur) => {
      return prev.highestId > cur.highestId ? prev : cur;
    }, {highestId:0});
    this.moveToBeginning(groupWithNewestKata);
  }
  
  moveToBeginning(itemToMove) {
    const idx = this.groups
      .map((item, idx) => Object.is(item, itemToMove) ? idx : null)
      .filter(id => id != null)[0];
    this.groups.unshift(this.groups.splice(idx, 1)[0]);
  }
  
}

function fromMetadataJsonToKataGroups(groupedMetadataJson) {
  const groups = groupedMetadataJson.groups;
  const groupNames = Object.keys(groups);
  return groupNames.map((groupName) => {
    let rawKataItems = groups[groupName].items;
    return KataGroup.withKatas(groupName, rawKataItems);
  });
}

@@ -1076,33 +1076,40 @@
  %0A  
-isNew
+eachGroupsHigh
 estKata
-(kata
+Id(
 ) %7B%0A    
 cons
@@ -1108,25 +1108,14 @@
     
-const highestId =
+return
  thi
@@ -1118,31 +1118,24 @@
  this.groups
-%0A      
 .map(group =
@@ -1136,25 +1136,16 @@
 roup =%3E 
-parseInt(
 group.hi
@@ -1155,67 +1155,86 @@
 stId
-, 10)
 )
+;
 %0A  
+%7D%0A
   
+%0A
   
-.sort((one, two) =%3E one %3C two ? -1 : 1)%0A      
+highestKataId() %7B%0A    return this.eachGroupsHighestKataId().sort()
 .rev
@@ -1243,19 +1243,42 @@
 se()
+%5B0%5D;
 %0A  
+%7D%0A
   
+%0A
   
-%5B0%5D;
+isNewestKata(%7Bid%7D) %7B
 %0A   
@@ -1285,16 +1285,23 @@
  return 
+Number.
 parseInt
@@ -1305,21 +1305,16 @@
 Int(
-kata.
 id) === 
 high
@@ -1309,25 +1309,36 @@
 id) === 
+this.
 highest
-Id
+KataId()
 ;%0A  %7D%0A  

Split big function into smaller ones.