////
/// @group card
/// A versatile container for displaying and summarizing individual items, entities, or resources in a visually appealing and concise format
////

@use "sass:map";
@use 'sass:list';

@use "../breakpoint";
@use "../utils";
@use "../selector";
@use "../color";
@use "../layout";

// todo
// sass color adjust for smooth transition. Add a comment for this if we can’t get to this

/// Module Settings
/// @type Map
/// @prop {Dimension} padding [2rem] The padding for the image icon
/// @prop {Dimension} margin-y [3rem] Top and bottom margin for the card.
/// @prop {Dimension} border-radius [5rem] The border radius of the card.
/// @prop {CssValue} box-shadow [null] The box-shadow for the card.
/// @prop {CssValue} box-shadow-hover [null] The box-shadow for the card when hovered or focused.
/// @prop {Color} color [null] The type color of the card.
/// @prop {Color} color-hover [null] The type color of the card when hovered or focused.
/// @prop {Color} color-overlay [white] The type color of the card when using card--overlay.
/// @prop {Color} color-overlay-hover [null] The type color of the card when hovered or focused and when using card--overlay.
/// @prop {Color} overlay-background-color [rgba(0, 0, 0, 0.6)] The background color for the text box when using card--overlay.
/// @prop {Color} background-color [white] The background color of the card.
/// @prop {Color} background-color-hover [rgb(242, 244, 246)] The background color of the card when hovered or focused.
/// @prop {Dimension} max-width [28rem] The max-width of the card.
/// @prop {Dimension} body-min-height [8rem] the min-height of the card body.
/// @prop {CssValue} border [1px solid #ccc] The card border.
/// @prop {CssValue} border-hover [2px solid #278cca] The card border when hovered or focused.
/// @prop {Dimension} header-margin [0.75em] The margin for the card header.
/// @prop {Color} title-color [null] The type color of the title.
/// @prop {Color} title-color-hover [null] The type color of the title (if link/button) when hovered or focused
/// @prop {Dimension} title-margin [0] The margin for the title.
/// @prop {CssValue} title-font-weight [bold] The font weight for the title.
/// @prop {Number} image-ratio [56.25%] The image ratio for the card image.
/// @prop {Color} image-background-color [rgb(197, 197, 197)] The background color behind the image.
/// @prop {Dimension} image-margin [null] The margin for the image.
/// @prop {Dimension} image-border [null] // For when you have a margin, the border for the image.
/// @prop {CssValue} image-transform-hover [null] Animation for the image when hovered or focused.
/// @prop {CssValue} image-filter-hover [null] Filter for the image when hovered or focused.
/// @prop {Color} overlay-background-color-hover [null] The color of the pseudo-element when using proxy click.
/// @prop {Boolean} clickable-card-enabled [true] Enable or disable proxy click.
/// @prop {String} clickable-card-selector [data-ulu-proxy-click-init] The selector for proxy-click.js to find the card and implement the clickable card script.
/// @prop {String} clickable-card-interact-selector [&:hover, &:focus-within] The selectors for the cards being interacted with.
/// @prop {Dimension} footer-padding-y [0.25rem] The top and bottom padding for the footer.
/// @prop {Dimension} footer-min-height [2.5rem] The min height for the footer
/// @prop {String} prefix [card] The class name used to add card styling.
/// @prop {Boolean} transition-enabled [true] Enable or disable transition for card.
/// @prop {CssValue} transition-timing-function [ease-in-out] The timing function for the card animation.
/// @prop {Time} transition-duration [200ms] The animation duration for the card animation.
/// @prop {List} transition-properties [(border-color, background-color, color, box-shadow, transform)] The properties for the card animation.
/// @prop {Boolean} image-transition-enabled [true] Enable or disable the image transition.
/// @prop {Time} image-transition-duration [350ms] The duration of the image transition.
/// @prop {CssValue} image-transition-timing-function [ease-in-out] The timing function for the image transition.
/// @prop {Number} image-fit-padding [1rem] Padding on inside of image when using image fit modifier
/// @prop {CssValue} image-fit-filter [drop-shadow(0 0px 8px rgba(0, 0, 0, 0.2))] Filter to use on image when using image fit modifier
/// @prop {List} image-icon-max-width [10rem] Max width for image when using the modifier on the .card__image--icon
/// @prop {List} image-transition-properties [(transform, filter)] The properties for the image transitions.
/// @prop {String} horizontal-breakpoint [small] The breakpoint used to change the card to vertical if using the card--horizontal styling. Uses ulu's breakpoint module.
/// @prop {Unit} horizontal-min-height [10rem] Minimum height when horizontal
/// @prop {Unit} horizontal-max-width [40rem] Maximum width when horizontal
/// @prop {Unit} horizontal-body-max-width [80rem] The max-width of body when horizontal
/// @prop {Boolean} aside-rule [false] Whether or not to have a rule separating body and aside
/// @prop {CssUnit} aside-rule-width [1px] Size of rule
/// @prop {CssUnit} aside-rule-color ["rule-light"] Color of rule
/// @prop {CssUnit} aside-rule-background-color [transparent] Color of aside background color

