package day13

import (
	_ "fmt"
	"encoding/json"
	"sort"
)

func Part1(input []string) int {
	sum := 0
	for i := 0; i < len(input); i += 3 {
		left, right := input[i], input[i+1]

		if isOrderRight(left, right) {
			sum += i/3 + 1
		}
	}
	return sum
}

func Part2(input []string) int {
	var trimmed []string
	for _, str := range input {
		if str != "" {
			trimmed = append(trimmed, str)
		}
	}
	trimmed = append(trimmed, "[[2]]", "[[6]]")
	sort.Slice(trimmed, func(i, j int) bool {
		return isOrderRight(trimmed[i], trimmed[j])
	})

	start := 0
	end := 0
	for i, value := range trimmed {
		if value == "[[2]]" {
			start = i + 1
		}
		if value == "[[6]]" {
			end = i + 1
			return start * end
		}
	}
	return 0
}

func isOrderRight(left, right string) bool {
	var l, r = unmarshal(left, right)

	if cmp(l, r) <= 0 {
		return true
	}

	return false
}

func unmarshal(left, right string) (any, any) {
	var l, r any

	json.Unmarshal([]byte(left), &l)
	json.Unmarshal([]byte(right), &r)

	return l, r
}

func cmp(left, right any) int {
	l, lok := left.([]any)
	r, rok := right.([]any)

	switch {
	case !lok && !rok:
		return int(left.(float64) - right.(float64))
	case !lok:
		l = []any{left}
	case !rok:
		r = []any{right}
	}

	for i := 0; i < len(l) && i < len(r); i++ {
		if res := cmp(l[i], r[i]); res != 0 {
			return res
		}
	}

	return len(l) - len(r)
}