/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

@use 'sass:map';
@use '@angular/material' as mat;

@mixin generate-theme($material-theme, $config) {
    $is-material-dark: if(mat.get-theme-type($material-theme) == dark, true, false);
    $material-theme-primary-palette-default: mat.get-theme-color(
        $material-theme,
        primary,
        map.get(map.get($config, primary), default)
    );
    $material-theme-secondary-palette-default: mat.get-theme-color(
        $material-theme,
        secondary,
        map.get(map.get($config, secondary), default)
    );
    $material-theme-tertiary-palette-default: mat.get-theme-color(
        $material-theme,
        tertiary,
        map.get(map.get($config, tertiary), default)
    );
    $material-theme-error-palette-default: mat.get-theme-color(
        $material-theme,
        error,
        map.get(map.get($config, error), default)
    );
    $material-theme-neutral-palette-default: mat.get-theme-color(
        $material-theme,
        neutral,
        map.get(map.get($config, neutral), default)
    );
    $material-theme-neutral-palette-darker: mat.get-theme-color(
        $material-theme,
        neutral,
        map.get(map.get($config, neutral), darker)
    );
    $material-theme-neutral-palette-lighter: mat.get-theme-color(
        $material-theme,
        neutral,
        map.get(map.get($config, neutral), lighter)
    );
    $primary-contrast: map.get(map.get($config, primary), contrast);
    $caution-contrast: map.get(map.get($config, caution), contrast);
    $error-contrast: map.get(map.get($config, error), contrast);
    $neutral-contrast: map.get(map.get($config, neutral), contrast);
    $border-color: mat.get-theme-color($material-theme, neutral-variant, map.get($config, neutral-variant));
    $success-lighter: map.get(map.get($config, success), lighter);
    $success-default: map.get(map.get($config, success), default);
    $caution: map.get(map.get($config, caution), default);

    // Shadows should always be darker. We explicitly set this so the SVG shadows are correct in both modes.
    $drop-shadow-color: black;
    $connection-drop-shadow-color: if($is-material-dark, black, white);

    .canvas-background {
        background-color: if(
            $is-material-dark,
            $material-theme-neutral-palette-darker,
            $material-theme-neutral-palette-lighter
        );
        background-image: linear-gradient(to right, if($is-material-dark, #0d1411, #e5ebed) 1px, transparent 1px),
            linear-gradient(to bottom, if($is-material-dark, #0d1411, #e5ebed) 1px, transparent 1px);
    }

    /* svg styles */

    svg.canvas-svg {
        /*
          All components
      */

        g.component {
            font-family: mat.get-theme-typography($material-theme, body-medium, font-family);
        }

        .transparent {
            fill: transparent;
        }

        g.component rect.body {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        rect.banner {
            fill: rgba(
                if($is-material-dark, $material-theme-neutral-palette-lighter, $material-theme-neutral-palette-darker),
                0.08
            );
        }

        rect.odd {
            fill: rgba(
                if($is-material-dark, $material-theme-neutral-palette-lighter, $material-theme-neutral-palette-darker),
                0.025
            );
        }

        rect.even {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        rect.row-border {
            fill: $border-color;
        }

        g.component rect.body.unauthorized {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        g.component rect.border,
        g.connections rect.border {
            stroke: $border-color;
            stroke-width: if(
                $is-material-dark,
                2,
                1
            ); // Dark mode gets a wider stroke to provide contrast between the canvas and components
        }

        g.component rect.border.unauthorized {
            stroke: $material-theme-error-palette-default !important;
        }

        g.component rect.border.ghost {
            stroke: $material-theme-neutral-palette-default !important;
        }

        g.component rect.processor-icon-container.unauthorized {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        g.component.selected rect.border {
            stroke: $material-theme-primary-palette-default !important;
        }

        text.stats-label {
            @extend .neutral-contrast;
            font-family: mat.get-theme-typography($material-theme, body-medium, font-family);
        }

        text.stats-value {
            fill: $material-theme-tertiary-palette-default;
        }

        text.stats-info {
            fill: $material-theme-primary-palette-default;
        }

        text.bulletin-icon {
            &.info,
            &.debug,
            &.trace {
                fill: $primary-contrast;
            }
        }

        text.bulletin-icon {
            &.error {
                fill: $error-contrast;
            }
        }

        text.bulletin-icon {
            &.warning {
                fill: $caution-contrast;
            }
        }

        rect.bulletin-background {
            &.error {
                fill: $material-theme-error-palette-default;
            }
            &.warning {
                fill: $caution;
            }
            &.info,
            &.debug,
            &.trace {
                fill: $success-default;
            }
        }

        text.component-comments {
            fill: $material-theme-primary-palette-default;
            stroke: $border-color;
        }

        /*
          Selection
      */

        g.component.connectable-destination rect.border {
            stroke: #00ff00;
        }

        rect.component-selection,
        rect.drag-selection,
        rect.label-drag {
            stroke: $material-theme-primary-palette-default;
            fill: transparent;
        }

        text.add-connect {
            fill: $material-theme-primary-palette-default;
        }

        /*
          Processor
      */
        #component-drop-shadow feFlood {
            flood-color: $drop-shadow-color;
        }

        rect.processor-read-write-stats {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        rect.processor-stats-border {
            fill: $border-color;
        }

        text.processor-name {
            fill: $neutral-contrast;
        }

        text.processor-type {
            fill: $material-theme-primary-palette-default;
        }

        circle.is-primary-background {
            stroke: if(
                $is-material-dark,
                $material-theme-neutral-palette-lighter,
                $material-theme-neutral-palette-darker
            );
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        text.is-primary {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-lighter,
                $material-theme-neutral-palette-darker
            );
        }

        text.processor-bundle {
            fill: $material-theme-neutral-palette-default;
        }

        rect.processor-icon-container {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        circle.restricted-background {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        text.restricted {
            fill: $material-theme-error-palette-default;
        }

        /*
          Connection
      */
        #connection-full-drop-shadow feFlood {
            flood-color: $material-theme-error-palette-default;
        }

        g.connection {
            font-family: mat.get-theme-typography($material-theme, body-medium, font-family);
        }

        g.connection rect.body {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        g.connection rect.body.unauthorized {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        g.connection rect.border.unauthorized {
            stroke: $material-theme-error-palette-default;
        }

        g.connection rect.border.full {
            stroke: $material-theme-tertiary-palette-default;
        }

        g.connection.selected rect.border {
            stroke: #ffcc00;
        }

        path.connector {
            stroke: #ff0000;
        }

        path.connector.connectable {
            stroke: #00ff00;
        }

        g.connection path.connection-path {
            fill: none;
            stroke: $neutral-contrast;
            filter: drop-shadow(
                0 3px 6px
                    if(
                        $is-material-dark,
                        $material-theme-neutral-palette-darker,
                        $material-theme-neutral-palette-lighter
                    )
            );
        }

        g.connection path.connection-path.full {
            stroke: $material-theme-error-palette-default;
        }

        g.connection path.connection-path.unauthorized {
            stroke: $material-theme-error-palette-default;
        }

        g.connection rect.backpressure-tick {
            fill: transparent;
        }

        g.connection rect.backpressure-tick.data-size-prediction.prediction-down,
        g.connection rect.backpressure-tick.object-prediction.prediction-down {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        g.connection rect.backpressure-tick.data-size-prediction,
        g.connection rect.backpressure-tick.object-prediction {
            fill: $border-color;
        }

        g.connection rect.backpressure-tick.data-size-prediction.not-configured,
        g.connection rect.backpressure-tick.object-prediction.not-configured,
        g.connection rect.backpressure-tick.data-size-prediction.prediction-down.not-configured,
        g.connection rect.backpressure-tick.object-prediction.prediction-down.not-configured {
            fill: transparent;
        }

        g.connection rect.backpressure-tick.not-configured {
            fill: $material-theme-neutral-palette-default;
        }

        g.connection rect.backpressure-object,
        g.connection rect.backpressure-data-size {
            fill: $border-color;
        }

        g.connection rect.backpressure-object.not-configured,
        g.connection rect.backpressure-data-size.not-configured {
            fill: transparent;
        }

        g.connection rect.backpressure-percent {
            fill: $success-lighter;
        }

        g.connection rect.backpressure-percent.warning {
            fill: #ffcc00;
        }

        g.connection rect.backpressure-percent.error {
            fill: $material-theme-error-palette-default;
        }

        /* ghost connection */

        g.connection.ghost path.connection-path,
        g.connection.ghost rect.connection-label {
            stroke: $material-theme-neutral-palette-default;
        }

        g.connection path.connection-selection-path {
            stroke: #ffcc00;
            fill: none;
        }

        g.connection path.connection-path-selectable {
            fill: none;
        }

        g.connection rect.startpoint {
            stroke: #ff0000;
            fill: #ff0000;
        }

        g.connection rect.midpoint {
            stroke: #ffcc00;
            fill: #ffcc00;
        }

        g.connection rect.endpoint {
            stroke: #0000ff;
            fill: #0000ff;
        }

        /* labels */

        g.label path.resizable-triangle {
            fill: rgba($material-theme-neutral-palette-darker, 0.2);
            stroke: rgba($material-theme-neutral-palette-darker, 0.2);
        }

        /* funnels */

        text.funnel-icon {
            fill: $material-theme-tertiary-palette-default;
        }

        /* ports */

        text.port-name {
            @extend .neutral-contrast;
        }

        text.port-icon {
            fill: $material-theme-tertiary-palette-default;
        }

        /* process groups */

        rect.process-group-stats-in-out {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        rect.process-group-stats-border {
            fill: $border-color;
        }

        rect.process-group-banner,
        rect.remote-process-group-banner {
            fill: $material-theme-secondary-palette-default;
        }

        text.version-control,
        text.not-transmitting,
        text.transmitting,
        text.process-group-transmitting,
        text.invalid,
        text.running,
        text.stopped,
        text.process-group-running,
        text.process-group-stopped {
            text-shadow: if($is-material-dark, 0 0 4px rgba(0, 0, 0, 1), 0 0 4px rgba(255, 255, 255, 1));
        }

        text.process-group-contents-count {
            fill: $material-theme-tertiary-palette-default;
            font-family: mat.get-theme-typography($material-theme, body-medium, font-family);
        }

        g.process-group.drop rect.border {
            stroke: #0000ff;
        }

        /* remote process group */

        rect.remote-process-group-stats-border {
            fill: $border-color;
        }

        rect.remote-process-group-received-stats {
            fill: if(
                $is-material-dark,
                $material-theme-neutral-palette-darker,
                $material-theme-neutral-palette-lighter
            );
        }

        text.remote-process-group-uri {
            fill: $material-theme-primary-palette-default;
        }

        text.remote-process-group-transmission-secure {
            fill: $material-theme-primary-palette-default;
        }

        text.remote-process-group-last-refresh {
            fill: $material-theme-primary-palette-default;
        }
    }
}
