import { ChangeDetectionStrategy, Component, computed, effect, inject, OnInit, signal, untracked, ViewChild } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { startWith } from 'rxjs';

import { CartService } from '../../../../core/services/cart/cart.service';
import { TenantService } from '../../../../core/services/tenant.service';
import { CheckoutService, CreatePurchasePayload } from '../../../../core/services/checkout.service';
import { AuthService } from '../../../../core/services/auth/auth.service';
import { BankAccount } from '../../../../core/services/tenant.interface';
import { CartItem } from '../../../../core/services/cart/cart.interface';
import { CartComponent, CartItemMock } from '../../../../shared/components/cart/cart.component';
import { StepComponent } from '../../../../shared/components/stepper/step.component';
import { StepperComponent } from '../../../../shared/components/stepper/stepper.component';
import { CheckoutDataStepComponent } from './checkout-data-step.component';
import { CheckoutPaymentStepComponent } from './checkout-payment-step.component';
import { CheckoutForm, PaymentMethod, PaymentMethodOption, TransferAccount, TransferField } from './checkout-page.models';

@Component({
  selector: 'app-checkout-page',
  standalone: true,
  imports: [
    CartComponent,
    StepperComponent,
    StepComponent,
    CheckoutDataStepComponent,
    CheckoutPaymentStepComponent
  ],
  templateUrl: './checkout-page.component.html',
  styleUrl: './checkout-page.component.scss',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CheckoutPageComponent implements OnInit {
  private readonly formBuilder = inject(FormBuilder);
  private readonly cartService = inject(CartService);
  private readonly router = inject(Router);
  private readonly tenantService = inject(TenantService);
  private readonly checkoutService = inject(CheckoutService);
  private readonly authService = inject(AuthService);

  @ViewChild(StepperComponent) stepper!: StepperComponent;

  protected readonly form: CheckoutForm = this.formBuilder.nonNullable.group({
    nombre: ['', [Validators.required]],
    email: ['', [Validators.required, Validators.email]],
    dni: ['', [Validators.required]],
    telefono: ['', [Validators.required]]
  });

  protected readonly cartSubtotal = computed(() => {
    const cart = this.cartService.cart();
    return cart ? parseFloat(cart.subtotal) : 0;
  });

  protected readonly cartDiscount = computed(() => 0);

  protected readonly cartTotal = computed(() => this.cartSubtotal() - this.cartDiscount());

  protected readonly mappedCartItems = computed<CartItemMock[]>(() => {
    const cart = this.cartService.cart();
    if (!cart || !cart.items) return [];
    return cart.items.map((item) => this.mapCartItemToMock(item));
  });

  protected readonly isStep1Valid = signal(this.form.valid);
  protected readonly paymentMethods: ReadonlyArray<PaymentMethodOption> = [
    { id: 'qr', label: 'QR' },
    { id: 'transfer', label: 'Transferencia' },
    { id: 'telepagos', label: 'TelePagos' }
  ];
  protected readonly selectedPaymentMethod = signal<PaymentMethod>('qr');
  protected readonly copiedTransferField = signal<TransferField | null>(null);
  protected readonly transferAccount = signal<TransferAccount>({
    titular: 'Nombre y Apellido',
    entidad: 'TelePagos',
    cvu: '0000000000000000000000',
    alias: 'telepagos.ar'
  });

  protected readonly isCreatingPurchase = signal(false);
  protected readonly createdPurchaseId = signal<number | null>(null);
  protected readonly isGeneratingIntent = signal(false);
  protected readonly isPaymentLoading = computed(() => this.isGeneratingIntent() || this.cartService.isUpdating());
  protected readonly qrData = signal<string | null>(null);

  constructor() {
    effect(() => {
      // We only want to trigger the intent generation when the cart changes.
      // So we track the cart, but untrack the other signals to prevent duplicate calls.
      const cart = this.cartService.cart();
      
      untracked(() => {
        const purchaseId = this.createdPurchaseId();
        if (cart && purchaseId) {
          // Trigger payment intent generation when cart changes and we are on the payment step
          void this.selectPaymentMethod(this.selectedPaymentMethod());
        }
      });
    });

    this.form.statusChanges
      .pipe(startWith(this.form.status))
      .subscribe(() => this.isStep1Valid.set(this.form.valid));

    const user = this.authService.user();
    if (user) {
      this.form.patchValue({
        nombre: user.nombre_apellido,
        email: user.email,
        dni: user.dni ?? '',
        telefono: user.telefono ?? ''
      });
      this.form.controls.nombre.disable();
      this.form.controls.email.disable();
    }
  }

  ngOnInit(): void {
    this.cartService.loadCart().subscribe();
  }

  private mapCartItemToMock(item: CartItem): CartItemMock {
    const fullName = item.product?.nombre ?? '';
    let product = fullName;
    let attributes: { label: string; value: string }[] = [];

    const match = fullName.match(/^(.*?)\s*\((.*?)\)$/);
    if (match) {
      product = match[1];
      const attributesString = match[2];
      attributes = attributesString.split(',').map((attr) => {
        const parts = attr.split(':');
        if (parts.length === 2) {
          return { label: parts[0].trim(), value: parts[1].trim() };
        }
        return { label: '', value: attr.trim() };
      });
    }

    return {
      productVariantId: item.product_variant_id,
      imageUrl: item.product?.imagen ?? null,
      product,
      originalPrice: null,
      discountedPrice: parseFloat(item.precio_unitario),
      discountPercentage: null,
      attributes,
      quantity: item.cantidad
    };
  }

  protected async onStep1Continue(): Promise<void> {
    if (this.form.invalid) return;

    const tenant = this.tenantService.tenant();
    if (!tenant) return;

    this.isCreatingPurchase.set(true);

    try {
      const cart = this.cartService.cart();
      if (!cart?.id) {
        throw new Error('No hay un carrito activo para finalizar la compra.');
      }

      const formValue = this.form.getRawValue();
      const payload: CreatePurchasePayload = {
        cart_id: cart.id,
        dni: formValue.dni,
        telefono: formValue.telefono,
        email: formValue.email,
        nombre_apellido: formValue.nombre,
      };

      const response = await this.checkoutService.createPurchase(tenant.codigo, payload);
      this.createdPurchaseId.set(response.id);
      
      this.stepper.next();
      
      // Auto trigger intent for default option
      void this.selectPaymentMethod(this.selectedPaymentMethod());

    } catch (error) {
      console.error('Failed to create purchase:', error);
      // Here we could show an alert or toast
    } finally {
      this.isCreatingPurchase.set(false);
    }
  }

  protected onCancel(): void {
    void this.router.navigate(['/']);
  }

  protected async selectPaymentMethod(method: PaymentMethod): Promise<void> {
    this.selectedPaymentMethod.set(method);

    const purchaseId = this.createdPurchaseId();
    const tenant = this.tenantService.tenant();

    if (!purchaseId || !tenant || method === 'telepagos') {
      return;
    }

    this.isGeneratingIntent.set(true);

    try {
      const response = await this.checkoutService.generatePaymentIntent(tenant.codigo, purchaseId, method);
      
      if (method === 'qr' && response.qr_data?.qr_code) {
        this.qrData.set(response.qr_data.qr_code);
      } else if (method === 'transfer' && response.transfer_data) {
        this.transferAccount.set({
          titular: response.transfer_data.titular,
          entidad: response.transfer_data.entidad,
          cvu: response.transfer_data.cvu,
          alias: response.transfer_data.alias
        });
      }
    } catch (error) {
      console.error('Failed to generate payment intent:', error);
    } finally {
      this.isGeneratingIntent.set(false);
    }
  }

  protected async copyTransferValue(field: TransferField, value: string): Promise<void> {
    if (!globalThis.navigator?.clipboard?.writeText) return;

    try {
      await globalThis.navigator.clipboard.writeText(value);
      this.copiedTransferField.set(field);

      setTimeout(() => {
        if (this.copiedTransferField() === field) {
          this.copiedTransferField.set(null);
        }
      }, 1800);
    } catch {
      this.copiedTransferField.set(null);
    }
  }

  protected async onComplete(): Promise<void> {
    const purchaseId = this.createdPurchaseId();
    const tenant = this.tenantService.tenant();

    if (!purchaseId || !tenant) {
      return;
    }

    try {
      await this.checkoutService.completePurchase(tenant.codigo, purchaseId);
      this.cartService.clearCart();
      void this.router.navigate(['/checkout/status', purchaseId]);
    } catch (error) {
      console.error('Failed to complete purchase:', error);
    }
  }
}
