import { Component, inject, input, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { PosCartService } from '../../services/pos-cart.service';

@Component({
  selector: 'app-numpad',
  standalone: true,
  imports: [CommonModule, TranslateModule],
  templateUrl: './numpad.component.html',
  styleUrl: './numpad.component.scss',
})
export class NumpadComponent {
  private cartService = inject(PosCartService);

  forceExpanded = input(false);
  showKeyboard = input(false);
  cashierMode = input(false);
  inputBuffer = signal('');
  mode = signal<'qty' | 'price' | 'discount' | 'tax'>('qty');
  expanded = signal(false);

  // Arabic keyboard rows
  readonly arabicRow1 = ['ض', 'ص', 'ث', 'ق', 'ف', 'غ', 'ع', 'ه', 'خ'];
  readonly arabicRow2 = ['ش', 'س', 'ي', 'ب', 'ل', 'ا', 'ت', 'ن', 'م'];
  readonly arabicRow3 = ['و', 'ر', 'ز', 'د', 'ذ'];

  pressAlpha(char: string): void {
    this.inputBuffer.update((v) => v + char);
  }

  pressSpace(): void {
    this.inputBuffer.update((v) => v + ' ');
  }

  pressKey(key: string): void {
    // If an external input (e.g. edit-bar) is focused, type into it
    if (this.typeIntoFocusedInput(key)) return;

    const current = this.inputBuffer();
    if (key === '.' && current.includes('.')) return;
    this.inputBuffer.set(current + key);
  }

  pressBackspace(): void {
    // If an external input is focused, backspace there
    const el = this.getFocusedExternalInput();
    if (el) {
      const val = el.value;
      el.value = val.slice(0, -1);
      el.dispatchEvent(new Event('change', { bubbles: true }));
      return;
    }

    const current = this.inputBuffer();
    this.inputBuffer.set(current.slice(0, -1));
  }

  pressClear(): void {
    const el = this.getFocusedExternalInput();
    if (el) {
      el.value = '';
      el.dispatchEvent(new Event('change', { bubbles: true }));
      return;
    }
    this.inputBuffer.set('');
  }

  pressEnter(): void {
    // If an external input is focused, trigger change and blur
    const el = this.getFocusedExternalInput();
    if (el) {
      el.dispatchEvent(new Event('change', { bubbles: true }));
      el.blur();
      return;
    }

    const value = parseFloat(this.inputBuffer());
    if (isNaN(value)) return;

    const index = this.cartService.selectedItemIndex();
    if (index === null) return;

    switch (this.mode()) {
      case 'qty':
        this.cartService.updateQuantity(index, value);
        break;
      case 'price':
        this.cartService.setPrice(index, value);
        break;
      case 'discount':
        this.cartService.setLineDiscount(index, value);
        break;
      case 'tax':
        this.cartService.setLineTax(index, value);
        break;
    }

    this.inputBuffer.set('');
  }

  /** Check if an external input (edit-bar, etc.) is focused and type into it */
  private typeIntoFocusedInput(key: string): boolean {
    const el = this.getFocusedExternalInput();
    if (!el) return false;
    if (key === '.' && el.value.includes('.')) return true; // prevent double dot
    el.value = el.value + key;
    el.dispatchEvent(new Event('change', { bubbles: true }));
    return true;
  }

  /** Get focused input element if it's outside the numpad */
  private getFocusedExternalInput(): HTMLInputElement | null {
    const active = document.activeElement as HTMLElement;
    if (!active || active.tagName !== 'INPUT') return null;
    // Check it's not inside the numpad itself
    const numpad = active.closest('app-numpad');
    if (numpad) return null;
    return active as HTMLInputElement;
  }

  setMode(mode: 'qty' | 'price' | 'discount' | 'tax'): void {
    this.mode.set(mode);
    this.inputBuffer.set('');
  }

  pressPlus(): void {
    const index = this.cartService.selectedItemIndex();
    if (index === null) return;
    const items = this.cartService.items();
    if (index >= 0 && index < items.length) {
      this.cartService.updateQuantity(index, items[index].qty + 1);
    }
  }

  pressMinus(): void {
    const index = this.cartService.selectedItemIndex();
    if (index === null) return;
    const items = this.cartService.items();
    if (index >= 0 && index < items.length) {
      this.cartService.updateQuantity(index, items[index].qty - 1);
    }
  }
}
