<?php

namespace App\Helpers\FirstParty;

class AspectRatio
{
    /**
     * Get the aspect ratio for given width and height
     * Returns common aspect ratios first, then computed ratios
     *
     * @param  int|float  $width
     * @param  int|float  $height
     * @return string
     */
    public static function get($width, $height)
    {
        // Handle edge cases
        if ($width <= 0 || $height <= 0) {
            return 'Invalid dimensions';
        }

        // Calculate the actual ratio
        $actualRatio = $width / $height;

        // Define common aspect ratios with their decimal values and string representations
        $commonRatios = [
            '1:1' => 1.0,           // 1/1 = 1.0
            '4:3' => 4 / 3,           // 1.333...
            '3:4' => 3 / 4,           // 0.75
            '16:9' => 16 / 9,         // 1.777...
            '9:16' => 9 / 16,         // 0.5625
            '20:9' => 20 / 9,         // 2.222...
            '9:20' => 9 / 20,         // 0.45
            '5:4' => 5 / 4,           // 1.25
            '4:5' => 4 / 5,           // 0.8
        ];

        // Tolerance for floating point comparison (about 1% difference)
        $tolerance = 0.01;

        // Check against common ratios first
        foreach ($commonRatios as $ratioString => $ratioValue) {
            if (abs($actualRatio - $ratioValue) < $tolerance) {
                return $ratioString;
            }
        }

        // If no common ratio matches, compute the simplified ratio
        return self::computeSimplifiedRatio($width, $height);
    }

    /**
     * Compute simplified aspect ratio using GCD
     *
     * @param  int|float  $width
     * @param  int|float  $height
     * @return string
     */
    private static function computeSimplifiedRatio($width, $height)
    {
        // Convert to integers for GCD calculation
        $intWidth = (int) $width;
        $intHeight = (int) $height;

        // Find the greatest common divisor
        $gcd = self::gcd($intWidth, $intHeight);

        // Simplify the ratio
        $simplifiedWidth = $intWidth / $gcd;
        $simplifiedHeight = $intHeight / $gcd;

        return $simplifiedWidth.':'.$simplifiedHeight;
    }

    /**
     * Calculate Greatest Common Divisor using Euclidean algorithm
     *
     * @param  int  $a
     * @param  int  $b
     * @return int
     */
    private static function gcd($a, $b)
    {
        // Euclidean algorithm for finding GCD
        while ($b != 0) {
            $temp = $b;
            $b = $a % $b;
            $a = $temp;
        }

        return $a;
    }
}
