/*
 * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
 * Ministerpräsidenten des Landes Schleswig-Holstein
 * Staatskanzlei
 * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
 *
 * Lizenziert unter der EUPL, Version 1.2 oder - sobald
 * diese von der Europäischen Kommission genehmigt wurden -
 * Folgeversionen der EUPL ("Lizenz");
 * Sie dürfen dieses Werk ausschließlich gemäß
 * dieser Lizenz nutzen.
 * Eine Kopie der Lizenz finden Sie hier:
 *
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 *
 * Sofern nicht durch anwendbare Rechtsvorschriften
 * gefordert oder in schriftlicher Form vereinbart, wird
 * die unter der Lizenz verbreitete Software "so wie sie
 * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
 * ausdrücklich oder stillschweigend - verbreitet.
 * Die sprachspezifischen Genehmigungen und Beschränkungen
 * unter der Lizenz sind dem Lizenztext zu entnehmen.
 */
import { CommonModule } from '@angular/common';
import { booleanAttribute, Component, EventEmitter, Input, Output } from '@angular/core';
import { cva, VariantProps } from 'class-variance-authority';

import { IconVariants } from '../icons/iconVariants';
import { SpinnerIconComponent } from '../icons/spinner-icon/spinner-icon.component';

export const buttonVariants = cva(
  [
    'flex items-center gap-4 rounded-lg text-sm font-medium box-border',
    'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
  ],
  {
    variants: {
      variant: {
        primary: 'bg-primary text-whitetext shadow-md hover:enabled:bg-primary-hover',
        outline:
          'border border-primary bg-background-50 text-primary shadow-md hover:enabled:bg-ghost-hover focus-visible:border-background-200',
        ghost:
          'border-2 border-transparent hover:enabled:bg-ghost-hover text-primary focus-visible:border-background-200 font-semibold',
      },
      size: {
        medium: 'h-9 py-2 px-4 min-w-32',
        fit: 'h-fit p-2',
      },
      disabled: {
        false: null,
        true: ['opacity-70', 'cursor-not-allowed'],
      },
      destructive: {
        false: 'outline-focus',
        true: 'outline-destructive',
      },
    },
    defaultVariants: {
      variant: 'primary',
      size: 'medium',
      disabled: false,
    },
    compoundVariants: [
      {
        variant: 'primary',
        destructive: true,
        class: '[&]:hover:enabled:bg-destructive-primary-hover [&]:bg-destructive [&]:outline-destructive',
      },
      {
        variant: 'outline',
        destructive: true,
        class: '[&]:border-destructive [&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
      },
      {
        variant: 'ghost',
        destructive: true,
        class: '[&]:text-destructive [&]:hover:enabled:bg-destructive-hover',
      },
    ],
  },
);
type ButtonVariants = VariantProps<typeof buttonVariants>;

@Component({
  selector: 'ods-button',
  standalone: true,
  imports: [CommonModule, SpinnerIconComponent],
  template: `<button
    type="button"
    [ngClass]="buttonVariants({ size, variant, disabled, destructive })"
    [disabled]="isDisabled"
    [attr.aria-disabled]="isDisabled"
    [attr.aria-label]="text"
    [attr.data-test-id]="dataTestId"
    (click)="clickEmitter.emit()"
  >
    <ng-content *ngIf="!isLoading" select="[icon]"></ng-content>
    <ods-spinner-icon *ngIf="isLoading" [size]="spinnerSize"></ods-spinner-icon>
    <div *ngIf="text" class="flex-grow">{{ text }}</div>
  </button>`,
})
export class ButtonComponent {
  @Input() text: string = '';
  @Input() dataTestId: string = '';
  @Input() disabled: boolean = false;
  @Input() isLoading: boolean = false;
  @Input({ transform: booleanAttribute }) destructive: boolean = false;
  @Input() variant: ButtonVariants['variant'];
  @Input() size: ButtonVariants['size'];
  @Input() spinnerSize: IconVariants['size'] = 'medium';

  @Output() public clickEmitter: EventEmitter<MouseEvent> = new EventEmitter<MouseEvent>();

  get isDisabled() {
    return this.disabled || this.isLoading;
  }

  readonly buttonVariants = buttonVariants;
}