@use "sass:list";
@use "sass:math";

$board-size: 16;
$mine-count: 40;
$cell-size: 40px;

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  counter-reset: flags;
}

@property --second {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

@keyframes second {
  from {
    --second: 0;
  }
  to {
    --second: 59;
  }
}

@property --minute {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

@keyframes minute {
  from {
    --minute: 0;
  }
  to {
    --minute: 1000;
  }
}

#game {
  position: relative;
  display: grid;
  grid-template-columns: repeat($board-size, $cell-size);
  grid-template-rows: repeat($board-size, $cell-size);
  margin: 80px;
  border: 1px solid lightgrey;
  border-left: none;
  border-top: none;

  &::after {
    content: counter(flags) " / #{$mine-count}";
    position: absolute;
    left: 140px;
    margin-top: -32px;
  }

  animation: minute 60000s linear;
  counter-reset: minute var(--minute);

  &::before {
    animation: second 60s infinite linear;
    counter-reset: second var(--second);
    content: counter(minute) " minutes and " counter(second) " seconds";
    position: absolute;
    left: 220px;
    margin-top: -32px;
  }

  .mode-toggles {
    position: absolute;
    left: 8px;
    margin-top: -32px;
    cursor: pointer;

    .select-toggle::after {
      content: "🮰";
    }

    .flag-toggle::after {
      content: "🚩";
    }

    .question-toggle::after {
      content: "❓";
    }

    .select-toggle::after,
    .flag-toggle::after,
    .question-toggle::after {
      cursor: pointer;
      padding: 5px;
      border-radius: 5px;
    }

    .select-toggle:hover::after,
    .flag-toggle:hover::after,
    .question-toggle:hover::after {
      background-color: #dddddd;
    }

    .select-toggle:has(input:checked)::after,
    .flag-toggle:has(input:checked)::after,
    .question-toggle:has(input:checked)::after {
      background-color: #eeeeee;
    }
  }

  input[type="radio"] {
    display: none;
  }
}

.cell {
  display: block;
  position: relative;
  border: 1px solid lightgrey;
  border-right: none;
  border-bottom: none;
  background-color: #bdbdbd;
  font-weight: bold;

  &::after {
    --n: calc(
      var(--n1) + var(--n2) + var(--n3) + var(--n4) + var(--n5) + var(--n6) +
        var(--n7) + var(--n8)
    );
    counter-reset: n var(--n);
    color: if(
      style(--n: 1): #2233f5; style(--n: 2): #047606; style(--n: 3): #fc0411;
        style(--n: 4): #000277; style(--n: 5): #872f33; style(--n: 6): #317261;
        style(--n: 7): black; style(--n: 8): #777777; else: transparent;
    );
    content: counter(n);
    display: none;
    align-items: center;
    justify-content: center;
    font-weight: bold;
    position: absolute;
    inset: 0;
    z-index: 1;
  }

  &::before {
    content: "";
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    position: absolute;
    inset: 0;
    background-color: rgb(245, 246, 247);
    z-index: 2;
  }

  &:has(.reveal input:checked)::before {
    display: none !important;
  }

  &:has(.flag input:checked)::before {
    content: "🚩";
    counter-increment: flags;
  }

  &:has(.question input:checked)::before {
    content: "❓";
  }

  &:hover::before {
    background-color: white;
  }

  .reveal {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 3;
    cursor: pointer;
  }

  .reveal:has(input:checked),
  .reveal:has(input:checked) ~ .flag,
  .reveal:has(input:checked) ~ .question {
    display: none !important;
  }

  .flag,
  .question {
    display: none;
    position: absolute;
    inset: 0;
    z-index: 4;
    cursor: pointer;
  }

  &:has(~ .mode-toggles .flag-toggle input:checked) .flag,
  &:has(~ .mode-toggles .question-toggle input:checked) .question {
    display: block;
  }
}

#end-screen {
  display: none;
  position: absolute;
  inset: 0;
  background-color: rgba(255, 255, 255, 0.8);
  z-index: 5;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 30px;

  &::before {
    font-size: 34px;
  }

  a {
    text-decoration: none;
    color: black;
    padding: 8px 16px;
    border: 1px solid black;
    border-radius: 8px;
    background-color: white;
    font-family: sans-serif;
    font-size: 1.2rem;

    &:hover {
      background-color: #eeeeee;
    }
  }
}

@function repeat-str($str, $count) {
  $value: $str;

  $i: 1;
  @while $i < $count {
    $value: "#{$str}#{$value}";
    $i: $i + 1;
  }

  @return $value;
}

$mineList: ();
@for $i from 0 through $mine-count {
  $mine: math.random($board-size * $board-size);

  @while list.index($mineList, $mine) != null {
    $mine: math.random($board-size * $board-size);
  }

  $mineList: list.append($mineList, $mine);
}

$mines: ();
@each $mine in $mineList {
  $mines: list.append($mines, ":nth-child(#{$mine})", comma);
}

$selectors: (
  ".cell:is(#{$mines}):not(:nth-child(#{$board-size}n)) + .cell",
  ".cell:is(#{$mines})#{repeat-str("+.cell", $board-size)}",
  ".cell:is(#{$mines}):not(:nth-child(#{$board-size}n+1))#{repeat-str("+.cell", $board-size - 1)}",
  ".cell:is(#{$mines}):not(:nth-child(#{$board-size}n))#{repeat-str("+.cell", $board-size + 1)}",
  ".cell:has(+ .cell:is(#{$mines}):not(:nth-child(#{$board-size}n+1)))",
  ".cell:has(#{repeat-str("+.cell", $board-size)}:is(#{$mines}))",
  ".cell:has(#{repeat-str("+.cell", $board-size - 1)}:is(#{$mines}):not(:nth-child(#{$board-size}n)))",
  ".cell:has(#{repeat-str("+.cell", $board-size + 1)}:is(#{$mines}):not(:nth-child(#{$board-size}n+1)))"
);

@property --n {
  syntax: "<integer>";
  initial-value: 0;
  inherits: true;
}

$n: 0;
@each $selector in $selectors {
  $n: $n + 1;

  @property --n#{$n} {
    syntax: "<integer>";
    initial-value: 0;
    inherits: true;
  }

  #{$selector}::after {
    display: flex;
    --n#{$n}: 1;
  }
}

.cell:is(#{$mines}) {
  &::after {
    display: flex;
    color: black;
    content: "💣" !important;
  }

  &:has(.reveal input:checked)::after {
    background-color: red;
  }
}

#game:has(.cell:is(#{$mines}) .reveal input:checked) #end-screen {
  display: flex;

  &::before {
    content: "Game Over";
  }
}

#game:not(:has(.cell:not(#{$mines}) .reveal input:not(:checked))) #end-screen {
  display: flex;

  &::before {
    content: "You win!";
  }
}

#game:has(.cell:is(#{$mines}) .reveal input:checked),
#game:not(:has(.cell:not(#{$mines}) .reveal input:not(:checked))) {
  animation-play-state: paused;

  &::before {
    animation-play-state: paused;
  }

  .cell::before {
    display: none;
  }
}

#game:not(:has(.cell input:checked)) {
  animation-name: invalid;

  &::before {
    animation-name: invalid;
  }
}

.cell:not(#{$mines}):has(.flag input:checked)::after {
  content: "🚩" !important;
  background-color: blue;
}

body::after {
  display: none;
}
