@use "sass:list";
@use "sass:map";
@use "sass:meta";
@use "@vrembem/core";
@use "./variables" as var;

// Arrow
// ---

@mixin arrow(
  $dir: null,
  $color: var.$arrow-color,
  $size: var.$arrow-size,
  $radius: var.$arrow-radius
) {
  $size-pointer: $size;
  @if (meta.type-of($size) == list) {
    $size-pointer: list.nth($size, 2);
    $size: list.nth($size, 1);
  }
  display: inline-block;
  flex-grow: 0;
  flex-shrink: 0;
  width: 0;
  height: 0;
  transform-origin: center;
  border-top: $size-pointer solid $color;
  border-right: ($size * 0.5) solid transparent;
  border-left: ($size * 0.5) solid transparent;
  border-radius: $radius;
  pointer-events: none;

  @if $dir == "up" {
    transform: rotate(180deg);
  }
  @else if $dir == "left" {
    transform: rotate(90deg);
  }
  @else if $dir == "right" {
    transform: rotate(-90deg);
  }
}

// Blockquote
// ---

@mixin blockquote() {
  @include core.gap(var.$blockquote-gap, "y");
  position: relative;
  padding: var.$blockquote-padding;
  border: var.$blockquote-border;
  border-radius: var.$blockquote-border-radius;
  background: var.$blockquote-background;
  color: var.$blockquote-color;

  @if var.$blockquote-accent-color {
    &::before {
      content: "";
      position: absolute;
      top: var.$blockquote-accent-offset;
      bottom: var.$blockquote-accent-offset;
      left: var.$blockquote-accent-offset;
      width: var.$blockquote-accent-width;
      background-color: var.$blockquote-accent-color;
    }
  }
}

// Code
// ---

@mixin code() {
  padding: var.$code-padding;
  border: var.$code-border;
  border-radius: var.$code-border-radius;
  background: var.$code-background;
  color: var.$code-color;
  font-family: var.$font-family-mono;
  font-size: var.$code-font-size;
  overflow-wrap: break-word;
}

// Heading
// ---

@mixin heading-base() {
  color: var.$heading-color;
  font-family: var.$heading-font-family;
  font-weight: var.$heading-font-weight;
  line-height: var.$heading-line-height;
}

@mixin heading-levels($map: var.$heading-scale, $prefix: null) {
  @each $key, $value in $map {
    $font-size: $value;
    $line-height: null;
    @if meta.type-of($value) == list {
      $font-size: list.nth($value, 1);
      $line-height: list.nth($value, 2);
    }
    #{$prefix}#{$key} {
      font-size: $font-size;
      line-height: $line-height;
    }
  }
}

@mixin heading($level, $map: var.$heading-scale) {
  $value: null;
  @if meta.type-of($level) == number {
    $value: list.nth(map.values($map), $level);
  }
  @else if meta.type-of($level) == string {
    $value: map.get($map, $level);
  }
  $font-size: $value;
  $line-height: null;
  @if meta.type-of($value) == list {
    $font-size: list.nth($value, 1);
    $line-height: list.nth($value, 2);
  }
  font-size: $font-size;
  line-height: $line-height;
}

// Link
// ---

@mixin link() {
  transition: var.$link-transition;
  border-bottom: var.$link-border;
  color: var.$link-color;
  text-decoration: var.$link-text-decoration;

  &:hover {
    border-bottom: var.$link-border-hover;
    color: var.$link-color-hover;
    text-decoration: var.$link-text-decoration-hover;
  }

  &:focus {
    outline: var.$link-outline-focus;
    outline-offset: var.$link-outline-focus-offset;
    border-bottom: var.$link-border-hover;
    color: var.$link-color-hover;
    text-decoration: var.$link-text-decoration-hover;
  }
}

@mixin link-modifier($modifier) {
  @if $modifier == "subtle" {
    border-color: var.$link-subtle-border-color;
    color: var.$link-subtle-color;

    &:hover,
    &:focus {
      border-color: var.$link-subtle-border-color-hover;
      color: var.$link-subtle-color-hover;
    }
  }

  @else if $modifier == "invert" {
    border-color: var.$link-invert-border-color;
    color: var.$link-invert-color;

    &:hover,
    &:focus {
      border-color: var.$link-invert-border-color-hover;
      color: var.$link-invert-color-hover;
    }
  }

  @else if $modifier == "invert-subtle" {
    border-color: var.$link-invert-subtle-border-color;
    color: var.$link-invert-subtle-color;

    &:hover,
    &:focus {
      border-color: var.$link-invert-subtle-border-color-hover;
      color: var.$link-invert-subtle-color-hover;
    }
  }
}

// List
// ---

@mixin list() {
  margin-left: var.$list-indent;

  ul,
  ol {
    margin-left: var.$list-indent;
  }

  li li,
  li + li {
    margin-top: var.$list-item-gap;
  }
}

// Pre
// ---

@mixin pre() {
  padding: var.$pre-padding;
  overflow: auto;
  border: var.$pre-border;
  border-radius: var.$pre-border-radius;
  background: var.$pre-background;
  color: var.$pre-color;
  font-family: var.$font-family-mono;

  code {
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font-size: 1em;
  }
}

// Scroll-box
// ---

@mixin scroll-box() {
  display: block;
  width: 100%;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

// Separator
// ---

@mixin separator($border) {
  display: block;
  height: 0;
  border: none;
  border-top: $border;
}

// Type
// ---

@mixin type() {
  @include core.gap(var.$type-gap, "y");
  color: var.$type-color;
  font-family: var.$type-font-family;
  font-size: var.$type-font-size;
  line-height: var.$type-line-height;

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    @include heading-base();
  }

  > {
    @include heading-levels();
  }

  > a,
  > :not(div) a {
    @include link();
  }

  > code,
  > :not(div) code {
    @include code();
  }

  > hr {
    @include separator(var.$separator-border);
  }

  > ul,
  > ol {
    @include list();
  }

  > blockquote {
    @include blockquote();
  }

  > pre {
    @include pre();
  }
}

@mixin type-invert() {
  color: var.$type-color-invert;

  > h1,
  > h2,
  > h3,
  > h4,
  > h5,
  > h6 {
    color: var.$heading-color-invert;
  }

  > hr {
    @include separator(var.$separator-border-invert);
  }

  > blockquote {
    border-color: var.$blockquote-border-color-invert;
  }

  > a,
  > :not(div) a {
    @include link-modifier("invert");
  }

  > code,
  > :not(div) code {
    color: var.$code-color-invert;
  }

  > pre {
    color: var.$pre-color;

    code {
      color: inherit;
    }
  }
}
