import { Component, inject, input, output, signal, computed, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { PosCartService } from '../../services/pos-cart.service';
import { environment } from '../../../../../environments/environment';
import { Subject, debounceTime, switchMap, of } from 'rxjs';

@Component({
  selector: 'app-invoice-table',
  standalone: true,
  imports: [CommonModule, FormsModule, TranslateModule],
  templateUrl: './invoice-table.component.html',
  styleUrl: './invoice-table.component.scss',
})
export class InvoiceTableComponent implements OnInit {
  readonly cartService = inject(PosCartService);
  private http = inject(HttpClient);
  private translate = inject(TranslateService);

  currencySymbol = input('');

  paymentRequested = output<void>();
  holdOrder = output<void>();
  showHeldOrders = output<void>();
  showCoupon = output<void>();
  closeSession = output<void>();
  showReturn = output<void>();
  keyboardRequested = output<boolean>();

  readonly WALK_IN_ID = 5;
  selectedCustomer = signal<any>(null);

  // Customer search overlay
  showCustomerSearch = signal(false);
  customerQuery = signal('');
  customerResults = signal<any[]>([]);
  customerSearching = signal(false);
  private searchSubject = new Subject<string>();

  // New customer form
  showNewCustomerForm = signal(false);
  newCustomerName = signal('');
  newCustomerPhone = signal('');
  savingCustomer = signal(false);

  // Invoice number (auto-increment mock)
  invoiceNumber = signal(Math.floor(1000 + Math.random() * 9000));

  // Selected item for edit bar
  readonly selectedItem = computed(() => {
    const idx = this.cartService.selectedItemIndex();
    if (idx === null) return null;
    return this.cartService.items()[idx] ?? null;
  });

  ngOnInit(): void {
    this.cartService.setCustomer(this.WALK_IN_ID, this.translate.instant('POS.WALK_IN'));
    this.selectedCustomer.set({
      id: this.WALK_IN_ID,
      name: this.translate.instant('POS.WALK_IN'),
    });

    // Debounced customer search
    this.searchSubject.pipe(
      debounceTime(300),
      switchMap((query) => {
        if (!query || query.length < 2) {
          this.customerResults.set([]);
          this.customerSearching.set(false);
          return of(null);
        }
        this.customerSearching.set(true);
        return this.http.get<any>(`${environment.apiUrl}/core/partners`, {
          params: { search: query, partner_type: 'customer' },
        });
      })
    ).subscribe({
      next: (res) => {
        if (res) {
          this.customerResults.set(res.data || []);
        }
        this.customerSearching.set(false);
      },
      error: () => this.customerSearching.set(false),
    });
  }

  openCustomerSearch(): void {
    this.showCustomerSearch.set(true);
    this.customerQuery.set('');
    this.customerResults.set([]);
    this.showNewCustomerForm.set(false);
    this.keyboardRequested.emit(true);
    setTimeout(() => {
      const el = document.querySelector('.cust-search-input') as HTMLInputElement;
      el?.focus();
    }, 100);
  }

  closeCustomerSearch(hideKeyboard = true): void {
    this.showCustomerSearch.set(false);
    this.showNewCustomerForm.set(false);
    if (hideKeyboard) {
      this.keyboardRequested.emit(false);
    }
  }

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

  selectCustomer(customer: any): void {
    this.selectedCustomer.set(customer);
    this.cartService.setCustomer(customer.id, customer.name);
    this.closeCustomerSearch(true);
  }

  resetToWalkIn(): void {
    this.cartService.setCustomer(this.WALK_IN_ID, this.translate.instant('POS.WALK_IN'));
    this.selectedCustomer.set({
      id: this.WALK_IN_ID,
      name: this.translate.instant('POS.WALK_IN'),
    });
  }

  openNewCustomerForm(): void {
    this.showNewCustomerForm.set(true);
    this.newCustomerName.set(this.customerQuery());
    this.newCustomerPhone.set('');
  }

  saveNewCustomer(): void {
    const name = this.newCustomerName().trim();
    if (!name) return;

    this.savingCustomer.set(true);
    this.http.post<any>(`${environment.apiUrl}/core/partners`, {
      name,
      phone: this.newCustomerPhone() || null,
      partner_type: 'customer',
    }).subscribe({
      next: (res) => {
        this.savingCustomer.set(false);
        const customer = res.data;
        this.selectCustomer(customer);
      },
      error: () => {
        this.savingCustomer.set(false);
      },
    });
  }

  onIncrement(index: number): void {
    const item = this.cartService.items()[index];
    if (item) {
      this.cartService.updateQuantity(index, item.qty + 1);
    }
  }

  onDecrement(index: number): void {
    const item = this.cartService.items()[index];
    if (item) {
      this.cartService.updateQuantity(index, item.qty - 1);
    }
  }

  onQtyInput(event: Event): void {
    const idx = this.cartService.selectedItemIndex();
    if (idx === null) return;
    const val = parseInt((event.target as HTMLInputElement).value) || 1;
    this.cartService.updateQuantity(idx, val);
  }

  onPriceChange(index: number, event: Event): void {
    const val = parseFloat((event.target as HTMLInputElement).value) || 0;
    this.cartService.setPrice(index, val);
  }

  onDiscountChange(index: number, event: Event): void {
    const val = parseFloat((event.target as HTMLInputElement).value) || 0;
    this.cartService.setLineDiscount(index, val);
  }

  onTaxChange(index: number, event: Event): void {
    const val = parseFloat((event.target as HTMLInputElement).value) || 0;
    this.cartService.setLineTax(index, val);
  }
}
