import {
  customElement,
  html,
  DeesElement,
  property,
  type TemplateResult,
  cssManager,
  css,
  type CSSResult,
  unsafeCSS,
} from '@design.estate/dees-element';

import * as domtools from '@design.estate/dees-domtools';
import { demoFunc } from './dees-chips.demo.js';
import { themeDefaultStyles } from '../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-chips': DeesChips;
  }
}

type Tag = { key: string; value: string };

@customElement('dees-chips')
export class DeesChips extends DeesElement {
  public static demo = demoFunc;

  @property()
  accessor selectionMode: 'none' | 'single' | 'multiple' = 'single';

  @property({
    type: Boolean,
  })
  accessor chipsAreRemovable: boolean = false;

  @property({
    type: Array,
  })
  accessor selectableChips: Tag[] = [];

  @property()
  accessor selectedChip: Tag = null;

  @property({
    type: Array,
  })
  accessor selectedChips: Tag[] = [];

  constructor() {
    super();
  }

  public static styles = [
    themeDefaultStyles,
    cssManager.defaultStyles,
    css`
      /* TODO: Migrate hardcoded values to --dees-* CSS variables */
      :host {
        display: block;
        box-sizing: border-box;
      }

      .mainbox {
        user-select: none;
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
      }

      .chip {
        background: ${cssManager.bdTheme('#f4f4f5', '#27272a')};
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#3f3f46')};
        display: inline-flex;
        align-items: center;
        height: 32px;
        padding: 0px 12px;
        font-size: 14px;
        font-weight: 500;
        color: ${cssManager.bdTheme('#09090b', '#fafafa')};
        border-radius: 6px;
        position: relative;
        cursor: pointer;
        transition: all 0.15s ease;
        box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
      }

      .chip:hover {
        background: ${cssManager.bdTheme('#e5e7eb', '#3f3f46')};
        border-color: ${cssManager.bdTheme('#d1d5db', '#52525b')};
      }

      .chip:active {
        transform: scale(0.98);
      }

      .chip.selected {
        background: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
        border-color: ${cssManager.bdTheme('#3b82f6', '#3b82f6')};
        color: #ffffff;
      }

      .chip.selected:hover {
        background: ${cssManager.bdTheme('#2563eb', '#2563eb')};
        border-color: ${cssManager.bdTheme('#2563eb', '#2563eb')};
      }

      .chipKey {
        background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.06)', 'rgba(255, 255, 255, 0.1)')};
        height: 20px;
        line-height: 20px;
        display: inline-flex;
        align-items: center;
        margin-left: -8px;
        padding: 0px 8px;
        margin-right: 8px;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 600;
        color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
      }

      .chip.selected .chipKey {
        background: rgba(255, 255, 255, 0.2);
        color: rgba(255, 255, 255, 0.9);
      }

      dees-icon {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 16px;
        height: 16px;
        margin-left: 8px;
        margin-right: -6px;
        border-radius: 3px;
        transition: all 0.15s ease;
        color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};
      }

      .chip.selected dees-icon {
        color: rgba(255, 255, 255, 0.8);
      }

      dees-icon:hover {
        background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
        color: ${cssManager.bdTheme('#ef4444', '#ef4444')};
      }

      .chip.selected dees-icon:hover {
        background: rgba(255, 255, 255, 0.2);
        color: #ffffff;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <div class="mainbox">
        ${this.selectableChips.map(
          (chip) => html`
            <div
              @click=${() => this.selectChip(chip)}
              class="chip ${this.isSelected(chip) ? 'selected' : ''}"
            >
              ${chip.key ? html`<div class="chipKey">${chip.key}</div>` : html``} ${chip.value}
              ${this.chipsAreRemovable
                ? html`
                    <dees-icon
                      @click=${(event: Event) => {
                        event.stopPropagation(); // prevent the selectChip event from being triggered
                        this.removeChip(chip);
                      }}
                      .icon=${'fa:xmark'}
                    ></dees-icon>
                  `
                : html``}
            </div>
          `
        )}
      </div>
    `;
  }

  public async firstUpdated() {
    // Component initialized
  }

  private isSelected(chip: Tag): boolean {
    if (this.selectionMode === 'single') {
      return this.selectedChip ? this.isSameChip(this.selectedChip, chip) : false;
    } else {
      return this.selectedChips.some((selected) => this.isSameChip(selected, chip));
    }
  }
  
  private isSameChip(chip1: Tag, chip2: Tag): boolean {
    // If both have keys, compare by key
    if (chip1.key && chip2.key) {
      return chip1.key === chip2.key;
    }
    // Otherwise compare by value (and key if present)
    return chip1.value === chip2.value && chip1.key === chip2.key;
  }

  public async selectChip(chip: Tag) {
    if (this.selectionMode === 'none') {
      return;
    }

    if (this.selectionMode === 'single') {
      if (this.isSelected(chip)) {
        this.selectedChip = null;
        this.selectedChips = [];
      } else {
        this.selectedChip = chip;
        this.selectedChips = [chip];
      }
    } else if (this.selectionMode === 'multiple') {
      if (this.isSelected(chip)) {
        this.selectedChips = this.selectedChips.filter((selected) => !this.isSameChip(selected, chip));
      } else {
        this.selectedChips = [...this.selectedChips, chip];
      }
      this.requestUpdate();
    }
    console.log(this.selectedChips);
  }

  public removeChip(chipToRemove: Tag): void {
    // Remove the chip from selectableChips
    this.selectableChips = this.selectableChips.filter((chip) => !this.isSameChip(chip, chipToRemove));

    // Remove the chip from selectedChips if present
    this.selectedChips = this.selectedChips.filter((chip) => !this.isSameChip(chip, chipToRemove));

    // If the removed chip was the selectedChip, set selectedChip to null
    if (this.selectedChip && this.isSameChip(this.selectedChip, chipToRemove)) {
      this.selectedChip = null;
    }

    // Trigger an update to re-render the component
    this.requestUpdate();
  }
}
