#!/bin/bash

# Get the active monitor (the one with the cursor)
ACTIVE_MONITOR=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name')
MONITOR_INFO=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true)')

# Get current scale and pixel dimensions of active monitor
CURRENT_SCALE=$(echo "$MONITOR_INFO" | jq -r '.scale')
PIXEL_WIDTH=$(echo "$MONITOR_INFO" | jq -r '.width')
PIXEL_HEIGHT=$(echo "$MONITOR_INFO" | jq -r '.height')

# Function to check if a scale produces integer logical dimensions using awk
is_valid_scale() {
  local scale=$1
  local width=$2
  local height=$3

  awk -v w="$width" -v h="$height" -v s="$scale" 'BEGIN {
    logical_w = w / s
    logical_h = h / s
    rounded_w = int(logical_w + 0.5)
    rounded_h = int(logical_h + 0.5)
    diff_w = (logical_w - rounded_w) < 0 ? -(logical_w - rounded_w) : (logical_w - rounded_w)
    diff_h = (logical_h - rounded_h) < 0 ? -(logical_h - rounded_h) : (logical_h - rounded_h)
    if (diff_w < 0.0001 && diff_h < 0.0001) exit 0
    exit 1
  }'
}

# Function to find the nearest valid scale for a target
find_nearest_valid_scale() {
  local target=$1
  local width=$2
  local height=$3

  # Round to nearest 1/120th (Hyprland's precision)
  awk -v t="$target" -v w="$width" -v h="$height" 'BEGIN {
    base = t * 120
    rounded = int(base + 0.5)
    scale_zero = rounded / 120

    # Test scale_zero first
    logical_w = w / scale_zero
    logical_h = h / scale_zero
    rnd_w = int(logical_w + 0.5)
    rnd_h = int(logical_h + 0.5)
    diff_w = (logical_w - rnd_w) < 0 ? -(logical_w - rnd_w) : (logical_w - rnd_w)
    diff_h = (logical_h - rnd_h) < 0 ? -(logical_h - rnd_h) : (logical_h - rnd_h)

    if (diff_w < 0.0001 && diff_h < 0.0001) {
      printf "%.6f\n", scale_zero
      exit 0
    }

    # Search outward
    for (i = 1; i <= 90; i++) {
      scale_up = (rounded + i) / 120
      scale_down = (rounded - i) / 120

      # Test scale_up
      logical_w = w / scale_up
      logical_h = h / scale_up
      rnd_w = int(logical_w + 0.5)
      rnd_h = int(logical_h + 0.5)
      diff_w = (logical_w - rnd_w) < 0 ? -(logical_w - rnd_w) : (logical_w - rnd_w)
      diff_h = (logical_h - rnd_h) < 0 ? -(logical_h - rnd_h) : (logical_h - rnd_h)

      if (diff_w < 0.0001 && diff_h < 0.0001) {
        printf "%.6f\n", scale_up
        exit 0
      }

      # Test scale_down (must be > 0.1)
      if (scale_down > 0.1) {
        logical_w = w / scale_down
        logical_h = h / scale_down
        rnd_w = int(logical_w + 0.5)
        rnd_h = int(logical_h + 0.5)
        diff_w = (logical_w - rnd_w) < 0 ? -(logical_w - rnd_w) : (logical_w - rnd_w)
        diff_h = (logical_h - rnd_h) < 0 ? -(logical_h - rnd_h) : (logical_h - rnd_h)

        if (diff_w < 0.0001 && diff_h < 0.0001) {
          printf "%.6f\n", scale_down
          exit 0
        }
      }
    }

    # Fallback
    printf "%.6f\n", scale_zero
  }'
}

# Define target scales and find their nearest valid equivalents
TARGET_SCALE_1=$(find_nearest_valid_scale "1" "$PIXEL_WIDTH" "$PIXEL_HEIGHT")
TARGET_SCALE_1_6=$(find_nearest_valid_scale "1.6" "$PIXEL_WIDTH" "$PIXEL_HEIGHT")
TARGET_SCALE_2=$(find_nearest_valid_scale "2" "$PIXEL_WIDTH" "$PIXEL_HEIGHT")
TARGET_SCALE_3=$(find_nearest_valid_scale "3" "$PIXEL_WIDTH" "$PIXEL_HEIGHT")

# Convert to comparable integers (multiply by 100) to avoid floating point issues
CURRENT_INT=$(echo "$CURRENT_SCALE" | awk '{printf "%.0f", $1 * 100}')
SCALE_1_INT=$(echo "$TARGET_SCALE_1" | awk '{printf "%.0f", $1 * 100}')
SCALE_1_6_INT=$(echo "$TARGET_SCALE_1_6" | awk '{printf "%.0f", $1 * 100}')
SCALE_2_INT=$(echo "$TARGET_SCALE_2" | awk '{printf "%.0f", $1 * 100}')
SCALE_3_INT=$(echo "$TARGET_SCALE_3" | awk '{printf "%.0f", $1 * 100}')

# Determine next scale using integer comparison
if [[ "$CURRENT_INT" -eq "$SCALE_1_INT" ]]; then
  NEW_SCALE="$TARGET_SCALE_1_6"
elif [[ "$CURRENT_INT" -eq "$SCALE_1_6_INT" ]]; then
  NEW_SCALE="$TARGET_SCALE_2"
elif [[ "$CURRENT_INT" -eq "$SCALE_2_INT" ]]; then
  NEW_SCALE="$TARGET_SCALE_3"
elif [[ "$CURRENT_INT" -eq "$SCALE_3_INT" ]]; then
  NEW_SCALE="$TARGET_SCALE_1"
else
  # Find closest target to determine where we are
  DIFF_1=$((CURRENT_INT - SCALE_1_INT))
  [[ $DIFF_1 -lt 0 ]] && DIFF_1=$((-DIFF_1))

  DIFF_1_6=$((CURRENT_INT - SCALE_1_6_INT))
  [[ $DIFF_1_6 -lt 0 ]] && DIFF_1_6=$((-DIFF_1_6))

  DIFF_2=$((CURRENT_INT - SCALE_2_INT))
  [[ $DIFF_2 -lt 0 ]] && DIFF_2=$((-DIFF_2))

  DIFF_3=$((CURRENT_INT - SCALE_3_INT))
  [[ $DIFF_3 -lt 0 ]] && DIFF_3=$((-DIFF_3))

  # Find minimum
  MIN=$DIFF_1
  CLOSEST="1"

  if [[ $DIFF_1_6 -lt $MIN ]]; then
    MIN=$DIFF_1_6
    CLOSEST="1.6"
  fi

  if [[ $DIFF_2 -lt $MIN ]]; then
    MIN=$DIFF_2
    CLOSEST="2"
  fi

  if [[ $DIFF_3 -lt $MIN ]]; then
    MIN=$DIFF_3
    CLOSEST="3"
  fi

  # Set next based on closest
  case "$CLOSEST" in
  "1") NEW_SCALE="$TARGET_SCALE_1_6" ;;
  "1.6") NEW_SCALE="$TARGET_SCALE_2" ;;
  "2") NEW_SCALE="$TARGET_SCALE_3" ;;
  "3") NEW_SCALE="$TARGET_SCALE_1" ;;
  esac
fi

# Apply the new scale to the active monitor only
hyprctl keyword monitor "$ACTIVE_MONITOR,preferred,auto,$NEW_SCALE"

# Format for display (remove trailing zeros)
DISPLAY_SCALE=$(echo "$NEW_SCALE" | sed 's/0*$//;s/\.$//')

# Notify the user
notify-send "󰍹  Display scaling set to ${DISPLAY_SCALE}x"
