import {
  DeesElement,
  html,
  property,
  customElement,
  css,
  type TemplateResult,
} from '@design.estate/dees-element';
import { idpElementStyles } from './tokens.js';
import './idp-icon.js';

export type TIdpButtonVariant = 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'accent';
export type TIdpButtonSize = 'sm' | 'md' | 'lg';

declare global {
  interface HTMLElementTagNameMap {
    'idp-button': IdpButton;
  }
}

@customElement('idp-button')
export class IdpButton extends DeesElement {
  public static demo = () => html`
    <div style="display: flex; gap: 10px; flex-wrap: wrap;">
      <idp-button>Default</idp-button>
      <idp-button variant="accent">Approve</idp-button>
      <idp-button variant="outline">Deny</idp-button>
      <idp-button variant="ghost">Ghost</idp-button>
      <idp-button variant="destructive">Delete</idp-button>
    </div>
  `;
  public static demoGroups = ['idp.global v3 primitives'];

  @property({ type: String })
  public accessor variant: TIdpButtonVariant = 'default';

  @property({ type: String })
  public accessor size: TIdpButtonSize = 'md';

  @property({ type: String })
  public accessor icon = '';

  @property({ type: String })
  public accessor type: 'button' | 'submit' | 'reset' = 'button';

  @property({ type: Boolean, reflect: true })
  public accessor disabled = false;

  @property({ type: Boolean, reflect: true })
  public accessor loading = false;

  public static styles = [
    ...idpElementStyles,
    css`
      :host {
        display: inline-block;
      }
      :host([disabled]) {
        pointer-events: none;
      }
      button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        border: 1px solid transparent;
        border-radius: 6px;
        font-family: var(--idp-font);
        font-weight: 500;
        letter-spacing: -0.01em;
        white-space: nowrap;
        cursor: pointer;
        transition: background 120ms ease, color 120ms ease, border-color 120ms ease, transform 80ms ease;
      }
      button:active:not(:disabled) {
        transform: translateY(1px);
      }
      button:focus-visible {
        outline: 2px solid color-mix(in srgb, var(--idp-accent), transparent 68%);
        outline-offset: 2px;
      }
      button:disabled {
        opacity: 0.5;
        cursor: not-allowed;
      }
      .sm {
        height: 32px;
        padding: 0 12px;
        font-size: 13px;
      }
      .md {
        height: 38px;
        padding: 0 14px;
        font-size: 14px;
      }
      .lg {
        height: 44px;
        padding: 0 18px;
        font-size: 15px;
      }
      .default {
        background: var(--idp-primary);
        color: var(--idp-primary-fg);
      }
      .default:hover:not(:disabled) {
        opacity: 0.88;
      }
      .accent {
        background: var(--idp-accent);
        color: var(--idp-accent-fg);
        box-shadow: 0 4px 14px color-mix(in srgb, var(--idp-accent), transparent 64%);
      }
      .accent:hover:not(:disabled) {
        background: var(--idp-accent-hover);
      }
      .secondary {
        background: var(--idp-muted);
        color: var(--idp-fg);
        border-color: var(--idp-border);
      }
      .outline {
        background: transparent;
        color: var(--idp-fg);
        border-color: var(--idp-border);
      }
      .outline:hover:not(:disabled), .secondary:hover:not(:disabled), .ghost:hover:not(:disabled) {
        background: var(--idp-muted);
      }
      .ghost {
        background: transparent;
        color: var(--idp-fg);
      }
      .destructive {
        background: var(--idp-destructive);
        color: var(--idp-accent-fg);
      }
      idp-icon {
        flex: 0 0 auto;
      }
      .spinner {
        width: 13px;
        height: 13px;
        border: 2px solid currentColor;
        border-right-color: transparent;
        border-radius: 999px;
        animation: spin 700ms linear infinite;
      }
      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <button class="${this.variant} ${this.size}" type=${this.type} ?disabled=${this.disabled || this.loading} part="button">
        ${this.loading
          ? html`<span class="spinner" aria-hidden="true"></span>`
          : this.icon ? html`<idp-icon name=${this.icon as any} size="14"></idp-icon>` : html``}
        <slot></slot>
      </button>
    `;
  }
}
