import * as colors from '../../00colors.js';
import { DeesInputBase } from '../dees-input-base/dees-input-base.js';
import { demoFunc } from './dees-input-text.demo.js';
import { cssGeistFontFamily, cssMonoFontFamily } from '../../00fonts.js';

import {
  customElement,
  type TemplateResult,
  property,
  html,
  cssManager,
  css,
} from '@design.estate/dees-element';
import { themeDefaultStyles } from '../../00theme.js';

declare global {
  interface HTMLElementTagNameMap {
    'dees-input-text': DeesInputText;
  }
}

@customElement('dees-input-text')
export class DeesInputText extends DeesInputBase {
  public static demo = demoFunc;
  public static demoGroup = 'Input';

  // INSTANCE
  @property({
    type: String,
    reflect: true,
  })
  accessor value: string = '';

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

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

  @property({
    type: Boolean,
    reflect: true,
  })
  accessor validationState: 'valid' | 'warn' | 'invalid';

  @property({
    reflect: true,
  })
  accessor validationText: string = '';

  @property({})
  accessor validationFunction: (value: string) => boolean;

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

      :host {
        position: relative;
        z-index: auto;
        font-family: ${cssGeistFontFamily};
      }

      .maincontainer {
        position: relative;
        color: ${cssManager.bdTheme('hsl(0 0% 15%)', 'hsl(0 0% 90%)')};
      }

      input {
        display: flex;
        height: 40px;
        width: 100%;
        padding: 0 12px;
        font-size: 14px;
        line-height: 40px;
        background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(0 0% 9%)')};
        border: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        border-radius: 6px;
        transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
        outline: none;
        cursor: text;
        font-family: inherit;
        color: ${cssManager.bdTheme('hsl(0 0% 3.9%)', 'hsl(0 0% 98%)')};
      }

      input::placeholder {
        color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
      }

      input:hover:not(:disabled):not(:focus) {
        border-color: ${cssManager.bdTheme('hsl(0 0% 79.8%)', 'hsl(0 0% 20.9%)')};
      }