$config: (
  "background-color" : white,
  "background-color-hover" : rgb(242, 244, 246),
  "body-min-height" : 10rem,
  "border" : 1px solid #ccc,
  "border-hover" : 2px solid #278cca,
  "border-radius" : 5px,
  "box-shadow" : null,
  "box-shadow-hover" : null,
  "clickable-card-enabled" : true,
  "clickable-card-selector" : "[data-ulu-proxy-click-init]",
  "clickable-card-interact-selector" : "&:hover, &:focus-within",
  "color" : null,
  "color-hover" : null,
  "footer-padding-y" : 0.25rem,
  "footer-min-height" : 2.5rem,
  "horizontal-breakpoint" : "small",
  "horizontal-image-width" : min(33%, 20rem),
  "horizontal-body-max-width" : 40rem,
  "horizontal-min-height" : 20rem,
  "horizontal-max-width" : 80rem,
  "header-margin" : 0.75em,
  "image-ratio" : 56.25%,
  "image-aspect-ratio": list.slash(5, 3),
  "image-background-color" : rgb(238, 238, 238),
  "image-border" : null, // For when you have a margin
  "image-filter-hover" : null,
  "image-margin" : null,
  "image-icon-max-width" : 8rem,
  "image-transform-hover" : null,
  "image-transition-duration" :    350ms,
  "image-transition-enabled" : true,
  "image-transition-properties" : (transform, filter),
  "image-transition-timing-function" : ease-in-out,
  "image-fit-padding" : 1rem,
  "image-fit-filter" : drop-shadow(0 0px 8px rgba(0, 0, 0, 0.3)),
  "margin-y" : 3rem,
  "max-width" : 28rem,
  "padding" : 2rem,
  "title-color" : null,
  "title-color-hover" : null,
  "title-color-card-hover" : null,
  "title-margin" : 1rem,
  "title-font-weight" : bold,
  "transition-enabled":      true,
  "transition-timing-function" : ease-in-out,
  "transition-duration" :    200ms,
  "transition-properties" :  (border-color, background-color, color, box-shadow, transform),
  "overlay-aspect-ratio": list.slash(4, 3),
  "overlay-background-color-hover" : null,
  "color-overlay" : white,
  "color-overlay-hover" : null,
  "overlay-background-color": rgba(0, 0, 0, 0.6),
  "overlay-shading": true,
  "overlay-body-padding-y": 1rem,
  // new below
  "aside-rule" : false,
  "aside-rule-width" : 1px,
  "aside-background-color" : transparent,
  "aside-rule-color": "rule-light",
) !default;
  
  /// Change modules $config
/// @param {Map} $changes Map of changes
/// @example scss
///   @include ulu.component-card-set(( "property" : value ));

@mixin set($changes) {
  $config: map.merge($config, $changes) !global;
}

/// Get a config option
/// @param {Map} $name Name of property
/// @example scss
///   @include ulu.component-card-get(( "property" : value ));

@function get($name) {
  @return utils.require-map-get($config, $name, "card [config]");
}

