@use 'sass:map';
@use 'sass:meta';
@use '@angular/material' as mat;
@use '../components/action-dialog/action-dialog.component' as action-dialog;
@use '../components/avatar/avatar.component' as avatar;
@use '../components/page-menu/page-menu.component' as page-menu;
@use '../components/payment-fees/payment-fees.component' as payment-fees;
@use '../components/paginated-table/paginated-table.component' as paginated-table;
@use './variables';

// Ensure core styles are included once
@include mat.core();

/**
 * Function to override foreground and background colors in a theme
 */
@function override-theme-colors($theme) {
  @return map-merge(
    $theme,
    (
      color: map-merge(
          map.get($theme, color),
          (
            foreground: map-merge(
                map.get($theme, color, foreground),
                (
                  base: variables.$dark-gray,
                  text: variables.$dark-gray,
                )
              ),
            background: map-merge(
                map.get($theme, color, background),
                (
                  background: variables.$white,
                )
              ),
          )
        ),
    )
  );
}

@function normalize-palette-shade($shade) {
  @if meta.type-of($shade) == number {
    @return $shade;
  }

  @if meta.type-of($shade) == string {
    $numeric-shades: (
      '50': 50,
      '100': 100,
      '200': 200,
      '300': 300,
      '400': 400,
      '500': 500,
      '600': 600,
      '700': 700,
      '800': 800,
      '900': 900,
      '950': 950,
    );

    @if map.has-key($numeric-shades, $shade) {
      @return map.get($numeric-shades, $shade);
    }
  }

  @return $shade;
}

@function validate-palette-shade($palette, $shade, $tone-name) {
  $normalized-shade: normalize-palette-shade($shade);

  @if map.has-key($palette, $normalized-shade) {
    @return $normalized-shade;
  }

  @error "Invalid #{$tone-name} shade `#{$shade}`. Available keys: #{map.keys($palette)}";
}

/**
 * This mixin provides a hook to initialize Angular Material theming
 * using the design system's recommended palettes (or custom ones).
 */
@mixin apply-material-theme($color-palette: ()) {
  // Set defaults for missing values
  $default-primary: variables.$dark-blue-palette;
  $default-accent: variables.$light-blue-palette;
  $default-warn: variables.$red-palette;
  $default-primary-shade: 800;
  $default-accent-shade: 500;

  // Extract individual palettes from the map, using defaults if not provided
  $primary-palette: $default-primary;
  $accent-palette: $default-accent;
  $warn-palette: $default-warn;
  $primary-shade: $default-primary-shade;
  $accent-shade: $default-accent-shade;

  @if map-has-key($color-palette, primary) {
    $primary-palette: map.get($color-palette, primary);
  }
  @if map-has-key($color-palette, accent) {
    $accent-palette: map.get($color-palette, accent);
  }
  @if map-has-key($color-palette, warn) {
    $warn-palette: map.get($color-palette, warn);
  }
  @if map-has-key($color-palette, primary-shade) {
    $primary-shade: map.get($color-palette, primary-shade);
  }
  @if map-has-key($color-palette, accent-shade) {
    $accent-shade: map.get($color-palette, accent-shade);
  }

  $primary-shade: validate-palette-shade($primary-palette, $primary-shade, 'primary');
  $accent-shade: validate-palette-shade($accent-palette, $accent-shade, 'accent');

  $primary: mat.define-palette($primary-palette, $primary-shade);
  $accent: mat.define-palette($accent-palette, $accent-shade);
  $warn: mat.define-palette($warn-palette);
  $typography: mat.define-typography-config(
    $font-family: '"OpenSans", sans-serif',
  );

  $theme: mat.define-light-theme(
    (
      color: (
        primary: $primary,
        accent: $accent,
        warn: $warn,
      ),
      typography: $typography,
      density: 0,
    )
  );

  // Override foreground and background colors
  $theme: override-theme-colors($theme);

  @include mat.all-component-themes($theme);
  @include mat.typography-hierarchy($theme);
  @include mat.private-form-field-density(-3);

  @include action-dialog.action-dialog-theme($theme);
  @include avatar.avatar-theme($theme);
  @include page-menu.page-menu-theme($theme);
  @include payment-fees.payment-fees-theme($theme);
  @include paginated-table.paginated-table-theme($theme);
}

// Optional: Default theme initialization if the user just wants to @use this file
$primary-palette: mat.define-palette(variables.$dark-blue-palette, 800);
$accent-palette: mat.define-palette(variables.$light-blue-palette, 500);
$warn-palette: mat.define-palette(variables.$red-palette);
$typography: mat.define-typography-config(
  $font-family: '"OpenSans", sans-serif',
);

$theme: mat.define-light-theme(
  (
    color: (
      primary: $primary-palette,
      accent: $accent-palette,
      warn: $warn-palette,
    ),
    typography: $typography,
    density: 0,
  )
);

// Override foreground and background colors
$theme: override-theme-colors($theme);

@include action-dialog.action-dialog-theme($theme);
@include avatar.avatar-theme($theme);
@include page-menu.page-menu-theme($theme);
@include payment-fees.payment-fees-theme($theme);
@include paginated-table.paginated-table-theme($theme);