      input:focus {
        outline: none;
        border-color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 98%)')};
        box-shadow: 0 0 0 2px ${cssManager.bdTheme('hsl(0 0% 9% / 0.05)', 'hsl(0 0% 98% / 0.05)')};
      }

      input:disabled {
        background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')};
        border-color: ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
        cursor: not-allowed;
        opacity: 0.5;
      }

      /* Password toggle button */
      .showPassword {
        position: absolute;
        right: 1px;
        top: 50%;
        transform: translateY(-50%);
        display: flex;
        align-items: center;
        justify-content: center;
        width: 38px;
        height: 38px;
        cursor: pointer;
        color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
        transition: all 0.15s ease;
        border-radius: 0 5px 5px 0;
      }

      .showPassword:hover {
        background: ${cssManager.bdTheme('hsl(0 0% 95.1%)', 'hsl(0 0% 14.9%)')};
        color: ${cssManager.bdTheme('hsl(0 0% 15%)', 'hsl(0 0% 93.9%)')};
      }

      /* Validation styles */
      .validationContainer {
        margin-top: 4px;
        padding: 4px 8px;
        font-size: 12px;
        font-weight: 500;
        border-radius: 4px;
        transition: all 0.2s ease;
        overflow: hidden;
      }

      .validationContainer.error {
        background: ${cssManager.bdTheme('hsl(0 84.2% 60.2% / 0.1)', 'hsl(0 72.2% 50.6% / 0.1)')};
        color: ${cssManager.bdTheme('hsl(0 84.2% 60.2%)', 'hsl(0 72.2% 50.6%)')};
      }

      .validationContainer.warn {
        background: ${cssManager.bdTheme('hsl(25 95% 53% / 0.1)', 'hsl(25 95% 63% / 0.1)')};
        color: ${cssManager.bdTheme('hsl(25 95% 53%)', 'hsl(25 95% 63%)')};
      }

      .validationContainer.valid {
        background: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3% / 0.1)', 'hsl(142.1 70.6% 45.3% / 0.1)')};
        color: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')};
      }

      /* Error state for input */
      :host([validation-state="invalid"]) input {
        border-color: ${cssManager.bdTheme('hsl(0 84.2% 60.2%)', 'hsl(0 72.2% 50.6%)')};
      }

      :host([validation-state="invalid"]) input:focus {
        border-color: ${cssManager.bdTheme('hsl(0 84.2% 60.2%)', 'hsl(0 72.2% 50.6%)')};
        box-shadow: 0 0 0 2px ${cssManager.bdTheme('hsl(0 84.2% 60.2% / 0.05)', 'hsl(0 72.2% 50.6% / 0.05)')};
      }

      /* Warning state for input */
      :host([validation-state="warn"]) input {
        border-color: ${cssManager.bdTheme('hsl(25 95% 53%)', 'hsl(25 95% 63%)')};
      }

      :host([validation-state="warn"]) input:focus {
        border-color: ${cssManager.bdTheme('hsl(25 95% 53%)', 'hsl(25 95% 63%)')};
        box-shadow: 0 0 0 2px ${cssManager.bdTheme('hsl(25 95% 53% / 0.05)', 'hsl(25 95% 63% / 0.05)')};
      }

      /* Valid state for input */
      :host([validation-state="valid"]) input {
        border-color: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')};
      }

      :host([validation-state="valid"]) input:focus {
        border-color: ${cssManager.bdTheme('hsl(142.1 76.2% 36.3%)', 'hsl(142.1 70.6% 45.3%)')};
        box-shadow: 0 0 0 2px ${cssManager.bdTheme('hsl(142.1 76.2% 36.3% / 0.05)', 'hsl(142.1 70.6% 45.3% / 0.05)')};
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <style>
        input {
          font-family: ${this.isPasswordBool ? cssMonoFontFamily : 'inherit'};
          letter-spacing: ${this.isPasswordBool ? '0.5px' : 'normal'};
          padding-right: ${this.isPasswordBool ? '48px' : '12px'};
        }
        ${this.validationText
          ? css`
              .validationContainer {
                height: auto;
                opacity: 1;
                transform: translateY(0);
              }
            `
          : css`
              .validationContainer {
                height: 0;
                padding: 0 !important;
                opacity: 0;
                transform: translateY(-4px);
              }
            `}
      </style>
      <div class="input-wrapper">
        <dees-label .label=${this.label} .description=${this.description} .required=${this.required}></dees-label>
        <div class="maincontainer">
          <input
            type="${this.isPasswordBool && !this.showPasswordBool ? 'password' : 'text'}"
            .value=${this.value}
            @input="${this.updateValue}"
            .disabled=${this.disabled}
            placeholder="${this.label ? '' : 'Enter text...'}"
          />
          ${this.isPasswordBool
            ? html`
                <div class="showPassword" @click=${this.togglePasswordView}>
                  <dees-icon .icon=${this.showPasswordBool ? 'lucide:Eye' : 'lucide:EyeOff'}></dees-icon>
                </div>
              `
            : html``}
          ${this.validationText
            ? html`
                <div class="validationContainer ${this.validationState || 'error'}">
                  ${this.validationText}
                </div>
              `
            : html`<div class="validationContainer"></div>`}
        </div>
      </div>
    `;
  }

  firstUpdated() {
    // Input event handling is already done in updateValue method
  }

  public async updateValue(eventArg: Event) {
    const target: any = eventArg.target;
    this.value = target.value;
    this.changeSubject.next(this);
  }

  public getValue(): string {
    return this.value;
  }

  public setValue(value: string): void {
    this.value = value;
  }

  public async togglePasswordView() {
    this.showPasswordBool = !this.showPasswordBool;
  }

  public async focus() {
    const textInput = this.shadowRoot.querySelector('input');
    textInput.focus();
  }

  public async blur() {
    const textInput = this.shadowRoot.querySelector('input');
    textInput.blur();
  }
}