/// Mixin styles for card when it has proxy click enabled and is being interacted with (hover/focus)
/// @param {Boolean} $hover [false] Apply styles when the card is being hover/focused within, else applies styles to rest state of a clickable card (one who has a proxy click setup)
/// Prints component styles
/// @example scss
///  @include ulu.component-card-styles();

@mixin when-clickable($hover: false) {
  $prefix: selector.class("card");
  // When proxy click enabled
  @if (get("clickable-card-enabled") and get("clickable-card-selector")) {
    #{ $prefix }#{ get("clickable-card-selector") },
    a#{ $prefix },
    button#{ $prefix },
    #{ $prefix }--clickable {
      @if ($hover) {
        #{ get("clickable-card-interact-selector") } {
          @content;
        }
      } @else {
        @content;
      }
    }
  // Without proxy click (only if interactive)
  } @else {
    a#{ $prefix },
    button#{ $prefix },
    #{ $prefix }--clickable {
      @if ($hover) {
        #{ get("clickable-card-interact-selector") } {
          @content;
        }
      } @else {
        @content;
      }
    }
  } 
}


@mixin shared-transition-styles() {
  transition-duration: get("transition-duration");
  transition-timing-function: get("transition-timing-function");
}
/// Prints component styles
/// @demo card
/// @example scss
/// @example
///   @include ulu.component-card-styles();

