//
//  Copyright (c) 2021 GrowStocks
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all
//  copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//  SOFTWARE.
//

@use 'sass:map';
@use 'sass:list';
@use 'sass:meta';
@use 'sass:math';

// Related Modules
@use '../Color';
@use '../Shape';
@use '../Typography';
@use '../Feature';

$_prefix: 'sc';
$_valid-screen-properties: ('small', 'medium', 'large', 'xlarge');
$_valid-color-variants: ('default', 'light', 'dark', 'ink');

$breakpoints: (
    'small': 320px,
    'medium': 540px,
    'large': 850px,
) !default;

$_state-map: (
    'error': (#b00020, #fff),
    'warning': (#ffa000, #000),
    'success': (#25a53f, #fff),
) !default;

$_radius-theme: (
    'small': 0.3rem,
    'medium': 0.5rem,
    'large': 0.7rem
) !default;

@mixin config(
    $primary-color: (),
    $secondary-color: Color.get-complement_($primary-color),
    $screen-sizes: (),
    $radius-settings: $_radius-theme,
    $args...
) {

    @if meta.type-of($primary-color) != map {

        $_color-map: Color.split($primary-color);

        @each $property, $value in $_color-map {
            @if $property == 'default' {
                --#{$_prefix}-theme--primary: #{$value};
            } @else {
                --#{$_prefix}-theme--primary-#{$property}: #{$value};
            }
        }

    } @else if _is-variant($primary-color) {

        $_properties: _check-variants($primary-color);

        $_color-map: Color.fill-missing($_properties, $primary-color);

        @each $property, $value in $_color-map {
            @if $property == 'default' {
                --#{$_prefix}-theme--primary: #{$value};
            } @else {
                --#{$_prefix}-theme--primary-#{$property}: #{$value};
            }
        }

    }

    @if meta.type-of($secondary-color) != map {

        $_color-map: Color.split($secondary-color);

        @each $property, $value in $_color-map {
            @if $property == 'default' {
                --#{$_prefix}-theme--secondary: #{$value};
            } @else {
                --#{$_prefix}-theme--secondary-#{$property}: #{$value};
            }
        }

    } @else if _is-variant($secondary-color) {

        $_properties: _check-variants($secondary-color);

        $_color-map: Color.fill-missing($_properties, $secondary-color);

        @each $property, $value in $_color-map {
            @if $property == 'default' {
                --#{$_prefix}-theme--secondary: #{$value};
            } @else {
                --#{$_prefix}-theme--secondary-#{$property}: #{$value};
            }
        }

    }

    @if meta.type-of($primary-color) == map {
        @if Feature.has-property($primary-color, 'ink') {
            --#{$_prefix}-theme--on-primary: #{map.get($primary-color, 'ink')};
        } @else {
            --#{$_prefix}-theme--on-primary: #{Color.get-ink_($primary-color)};
        }
    } @else {
        --#{$_prefix}-theme--on-primary: #{Color.get-ink_(Color.split($primary-color))};
    }

    @if meta.type-of($secondary-color) == map {
        @if Feature.has-property($secondary-color, 'ink') {
            --#{$_prefix}-theme--on-secondary: #{map.get($secondary-color, 'ink')};
        } @else {
            --#{$_prefix}-theme--on-secondary: #{Color.get-ink_($secondary-color)};
        }
    } @else {
        --#{$_prefix}-theme--on-secondary: #{Color.get-ink_(Color.split($secondary-color))};
    }

    @each $property, $value in $_state-map {
        --#{$_prefix}-theme--#{$property}: #{list.nth($value, 1)};
    }

    @each $property, $value in $_state-map {
        --#{$_prefix}-theme--on-#{$property}: #{list.nth($value, 2)};
    }

    @each $property, $value in $radius-settings {
        --#{$_prefix}-theme--#{$property}-radius: #{$value};
    }

    @each $property, $value in meta.keywords($args) {
        --#{$_prefix}-theme--#{$property}: #{$value};
    }

    @if (Feature.is-empty($screen-sizes)) == false {
        @each $property, $value in $screen-sizes {

            $_valid-property: Feature.has-item($_valid-screen-properties, $property);

            @if $_valid-property == true {
                $breakpoints: map.merge($breakpoints, $screen-sizes);
            } @else {
                @error 'Screen property: #{$property} is invalid. Please select from the following valid screen properties: #{$_valid-screen-properties}';
            }

        }
    }

}

@function get-breakpoint($query, $reference: $breakpoints) {

    @return map.get($reference, $query);

}

@function _is-variant($query) {

    @each $property, $value in $query {

        @if not Feature.has-item($_valid-color-variants, $property) {
            @error 'Invalid variant: #{$property}. The available variants are: #{$_valid-color-variants}';
        }

        @return true;

    }

}

@function _check-variants($query) {

    @if Feature.validate-data-type('map', $query) {

        @return map.keys($query);

    }

}

@function _get-default($query) {

    @if Feature.validate-data-type('map', $query) {

        @return map.get($query, 'default');

    }

}

// @depricated
@mixin _set-breakpoint($screen-sizes: ()) {
    @if (Feature.is-empty($screen-sizes)) == false {
        @each $property, $value in $screen-sizes {

            $_valid-property: Feature.has-item($_valid-screen-properties, $property);

            @if $_valid-property == true {
                $breakpoints: map.merge($breakpoints, $screen-sizes);
            } @else {
                @error 'Screen property: #{$property} is invalid. Please select from the following valid screen properties: #{$_valid-screen-properties}';
            }

        }
    }
}
