import {
  ChangeDetectionStrategy,
  Component,
  computed,
  effect,
  input,
  model,
  output,
} from '@angular/core';

import { ButtonComponent } from '../button/button.component';
import { QuantitySelectorComponent } from '../quantity-selector/quantity-selector.component';
import { TooltipComponent } from '../tooltip/tooltip.component';
import {
  VariantSelectorComponent,
  VariantSelectorVariant,
} from '../variant-selector/variant-selector.component';

export interface VerticalCartVariant extends VariantSelectorVariant {
  descripcion?: string | null;
  precio?: string | number;
  maximum_addable_quantity?: number | null;
  unavailable_message?: string | null;
}

@Component({
  selector: 'app-product-vertical-with-cart-card',
  imports: [ButtonComponent, QuantitySelectorComponent, TooltipComponent, VariantSelectorComponent],
  templateUrl: './product-vertical-with-cart-card.component.html',
  styleUrl: './product-vertical-with-cart-card.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ProductVerticalWithCartCardComponent {
  readonly title = input<string>('');
  readonly description = input<string>('');
  readonly price = input<number>(0);
  readonly maximumAddableQuantity = input<number | null>(null);
  readonly unavailableMessage = input<string | null>(null);
  readonly variants = input<VerticalCartVariant[]>([]);
  readonly saving = input(false);

  readonly quantity = model<number>(1);
  readonly selectedVariant = model<number | null>(null);

  readonly buy = output<{ quantity: number; variant: number | null }>();
  readonly addToCart = output<{ quantity: number; variant: number | null }>();

  protected readonly selectedVariantData = computed(() =>
    this.variants().find((variant) => variant.id === this.selectedVariant()),
  );
  protected readonly effectiveDescription = computed(
    () => this.selectedVariantData()?.descripcion ?? this.description(),
  );
  protected readonly effectivePrice = computed(() => {
    const variantPrice = Number(this.selectedVariantData()?.precio);

    return Number.isFinite(variantPrice) ? variantPrice : this.price();
  });
  protected readonly formattedPrice = computed(() => this.formatCurrency(this.effectivePrice()));
  protected readonly hasVariants = computed(() => this.variants().length > 0);
  protected readonly effectiveMaximum = computed(
    () => this.selectedVariantData()?.maximum_addable_quantity ?? this.maximumAddableQuantity(),
  );
  protected readonly unavailable = computed(() => this.effectiveMaximum() === 0);
  protected readonly effectiveUnavailableMessage = computed(() => {
    const selectedVariant = this.selectedVariantData();

    return selectedVariant
      ? (selectedVariant.unavailable_message ?? null)
      : this.unavailableMessage();
  });

  constructor() {
    effect(() => {
      const maximum = this.effectiveMaximum();

      if (maximum !== null && maximum > 0 && this.quantity() > maximum) {
        this.quantity.set(maximum);
      }
    });
  }

  protected onAddToCart(): void {
    if (this.saving() || this.unavailable()) {
      return;
    }

    this.addToCart.emit({ quantity: this.quantity(), variant: this.selectedVariant() });
  }

  protected onBuy(): void {
    if (this.unavailable()) return;

    this.buy.emit({ quantity: this.quantity(), variant: this.selectedVariant() });
  }

  private formatCurrency(value: number): string {
    const rounded = Math.round(value);
    const parts = rounded.toString().split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.');

    return `$ ${parts.join(',')}`;
  }
}