@mixin styles {
  $prefix: selector.class("card");

  #{ $prefix } {
    color: color.get(get("color"));
    background-color: color.get(get("background-color"));
    border-radius: get("border-radius");
    box-shadow: get("box-shadow");
    margin-top: get("margin-y");
    margin-bottom: get("margin-y");
    position: relative;
    display: flex; // Reorder image
    flex-direction: column;
    justify-content: flex-end;
    max-width: get("max-width");
    // Not absolutely necessary, incase we want to remove in future
    overflow: hidden; 

    // Border is on pseudo so that it's on top of image/etc
    &::after {
      @include layout.absolute-fill();
      content: if(get("border"), "", null);
      border: get("border");
      border-radius: get("border-radius");
      z-index: 4;
      pointer-events: none;
    }
  }

  @include when-clickable($hover: true) {
    background-color: color.get(get("background-color-hover"));
    color: color.get(get("color-hover"));
    box-shadow: get("box-shadow-hover");
    
    @if (get("border-hover") or get("overlay-background-color-hover")) {
      &::after {
        content: "";
        border: get("border-hover");
        background-color: color.get(get("overlay-background-color-hover"));
      }
    }
  }

  // Setting transitions regardless of clickable card selector
  // This shouldn't interfere since styles aren't changed if not clickable (ie. .card [border-color, etc])
  @if get("transition-enabled") {
    #{ $prefix },
    #{ $prefix }::after,
    #{ $prefix }__title {
      @include shared-transition-styles();
      transition-property: get("transition-properties");
    }
  } 

  #{ $prefix }__title {
    color: color.get(get("title-color"));
    margin-bottom: get("title-margin");
    display: block;
    font-weight: get("title-font-weight");
    #{ $prefix }__title-link {
      all: unset;
      cursor: pointer;
      @if get("title-color-hover") {
        &:hover,
        &:focus {
          color: color.get(get("title-color-hover"));
        }
      }
    }
  }
  @if get("title-color-hover") {
    @include when-clickable($hover: true) {
      #{ $prefix }__title {
        color: color.get(get("title-color-hover"));
      }
    }
  }

  #{ $prefix }__header + #{ $prefix }__content {
    margin-top: get("header-margin");
  }
  
  // Fix since sometimes these have nested markup sometimes just raw text
  #{ $prefix }__image {
    order: -1;
    position: relative;
    z-index: 1;
    overflow: hidden;
    // padding-top: get("image-ratio"); // 9:16
    margin: get("image-margin");
    border: get("image-border");
    background-color: color.get(get("image-background-color"));
    border-top-right-radius: get("border-radius");
    border-top-left-radius: get("border-radius");
    aspect-ratio: get("image-aspect-ratio");
    width: 100%;
  }
  #{ $prefix }__image img,
  #{ $prefix}__image-media {
    @include layout.absolute-fill(true);
    border: 0;
    object-fit: cover;
    transform-origin: center center;
    @if (get("image-transition-enabled")) {
      transition-duration: get("image-transition-duration");
      transition-timing-function: get("image-transition-timing-function");
      transition-property: get("image-transition-properties");
    }
  }
  @if (get("image-transform-hover") or get("image-filter-hover")) {
    @include when-clickable($hover: true) {
      #{ $prefix }__image img,
      #{ $prefix}__image-media {
        transform: get("image-transform-hover");
        filter: get("image-filter-hover");
      }
    }
  }

  #{ $prefix }__footer {
    padding: get("padding");
  }
  #{ $prefix }__main {
    padding: get("padding");
  }
  #{ $prefix }__aside {
    position: relative;
    padding: get("padding");
  }

  #{ $prefix }__image--icon {
    // background-color: transparent; 
    display: flex;
    align-items: center;
    justify-content: center;
    // padding: 2rem;
    img {
      position: static;
      display: block;
      max-width: get("image-icon-max-width");
      height: auto;
      top: auto;
      left: auto;
    }
  }
  #{ $prefix }__body,
  #{ $prefix }__footer { 
    position: relative;
    z-index: 2; // Above image
  }
  #{ $prefix }__body {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-height: get("body-min-height");
  }
  @if(get("aside-rule")) {
    #{ $prefix }__aside {
      background-color: color.get(get("aside-background-color"));
    }
    #{ $prefix }__aside::after {
      content: "";
      position: absolute;
      top: calc(0rem - get("aside-rule-width") / 2);
      left: get("padding");
      right: get("padding");
      height: get("aside-rule-width");
      background-color: color.get(get("aside-rule-color"));
    }
  }
  // For actions/messages
  // - Layout as flex with min height to support buttons 
  //   and text without relying so much on padding
  #{ $prefix }__footer {
    flex: 0;
    z-index: 4;
    padding-top: get("footer-padding-y");
    padding-bottom: get("footer-padding-y");
    min-height: get("footer-min-height");
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
  // body + footer {
  // means body keeps before pseudo element while footer loses it
  #{ $prefix }--overlay {
    // overflow: hidden;
    aspect-ratio: get("overlay-aspect-ratio");
    height: min-content;
    #{ $prefix }__body {
      position: relative;
      flex-grow: 0;
      z-index: 2;
      color: color.get(get("color-overlay"));
      background-color: color.get(get("overlay-background-color"));
      min-height: 0;
      padding-top: get("overlay-body-padding-y");
      padding-bottom: get("overlay-body-padding-y");
      
      &:not(:has(~ #{ $prefix }__footer)) {
        border-bottom-left-radius: get("border-radius");
        border-bottom-right-radius: get("border-radius");
      }

      @if (get("overlay-shading")) {
        margin-top: 4rem;
        &::before {
          content: "";
          position: absolute;
          bottom: 100%;
          left: 0;
          right: 0;
          height: 4rem;
          background: linear-gradient(to top, get("overlay-background-color") 0%, rgba(0, 0, 0, 0));
        }
      }
    }
    #{ $prefix }__footer {
      background-color: color.get(get("overlay-background-color"));
      color: color.get(get("color-overlay"));
      border-bottom-left-radius: get("border-radius");
      border-bottom-right-radius: get("border-radius");
    }
    #{ $prefix }__body,
    #{ $prefix }__footer {
      &:last-child {
        border-bottom-left-radius: get("border-radius");
        border-bottom-right-radius: get("border-radius");
      }
    }
    #{ $prefix }__title {
      color: color.get(get("color-overlay"));
    }
    #{ $prefix }__image {
      @include layout.absolute-fill();
      overflow: hidden;
      padding-top: 0;
      background-color: color.get(rgb(255, 255, 255));
      border-radius: get("border-radius");
      aspect-ratio: auto;
      img {      
        z-index: 1;
        position: relative;
        width: 100%;
        height: 100%;
        border: 0;
        object-fit: cover;
        &::before {
          @include layout.absolute-fill(true);
          display: block;
          background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(0, 0, 0, 0.9));
        }
      }
    }
  }

  // Incase this modifier is being used to hide the image
  // not just to tell the component how to layout without image
  // - Use case is hiding image when you can't control the output 
  //   of the inside of the card (printed no matter what). We had
  //   this happen in HHRC, including this extra CSS for that
  #{ $prefix }--no-image {
    #{ $prefix }__image {
      display: none;
    }
  }
  #{ $prefix }--image-fit {
    #{ $prefix }__image {
      img {
        padding: get("image-fit-padding");
        object-fit: contain;
        object-position: top center;
        filter: get("image-fit-filter");
      }
    }
  }
  #{ $prefix }--fill {
    max-width: none;
    height: 100%;
    margin: 0;
  }

  @if (get("horizontal-breakpoint")) {
    @include breakpoint.min(get("horizontal-breakpoint")) {
      @include -horizontal-card-styles();
    }
  } @else {
    @include -horizontal-card-styles();
  }
}

