import { describe, it, expect, beforeEach, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import { useUi } from '@/stores/useUi'
import { useAsistenciasStore } from '@/stores/useAsistencias'
import AsistenciasIndex from '../AsistenciasIndex.vue'
import TablaAsistencias from '@/components/asistencias/tablaAsistencias.vue'
import CardAsistencia from '@/components/asistencias/cardAsistencia.vue'

// Mock child components
vi.mock('@/components/asistencias/tablaAsistencias.vue', () => ({
  default: {
    name: 'TablaAsistencias',
    props: ['asistencias', 'isLoading'], // Match actual props if different
    emits: ['edit'],
    template: '<div data-testid="tabla-asistencias"></div>',
  },
}))

vi.mock('@/components/asistencias/cardAsistencia.vue', () => ({
  default: {
    name: 'CardAsistencia',
    props: ['asistencia'], // Match actual props
    emits: ['edit'],
    template: '<div data-testid="card-asistencia"></div>',
  },
}))

// Mock stores
const mockSetDefaultViewAsistencias = vi.fn();
const mockFetchAsistencias = vi.fn();

vi.mock('@/stores/useUi', () => ({
  useUi: vi.fn(() => ({
    defaultViewAsistencias: 'table', // Default mock value
    setDefaultViewAsistencias: mockSetDefaultViewAsistencias,
  })),
}))

vi.mock('@/stores/useAsistencias', () => ({
  useAsistenciasStore: vi.fn(() => ({
    asistencias: [],
    fetchAsistencias: mockFetchAsistencias,
  })),
}))

describe('AsistenciasIndex.vue', () => {
  let uiStoreMock
  let asistenciasStoreMock

  beforeEach(() => {
    setActivePinia(createPinia())
    mockFetchAsistencias.mockClear().mockResolvedValue([])
    mockSetDefaultViewAsistencias.mockClear()

    uiStoreMock = useUi()
    asistenciasStoreMock = useAsistenciasStore()
  })

  const mountComponent = () => {
    return mount(AsistenciasIndex, {
      global: {
        // Stubs can be defined here too if not using vi.mock for everything
      },
    })
  }

  it('fetches asistencias on mount', async () => {
    mountComponent()
    // It seems the component has its own isLoading ref, wait for it to resolve
    await mockFetchAsistencias(); // Ensure the promise resolves
    expect(mockFetchAsistencias).toHaveBeenCalledTimes(1)
  })

  describe('View Rendering based on useUi store', () => {
    it('renders TablaAsistencias when defaultViewAsistencias is "table"', async () => {
      uiStoreMock.defaultViewAsistencias = 'table'
      asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'Test Employee', fecha: '2023-01-01' }]

      const wrapper = mountComponent()
      // Wait for internal loading state and then data processing
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick()
      await wrapper.vm.$nextTick()


      expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(true)
      expect(wrapper.findComponent({ name: 'TablaAsistencias' }).props('asistencias')).toEqual(asistenciasStoreMock.asistencias)
      expect(wrapper.findComponent({ name: 'CardAsistencia' }).exists()).toBe(false)
    })

    it('renders CardAsistencia when defaultViewAsistencias is "card"', async () => {
      uiStoreMock.defaultViewAsistencias = 'card'
      asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'E1' }, { id: 2, empleado: 'E2' }]

      const wrapper = mountComponent()
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick()
      await wrapper.vm.$nextTick()

      const cardWrappers = wrapper.findAllComponents({ name: 'CardAsistencia' })
      expect(cardWrappers.length).toBe(asistenciasStoreMock.asistencias.length)
      expect(cardWrappers[0].props('asistencia')).toEqual(asistenciasStoreMock.asistencias[0])
      expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(false)
    })

    it('renders no data message for table view when no asistencias exist', async () => {
        uiStoreMock.defaultViewAsistencias = 'table';
        asistenciasStoreMock.asistencias = [];

        const wrapper = mountComponent();
        await mockFetchAsistencias();
        await wrapper.vm.$nextTick();
        await wrapper.vm.$nextTick();

        expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(true);
        // The component might show "Cargando asistencias..." initially, then the no data message.
        // We need to ensure loading is complete.
        expect(wrapper.text()).toContain('No hay asistencias para mostrar');
    });

    it('renders no data message for card view when no asistencias exist', async () => {
        uiStoreMock.defaultViewAsistencias = 'card';
        asistenciasStoreMock.asistencias = [];

        const wrapper = mountComponent();
        await mockFetchAsistencias();
        await wrapper.vm.$nextTick();
        await wrapper.vm.$nextTick();

        expect(wrapper.findAllComponents({ name: 'CardAsistencia' }).length).toBe(0);
        expect(wrapper.text()).toContain('No hay asistencias para mostrar');
    });
  })

  describe('Local View Toggle Buttons', () => {
    it('renders toggle buttons and reflects initial view from store (table)', async () => {
      uiStoreMock.defaultViewAsistencias = 'table';
      const wrapper = mountComponent();
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick();
      await wrapper.vm.$nextTick();

      const tableViewButton = wrapper.find('button[aria-label="Table View"]');
      const cardViewButton = wrapper.find('button[aria-label="Card View"]');

      expect(tableViewButton.exists()).toBe(true);
      expect(cardViewButton.exists()).toBe(true);

      // Check active class based on btnViewClass logic
      // Active: bg-[var(--accent-color-asistencias)] text-white
      // Inactive: bg-gray-200 text-gray-700
      expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
      expect(cardViewButton.classes()).toContain('bg-gray-200');
    });

    it('renders toggle buttons and reflects initial view from store (card)', async () => {
      uiStoreMock.defaultViewAsistencias = 'card';
      const wrapper = mountComponent();
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick();
      await wrapper.vm.$nextTick();

      const tableViewButton = wrapper.find('button[aria-label="Table View"]');
      const cardViewButton = wrapper.find('button[aria-label="Card View"]');

      expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
      expect(tableViewButton.classes()).toContain('bg-gray-200');
    });

    it('switches to card view on button click and updates button styles, does not call global store action', async () => {
      uiStoreMock.defaultViewAsistencias = 'table';
      asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'Test' }];
      const wrapper = mountComponent();
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick();
      await wrapper.vm.$nextTick();

      const cardViewButton = wrapper.find('button[aria-label="Card View"]');
      const tableViewButton = wrapper.find('button[aria-label="Table View"]');

      await cardViewButton.trigger('click');
      await wrapper.vm.$nextTick();

      expect(wrapper.findComponent({ name: 'CardAsistencia' }).exists()).toBe(true);
      expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(false);
      expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
      expect(tableViewButton.classes()).toContain('bg-gray-200');
      expect(mockSetDefaultViewAsistencias).not.toHaveBeenCalled();
    });

    it('switches back to table view on button click and updates button styles, does not call global store action', async () => {
      uiStoreMock.defaultViewAsistencias = 'card'; // Start with card view
      asistenciasStoreMock.asistencias = [{ id: 1, empleado: 'Test' }];
      const wrapper = mountComponent();
      await mockFetchAsistencias();
      await wrapper.vm.$nextTick();
      await wrapper.vm.$nextTick();

      // Initially card view is active
      const cardViewButton = wrapper.find('button[aria-label="Card View"]');
      const tableViewButton = wrapper.find('button[aria-label="Table View"]');
      expect(cardViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');


      await tableViewButton.trigger('click');
      await wrapper.vm.$nextTick();

      expect(wrapper.findComponent({ name: 'TablaAsistencias' }).exists()).toBe(true);
      expect(wrapper.findComponent({ name: 'CardAsistencia' }).exists()).toBe(false);
      expect(tableViewButton.classes()).toContain('bg-[var(--accent-color-asistencias)]');
      expect(cardViewButton.classes()).toContain('bg-gray-200');
      expect(mockSetDefaultViewAsistencias).not.toHaveBeenCalled();
    });
  });
})
