@use "sass:math";
@use "sass:color";
@use "sass:list";
@use "sass:map";
@use "sass:meta";
@use "sass:selector";
@use "sass:string";
@use "./utils" as u;

/***
* Inspired by Pedro Rodríguez's article in CSS-Tricks
* Article: https://css-tricks.com/linearly-scale-font-size-with-css-clamp-based-on-the-viewport/
* Twitter: https://twitter.com/pprg1996
***/

$default-wide-width: 1440 !default;
$default-narrow-width: 375 !default;
$default-narrow: false !default;
$default-clamp: false !default;
$default-dynamic: false !default;
$default-base-font-size: 16 !default;

@function vw-calc(
  $values,
  $wide-width: $default-wide-width,
  $narrow-width: $default-narrow-width,
  $narrow: $default-narrow,
  $clamp: $default-clamp,
  $dynamic: $default-dynamic,
  $base-font-size: $default-base-font-size
) {
  $base-width: u.strip-unit($wide-width);
  $count: list.length($values);
  $min-value: 0;
  $max-value: 0;
  $limit-value-size: 0;

  $min-width-px: u.strip-unit($narrow-width);
  $max-width-px: u.strip-unit($wide-width);
  $min-value-size: u.strip-unit(u.rem-calc(list.nth($values, 1)));
  $max-value-size: u.strip-unit(u.rem-calc(list.nth($values, 1)));
  $limit-value-size: u.strip-unit(u.rem-calc(list.nth($values, 1)));

  @if $narrow {
    $max-width-px: u.strip-unit($narrow-width);
    $min-width-px: 0;
  }
  
  @if $count == 1 {
    $temp-min-value-size: math.div(($min-width-px * u.strip-unit($values)), $max-width-px);
    $min-value-size: u.strip-unit(u.rem-calc($temp-min-value-size));
    $max-value-size: u.strip-unit(u.rem-calc($values));
  }

  @if $count == 2 {
    $min-value-size: u.strip-unit(u.rem-calc(list.nth($values, 1)));
    $max-value-size: u.strip-unit(u.rem-calc(list.nth($values, 2)));

    @if list.nth($values, 1) > list.nth($values, 2) {
      @error "#{list.nth($values, 1)} < #{list.nth($values, 2)} = false | {{max-value}} can't be lower than {{min-value}}.";
    }

    @if list.nth($values, 1) == list.nth($values, 2) {
      @error "#{list.nth($values, 1)} === #{list.nth($values, 2)} | {{min-value}} cannot be equal to {{max-value}}.";
    }
  }

  @if $count == 3 {
    $clamp: true;
    $min-value-size: u.strip-unit(u.rem-calc(list.nth($values, 1)));
    $max-value-size: u.strip-unit(u.rem-calc(list.nth($values, 2)));
    $limit-value-size: u.strip-unit(u.rem-calc(list.nth($values, 3)));

    @if list.nth($values, 1) > list.nth($values, 2) {
      @error "#{list.nth($values, 1)} < #{list.nth($values, 2)} = false | {{max-value}} can't be lower than {{min-value}}.";
    }

    @if list.nth($values, 2) > list.nth($values, 3) {
      @error "#{list.nth($values, 2)} < #{list.nth($values, 3)} = false | {{limit-value}} can't be lower than {{max-value}}.";
    }

    @if list.nth($values, 1) == list.nth($values, 2) {
      @error "#{list.nth($values, 1)} === #{list.nth($values, 2)} | {{min-value}} cannot be equal to {{max-value}}.";
    }
  }

  $min-width: math.div($min-width-px, $base-font-size);
  $max-width: math.div($max-width-px, $base-font-size);

  $slope: math.div(($max-value-size - $min-value-size), ($max-width - $min-width));
  $y-axis-intersection: -$min-width * $slope + $min-value-size;
  $slope-angle: calc(#{$y-axis-intersection}rem + #{$slope * 100}vw);

  @if $count == 3 {
    @return clamp(#{$min-value-size}rem, $slope-angle, #{$limit-value-size}rem);
  } 
  
  @if $count == 2 {
    @if $clamp {
      @return clamp(#{$min-value-size}rem, $slope-angle, #{$max-value-size}rem);
    } @else {
      @return max(#{$min-value-size}rem, $slope-angle);
    }
  }

  @if $count == 1 {
    @if $clamp {
      @if $dynamic {
        @return clamp(#{$min-value-size}rem, $slope-angle, #{$max-value-size}rem);
      } @else {
        @warn "Unnecessary declaration: vw-calc(#{list.nth($values, 1)}) === #{math.div(list.nth($values, 1), 16)}rem, use rem value directly instead.";
        @return #{$max-value-size}rem;
      }
    } @else {
      @if $dynamic {
        @return max(#{$min-value-size}rem,$slope-angle);
      } @else {
        @return max(#{$max-value-size}rem, $slope-angle);
      }
    }
  }

  @if $count > 3 {
    @error "(#{$values}) | Maximum of 3 (three) values allowed.";
  }
}
