import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, inject } from '@angular/core';
import { DecimalPipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { CartItem, DeliveryOption } from '../../models';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { LanguageService } from '../../services/language.service';
import { CurrencyRatesService } from '../../services/currency-rates.service';

let nextDeliverySelectorId = 0;

@Component({
  selector: 'app-delivery-selector',
  standalone: true,
  imports: [FormsModule, DecimalPipe, TranslatePipe],
  templateUrl: './delivery-selector.component.html',
  styleUrls: ['./delivery-selector.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DeliverySelectorComponent {
  private readonly languageService = inject(LanguageService);
  private readonly currencyRates = inject(CurrencyRatesService);

  @Input({ required: true }) item: CartItem | null = null;

  @Output() selectedDeliveryChange = new EventEmitter<DeliveryOption | null>();

  readonly selectId = `delivery-select-${nextDeliverySelectorId++}`;

  get options(): DeliveryOption[] {
    return this.item?.deliveryOptions ?? [];
  }

  get selectedDelivery(): DeliveryOption | null {
    return this.item?.selectedDelivery ?? null;
  }

  /** Source currency the item's prices are stored in. */
  get sourceCurrency(): string {
    return this.item?.currency || 'RUB';
  }

  /** Currency the shopper has selected for display. */
  get currency(): string {
    return this.languageService.currentCurrency();
  }

  private convert(amount: number): number {
    return this.currencyRates.convert(amount, this.sourceCurrency, this.currency);
  }

  get required(): boolean {
    return this.item?.deliveryMode !== 'digital'
      && this.options.length > 0
      && this.item?.deliverySelectionRequired !== false;
  }

  get isDigital(): boolean {
    return this.item?.deliveryMode === 'digital';
  }

  get selectedKey(): string {
    return this.selectedDelivery ? this.optionKey(this.selectedDelivery) : '';
  }

  get selectedDeliveryTotal(): number {
    const base = (this.selectedDelivery?.deliveryPrice ?? 0) * (this.item?.quantity ?? 1);
    return this.convert(base);
  }

  optionKey(option: DeliveryOption): string {
    return `${option.deliveryPlace}__${option.deliveryTime}__${option.deliveryPrice}`;
  }

  optionLabel(option: DeliveryOption): string {
    const details = [option.deliveryPlace, option.deliveryTime].filter(Boolean);
    details.push(`${this.convert(option.deliveryPrice).toFixed(2)} ${this.currency}`);
    return details.join(' • ');
  }

  trackByOption(index: number, option: DeliveryOption): string {
    return `${index}-${this.optionKey(option)}`;
  }

  onSelectionChange(nextKey: string): void {
    if (!nextKey) {
      this.selectedDeliveryChange.emit(null);
      return;
    }

    this.selectedDeliveryChange.emit(
      this.options.find(option => this.optionKey(option) === nextKey) ?? null
    );
  }
}