@mixin -horizontal-card-styles() {
  $prefix: selector.class("card");

  #{ $prefix }--horizontal {
    display: grid;
    grid-template-columns: get("horizontal-image-width") 1fr;
    // Creating the two rows (body and footer), if one is missing it's height will be 0
    // Cannot use gap with the grid as it will create space when a row isn't needed
    grid-template-rows: auto auto;
    min-height: get("horizontal-min-height");
    max-width: get("horizontal-max-width");

    // When no footer remove extra row
    &:not(:has(> #{ $prefix }__footer)) {
      grid-template-rows: auto;
    }
    #{ $prefix }__image {
      grid-column: 1 / 2;
      grid-row: 1 / -1;
      aspect-ratio: auto;
      border-top-right-radius: 0;
      border-bottom-left-radius: get("border-radius");
    }
    #{ $prefix }__body,
    #{ $prefix }__footer {
      grid-column: 2 / 3;
    }
    #{ $prefix }__body {
      flex-direction: row;
      max-width: get("horizontal-body-max-width");
    }
    
    @if(get("aside-rule")) {
      #{ $prefix }__main {
        flex: 1 1 60%;
      }
      #{ $prefix }__aside {
        flex: 1 1 40%;
        height: 100%;
        // flex-basis: 40%;
        // min-width: 40%;
      }
      #{ $prefix }__aside::after {
        content: "";
        position: absolute;
        top: get("padding");
        left: calc(0rem - get("aside-rule-width") / 2);
        height: calc(100% - get("padding") - get("padding"));
        width: get("aside-rule-width");
        background-color: get("aside-rule-color");
      }
    }

    // For modern browsers
    // Optionally use no-image modifier for older browser support
    &:not(:has(#{ $prefix }__image)) {
      @include -card-horizontal-no-image-styles();
    }
    &#{ $prefix }--no-image {
      @include -card-horizontal-no-image-styles();
    }
  }
  #{ $prefix }--horizontal-center {
    #{ $prefix }__body {
      align-self: center;
    }
  }
}

@mixin -card-horizontal-no-image-styles() {
  $prefix: selector.class("card");
  grid-template-columns: 1fr;
  #{ $prefix }__body,
  #{ $prefix }__footer {
    grid-column: 1 / 2;
  }
}

// OLD CSS FOR HORIZONTAL
  // #{ $prefix }--horizontal {
  //   display: flex;
  //   flex-direction: row;
  //   justify-content: center;
  //   align-items: center;
  //   #{ $prefix }__image {
  //     align-self: stretch;
  //     border-top-right-radius: 0;
  //     border-bottom-left-radius: get("border-radius");
  //     width: get("horizontal-image-width");
  //     flex: 0 0 get("horizontal-image-width");
  //     // max-width: 30rem;
  //     // min-height: 28rem;
  //     // padding-top: 0;
  //   }
  //   #{ $prefix }__body {
  //     display: flex;
  //     flex: 1;
  //     flex-direction: column;
  //     justify-content: center;
  //     max-width: get("horizontal-body-max-width");
  //   }
  // }

