@use 'sass:color';
@use 'sass:list';
@use 'sass:meta';
@use 'sass:string';
@use 'conv-color' as *;
@use 'get-color-type' as *;
@use 'is-color' as *;
@use 'is-string' as *;

/// Takes a given color and finds a complementary color that contrasts well
/// with the given color such that they will look good together. Allows you
/// to choose the desired syntax of the returned color.
///
/// @param {Color} $color - The color to find a contrast for. Must be a color
/// type recognized by Sass.
/// @param {String} $syntax [get-color-type($color)] - The desired syntax of the
/// returned color. Defaults to the color notation used by `$color`.
///
/// @return {Color} - The contrasting color in the given syntax.
///
/// @access public
/// @group Utilities
/// @require {function} conv-color
/// @require {function} get-color-type
/// @require {function} is-color
/// @require {function} is-string
/// @since 0.9.0
///
/// @throw Invalid $color data type, must be a color.
/// @throw Invalid $syntax data type, must be a string.
/// @throw Invalid $syntax value, must be a color syntax string.
@function color-contrast($color, $syntax: get-color-type($color)) {
  $complement: null;
  $adjusted-color: null;
  $final-color: null;

  // Input scrubbing and error reporting
  $valid-syntax-values: (
    'hex', '#', 'rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'function', 'name', 'cmyk'
  );

  @if not is-color($color) {
    @error 'Invalid $color data type of #{meta.inspect(meta.type-of($color))} ' +
        'passed to the [ color-contrast() ] function. This value is not ' +
        'currently recognized as a color by your version of Sass.';
  }

  @if $syntax and is-string($syntax) {
    $syntax: string.to-lower-case($syntax);
  } @else if not $syntax {
    $syntax: get-color-type($color);
  } @else {
    @error 'Invalid $sytax data type of #{meta.type-of($syntax)} passed to ' +
        'the [ color-complement() ] function. The $syntax parameter must be ' +
        'of type \'string\' or be `null` or `false`. This function supports ' +
        'converting into the following $syntax values: ' +
        '[ \'hex\', \'#\', \'rgb\', \'rgba\', \'hsl\', \'hsla\', \'hwb\', ' +
        '\'function\', \'name\', \'cmyk\' ].';
  }

  @if not list.index($valid-syntax-values, $syntax) {
    @error 'Invalid $syntax value of #{meta.inspect($syntax)} passed to ' +
        'the [ color-complement() ] function. Value of $syntax must be a string ' +
        'representing a valid CSS color function specification. This function ' +
        'supports converting into the following $syntax values: ' +
        '[ \'hex\', \'#\', \'rgb\', \'rgba\', \'hsl\', \'hsla\', \'hwb\', ' +
        '\'function\', \'name\', \'cmyk\' ].';
  }

   // Get the complementary color
  $complement: color.complement($color);

  // Check the lightness of the original color and adjust the complementary
  // color accordingly If the original color is light, make the complementary
  // color darker, and vice versa
  @if color.lightness($color) > 0.5 {
    $adjusted-color: color.scale($complement, $lightness: -50%);
  } @else {
    $adjusted-color: color.scale($complement, $lightness: 50%);
  }

  // Adjust the saturation to ensure the color is vibrant but not overly saturated
  @if color.saturation($adjusted-color) < 50% {
    $final-color: color.scale($adjusted-color, $saturation: 50%);
  } @else {
    $final-color: $adjusted-color;
  }

  // Return the adjusted color
  @return conv-color($final-color, $syntax);
}

/// Takes a given color and finds a complementary color that contrasts well
/// with the given color such that they will look good together. Allows you
/// to choose the desired syntax of the returned color.
///
/// @param {Color} $color - The color to find a contrast for. Must be a color
/// type recognized by Sass.
/// @param {String} $syntax [get-color-type($color)] - The desired syntax of the
/// returned color. Defaults to the color notation used by `$color`.
///
/// @return {Color} - The contrasting color in the given syntax.
///
/// @access public
/// @group Utilities
/// @require {function} color-contrast
///
/// @throw Invalid $color data type, must be a color.
/// @throw Invalid $syntax data type, must be a string.
/// @throw Invalid $syntax value, must be a color syntax string.
///
/// @alias color-contrast
@function contrast-color($color, $syntax: get-color-type($color)) {
  @return color-contrast($color, $syntax);
}
