import {
  Component,
  computed,
  inject,
  input,
  output,
  signal,
  OnInit,
  OnDestroy,
  ElementRef,
  viewChild,
  AfterViewInit,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { InputTextModule } from 'primeng/inputtext';
import { PopoverModule } from 'primeng/popover';
import { Subject, debounceTime, distinctUntilChanged, switchMap, takeUntil, of } from 'rxjs';
import { PosProductService } from '../../services/pos-product.service';
import { PosCartService } from '../../services/pos-cart.service';
import { LanguageService } from '../../../../core/services/language.service';
import { PosSession, PosProduct, ConnectionStatus } from '../../models/pos.model';

@Component({
  selector: 'app-pos-header',
  standalone: true,
  imports: [CommonModule, FormsModule, TranslateModule, InputTextModule, PopoverModule],
  templateUrl: './pos-header.component.html',
  styleUrl: './pos-header.component.scss',
  host: {
    '[class.retail-header]': 'isRetail()',
    '[class.cashier-header]': 'isCashier()',
  },
})
export class PosHeaderComponent implements OnInit, OnDestroy, AfterViewInit {
  private productService = inject(PosProductService);
  private cartService = inject(PosCartService);
  private router = inject(Router);
  private translate = inject(TranslateService);
  langService = inject(LanguageService);

  // Inputs
  session = input<PosSession | null>(null);
  connectionStatus = input<ConnectionStatus>('online');
  pendingCount = input<number>(0);
  posLayout = input<'modern' | 'classic' | 'retail' | 'cashier'>('modern');
  cashierMode = input(false);
  keyboardEnabled = input(false);
  keyboardVisible = input(false);
  isRetail = computed(() => this.posLayout() === 'retail');
  isCashier = computed(() => this.cashierMode());

  isSyncing = input(false);

  // Outputs
  productSelected = output<PosProduct>();
  exitRequested = output<void>();
  layoutToggled = output<void>();
  keyboardToggled = output<void>();
  keyboardSettingToggled = output<void>();
  syncRequested = output<void>();

  // === Barcode field (cashier mode) ===
  barcodeValue = signal('');
  barcodeInput = viewChild<ElementRef>('barcodeInput');

  // === Search overlay (cashier mode) ===
  showSearchOverlay = signal(false);
  highlightedIndex = signal(-1);
  searchOverlayInput = viewChild<ElementRef>('searchOverlayInput');

  // === Default search (non-cashier) ===
  searchQuery = signal('');
  searchResults = signal<PosProduct[]>([]);
  showResults = signal(false);
  searchInput = viewChild<ElementRef>('searchInput');

  private searchSubject = new Subject<string>();
  private destroy$ = new Subject<void>();

  ngOnInit(): void {
    this.searchSubject
      .pipe(
        debounceTime(300),
        distinctUntilChanged(),
        switchMap((query) => {
          if (!query || query.trim().length < 2) {
            return of([]);
          }
          return this.productService.searchProducts(query.trim());
        }),
        takeUntil(this.destroy$)
      )
      .subscribe((results) => {
        this.searchResults.set(results);
        this.highlightedIndex.set(results.length > 0 ? 0 : -1);
        // Only show dropdown in non-cashier mode or search overlay
        if (!this.cashierMode()) {
          this.showResults.set(results.length > 0);
        }
      });
  }

  ngAfterViewInit(): void {
    // Auto-focus barcode input in cashier mode
    if (this.cashierMode()) {
      setTimeout(() => this.focusBarcode(), 200);
    }
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  // ─── Barcode field (cashier mode) ───

  onBarcodeInput(event: Event): void {
    this.barcodeValue.set((event.target as HTMLInputElement).value);
  }

  onBarcodeScan(event: Event): void {
    event.preventDefault();
    const value = this.barcodeValue().trim();
    if (!value) return;

    // Try exact barcode match first
    this.productService.getByBarcode(value).subscribe({
      next: (product) => {
        if (product) {
          this.cartService.addProduct(product);
          this.clearBarcode();
        } else {
          // Fallback: search and auto-add if single result
          this.productService.searchProducts(value).subscribe({
            next: (results) => {
              if (results.length === 1) {
                this.cartService.addProduct(results[0]);
                this.clearBarcode();
              } else if (results.length > 1) {
                // Multiple results → open search overlay with results
                this.searchQuery.set(value);
                this.searchResults.set(results);
                this.highlightedIndex.set(0);
                this.showSearchOverlay.set(true);
                setTimeout(() => {
                  const el = this.searchOverlayInput()?.nativeElement;
                  if (el) {
                    el.value = value;
                    el.focus();
                  }
                }, 50);
              }
              // No results → just clear and refocus
              if (results.length === 0) {
                this.clearBarcode();
              }
            },
          });
        }
      },
    });
  }

  clearBarcode(): void {
    this.barcodeValue.set('');
    this.focusBarcode();
  }

  focusBarcode(): void {
    const el = this.barcodeInput()?.nativeElement;
    if (el) {
      el.value = '';
      el.focus();
    }
  }

  // ─── Search overlay (cashier mode) ───

  toggleSearchOverlay(): void {
    if (this.showSearchOverlay()) {
      this.closeSearchOverlay();
    } else {
      this.showSearchOverlay.set(true);
      this.searchQuery.set('');
      this.searchResults.set([]);
      this.highlightedIndex.set(-1);
      // Show on-screen keyboard with search
      if (this.keyboardEnabled() && !this.keyboardVisible()) {
        this.keyboardToggled.emit();
      }
      setTimeout(() => {
        this.searchOverlayInput()?.nativeElement?.focus();
      }, 50);
    }
  }

  closeSearchOverlay(): void {
    this.showSearchOverlay.set(false);
    this.searchQuery.set('');
    this.searchResults.set([]);
    this.highlightedIndex.set(-1);
    // Hide on-screen keyboard
    if (this.keyboardVisible()) {
      this.keyboardToggled.emit();
    }
    // Return focus to barcode
    setTimeout(() => this.focusBarcode(), 50);
  }

  onSearchEnter(event: Event): void {
    event.preventDefault();
    const results = this.searchResults();
    const idx = this.highlightedIndex();
    if (results.length > 0 && idx >= 0 && idx < results.length) {
      this.selectProduct(results[idx]);
    }
  }

  // ─── Common search logic ───

  onSearch(event: Event): void {
    const value = (event.target as HTMLInputElement).value;
    this.searchQuery.set(value);
    this.searchSubject.next(value);
  }

  onBarcodeEnter(event: Event): void {
    event.preventDefault();
    const value = this.searchQuery().trim();
    if (!value) return;

    this.productService.getByBarcode(value).subscribe({
      next: (product) => {
        if (product) {
          this.cartService.addProduct(product);
          this.clearSearch();
        } else {
          this.productService.searchProducts(value).subscribe({
            next: (results) => {
              if (results.length === 1) {
                this.cartService.addProduct(results[0]);
                this.clearSearch();
              } else if (results.length > 1) {
                this.searchResults.set(results);
                this.showResults.set(true);
              }
            },
          });
        }
      },
    });
  }

  selectProduct(product: PosProduct): void {
    this.productSelected.emit(product);
    if (this.cashierMode()) {
      this.closeSearchOverlay();
    } else {
      this.clearSearch();
    }
  }

  clearSearch(): void {
    this.searchQuery.set('');
    this.searchResults.set([]);
    this.showResults.set(false);
  }

  onClickOutside(): void {
    this.showResults.set(false);
  }
}
