<script>
const ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];

class Card {
    constructor(suit, rank) {
        this.suit = suit;
        this.rank = rank;
    }
}

class Combination {
    constructor() {}
    static name = null;
    static id = null;
    static rank = null;

    static test(cards) {}
}


class StraightFlush extends Combination {
    static name = "Straight flush";
    static id = 8;
    static rank = 8;

    static test(cards) {
        const counts = {};

        for (let card of cards) {
            counts[card.suit] = (counts[card.suit] || []).concat(card);
        }

        const flusharr = Object.keys(counts).filter((key) => counts[key].length >= 5);

        if (flusharr.length !== 1) {
            return null;
        }

        let flushCards = counts[flusharr[0]];

        let sorted_rank = [
            ...new Set(
                flushCards.map((card) => {
                    const index = ranks.indexOf(card.rank);
                    return index !== -1 ? index : null;
                })
            ),
        ].sort((a, b) => a - b);

        if (sorted_rank.includes(ranks.length - 1) && sorted_rank.includes(0)) {
            sorted_rank.push(sorted_rank.shift());
        }

        for (let i = 0; i < sorted_rank.length - 4; i++) {
            let isStraightFlush = true;
            for (let j = 0; j < 4; j++) {
                if (sorted_rank[i + j + 1] - sorted_rank[i + j] !== 1) {
                    isStraightFlush = false;
                    break;
                }
            }
            if (isStraightFlush) {
                const straightFlushCards = flushCards
                    .filter((c) => {
                        const cIndex = ranks.indexOf(c.rank);
                        return cIndex >= sorted_rank[i] && cIndex <= sorted_rank[i + 4];
                    })
                    .sort((c1, c2) => {
                        const c1Index = ranks.indexOf(c1.rank);
                        const c2Index = ranks.indexOf(c2.rank);
                        return c1Index - c2Index;
                    });
                return {
                    combination: this,
                    cards: straightFlushCards.slice(0, 5),
                };
            }
        }

        return null;
    }
}



////////////////////////////////////

// Define a function to test StraightFlush combination
function testStraightFlush() {

  // Test case 1: straight flush with Ace as the high card
  const cards1 = [
    new Card("hearts", "K"),
    new Card("hearts", "Q"),
    new Card("hearts", "J"),
    new Card("hearts", "10"),
    new Card("hearts", "A"),
    new Card("spades", "9"),
    new Card("clubs", "7"),
  ];
  const result1 = StraightFlush.test(cards1);
 console.log(JSON.stringify(result1));

  // Test case 2: straight flush with Ace followed by five as the low card
  const cards2 = [
    new Card("diamonds", "4"),
    new Card("diamonds", "3"),
    new Card("diamonds", "2"),
    new Card("diamonds", "A"),
    new Card("diamonds", "5"),
    new Card("clubs", "K"),
    new Card("spades", "7")
  ];
  const result2 = StraightFlush.test(cards2);
 console.log(JSON.stringify(result2));


   // Test case 3: flush, but not a straight
   const cards3 = [
     new Card("hearts", "2"),
     new Card("hearts", "4"),
     new Card("hearts", "6"),
     new Card("hearts", "8"),
     new Card("hearts", "A")
   ];
   const result3 = StraightFlush.test(cards3);
 console.log(JSON.stringify(result3));

   // Test case 4: not a flush
	 const cards4 = [
			new Card('spades', 'K'),
			new Card('hearts', '10'),
			new Card('clubs', '5'),
      new Card('diamonds', 'Q'),
      new Card('spades', 'J')
	 ];
	 const result4 = StraightFlush.test(cards4);
 console.log(JSON.stringify(result4));

}
testStraightFlush();
</script>
/////////////////
{"cards":[{"suit":"hearts","rank":"10"},{"suit":"hearts","rank":"J"},{"suit":"hearts","rank":"Q"},{"suit":"hearts","rank":"K"},{"suit":"hearts","rank":"A"}]}
tmp.html:115 null
tmp.html:127 null
tmp.html:138 null