import { ChangeDetectionStrategy, Component, Input, computed, inject } from '@angular/core';
import { Product } from '../../../../../core/products/models/product-domain.model';
import { TranslateService } from '../../../../../i18n/translate.service';
import { TranslatePipe } from '../../../../../i18n/translate.pipe';
import { LanguageService } from '../../../../../services/language.service';
import { CurrencyRatesService } from '../../../../../services/currency-rates.service';
import { getTranslatedField } from '../../../../../utils/item.utils';

interface CompareRow {
  key: string;
  label: string;
  values: string[];
  identical: boolean;
}

const STOCK_LABEL_KEYS: Record<string, string> = {
  high: 'catalog.stockHigh',
  medium: 'catalog.stockMedium',
  low: 'catalog.stockLow',
  out: 'catalog.stockOut'
};

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

  @Input() products: Product[] = [];
  @Input() hideIdentical = false;
  @Input() highlightDifferences = true;

  readonly rows = computed<CompareRow[]>(() => {
    const products = this.products;
    if (products.length === 0) {
      return [];
    }

    const targetCurrency = this.languageService.currentCurrency();

    const baseRows: CompareRow[] = [
      this.toRow('price', this.i18n.t('ux.comparePrice'), products.map(product =>
        `${this.currencyRates.convert(product.price, product.currency, targetCurrency).toFixed(2)} ${targetCurrency}`
      )),
      this.toRow('rating', this.i18n.t('ux.compareRating'), products.map(product => `${(product.rating ?? 0).toFixed(1)}`)),
      this.toRow('stock', this.i18n.t('ux.compareStock'), products.map(product => this.stockLabel(product.remainings))),
      this.toRow('discount', this.i18n.t('ux.compareDiscount'), products.map(product => `${product.discount ?? 0}%`)),
      this.toRow('color', this.i18n.t('ux.compareColor'), products.map(product => product.colour ?? '—')),
      this.toRow('size', this.i18n.t('ux.compareSize'), products.map(product => product.size ?? '—'))
    ];

    const dynamicKeys = [...new Set(products.flatMap(product => (product.descriptionFields ?? []).map(field => field.key)))];

    for (const key of dynamicKeys) {
      const values = products.map(product => {
        const value = (product.descriptionFields ?? []).find(field => field.key === key)?.value;
        return value?.trim() || '—';
      });

      baseRows.push(this.toRow(`attr:${key}`, key, values));
    }

    return this.hideIdentical ? baseRows.filter(row => !row.identical) : baseRows;
  });

  productTitle(product: Product): string {
    return getTranslatedField(product, 'name', this.languageService.currentLanguage());
  }

  isDifferentRow(row: CompareRow): boolean {
    return this.highlightDifferences && !row.identical;
  }

  private stockLabel(remainings: string | undefined): string {
    if (!remainings) {
      return this.i18n.t('ux.compareUnknown');
    }
    const key = STOCK_LABEL_KEYS[remainings.toLowerCase()];
    return key ? this.i18n.t(key) : remainings;
  }

  private toRow(key: string, label: string, values: string[]): CompareRow {
    const normalized = values.map(value => value.trim().toLowerCase());
    const identical = normalized.every(value => value === normalized[0]);

    return { key, label, values, identical };
  }
}
