import '@angular/compiler';
import { signal } from '@angular/core';
import { TestBed, getTestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
  BrowserTestingModule,
  platformBrowserTesting
} from '@angular/platform-browser/testing';
import { of } from 'rxjs';
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';

import { CartService } from '../../../core/services/cart/cart.service';
import { ModalService } from '../../../core/services/modal.service';
import { ToastService } from '../../../core/services/toast.service';
import { CartComponent } from './cart.component';

describe('CartComponent', () => {
  beforeAll(() => {
    try {
      getTestBed().initTestEnvironment(
        BrowserTestingModule,
        platformBrowserTesting()
      );
    } catch {
      // Test environment may already be initialized by another setup entrypoint.
    }
  });

  afterEach(() => {
    TestBed.resetTestingModule();
  });

  it('opens a confirm delete modal before removing an item', async () => {
    const removeItem = vi.fn().mockReturnValue(of({ message: 'Producto eliminado.' }));
    const openConfirmDelete = vi.fn().mockReturnValue(of(true));

    await TestBed.configureTestingModule({
      imports: [CartComponent],
      providers: [
        {
          provide: CartService,
          useValue: {
            cart: signal(null).asReadonly(),
            updateItemQuantity: vi.fn(),
            removeItem
          }
        },
        {
          provide: ModalService,
          useValue: {
            openConfirmDelete
          }
        },
        {
          provide: ToastService,
          useValue: {
            success: vi.fn(),
            info: vi.fn(),
            danger: vi.fn()
          }
        }
      ]
    }).compileComponents();

    const fixture = TestBed.createComponent(CartComponent);
    fixture.componentRef.setInput('items', [
      {
        productVariantId: 10,
        imageUrl: null,
        product: 'Producto de prueba',
        originalPrice: null,
        discountedPrice: 1000,
        discountPercentage: null,
        attributes: [],
        quantity: 1
      }
    ]);
    fixture.detectChanges();

    fixture.debugElement.query(By.css('app-cart-item')).triggerEventHandler('remove');

    expect(openConfirmDelete).toHaveBeenCalledWith({
      title: 'Eliminar producto',
      content:
        'Se eliminara "Producto de prueba" del carrito. Esta accion no se puede deshacer.',
      confirmLabel: 'Eliminar',
      cancelLabel: 'Cancelar'
    });
    expect(removeItem).toHaveBeenCalledWith(10);
  });

  it('does not remove the item when the delete confirmation is cancelled', async () => {
    const removeItem = vi.fn().mockReturnValue(of({}));
    const openConfirmDelete = vi.fn().mockReturnValue(of(false));

    await TestBed.configureTestingModule({
      imports: [CartComponent],
      providers: [
        {
          provide: CartService,
          useValue: {
            cart: signal(null).asReadonly(),
            updateItemQuantity: vi.fn(),
            removeItem
          }
        },
        {
          provide: ModalService,
          useValue: {
            openConfirmDelete
          }
        },
        {
          provide: ToastService,
          useValue: {
            success: vi.fn(),
            info: vi.fn(),
            danger: vi.fn()
          }
        }
      ]
    }).compileComponents();

    const fixture = TestBed.createComponent(CartComponent);
    fixture.componentRef.setInput('items', [
      {
        productVariantId: 10,
        imageUrl: null,
        product: 'Producto de prueba',
        originalPrice: null,
        discountedPrice: 1000,
        discountPercentage: null,
        attributes: [],
        quantity: 1
      }
    ]);
    fixture.detectChanges();

    fixture.debugElement.query(By.css('app-cart-item')).triggerEventHandler('remove');

    expect(openConfirmDelete).toHaveBeenCalled();
    expect(removeItem).not.toHaveBeenCalled();
  });
});
