import { renderHook, act } from '@testing-library/react';
import { useSliderEditor } from '../SliderEditorContext';
import { SliderEditorProvider } from '../SliderEditorContext';
import type { SliderContent } from '@/types/slider';

// Mock uuid to return predictable IDs
jest.mock('uuid', () => ({
  v4: jest.fn(() => 'test-uuid-12345'),
}));

// Mock server actions to avoid next-auth dependencies
jest.mock('@/app/actions/slider', () => ({
  saveHeroSlider: jest.fn(() => Promise.resolve()),
  getHeroSlider: jest.fn(() => Promise.resolve(null)),
}));

describe('SliderEditorContext', () => {
  describe('addSlide', () => {
    it('should add a new slide with incremented order', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.addSlide();
      });

      expect(result.current.sliderContent.slides).toHaveLength(2);
      expect(result.current.sliderContent.slides[1].order).toBe(1);
      expect(result.current.sliderContent.slides[1].id).toBe('test-uuid-12345');
    });

    it('should set hasUnsavedChanges to true when adding slide', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.addSlide();
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(true);
    });
  });

  describe('deleteSlide', () => {
    it('should remove slide at specified index', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
          {
            id: 'slide-2',
            order: 1,
            image: { url: 'image2.jpg', source: 'upload' },
            headline: 'Slide 2',
            headlineFormatting: {},
            subheading: 'Sub 2',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.deleteSlide(0);
      });

      expect(result.current.sliderContent.slides).toHaveLength(1);
      expect(result.current.sliderContent.slides[0].id).toBe('slide-2');
    });

    it('should prevent deleting the last slide', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.deleteSlide(0);
      });

      expect(result.current.sliderContent.slides).toHaveLength(1);
    });

    it('should set hasUnsavedChanges to true when deleting slide', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
          {
            id: 'slide-2',
            order: 1,
            image: { url: 'image2.jpg', source: 'upload' },
            headline: 'Slide 2',
            headlineFormatting: {},
            subheading: 'Sub 2',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.deleteSlide(0);
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(true);
    });
  });

  describe('updateSlide', () => {
    it('should update slide with partial updates without mutation', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.updateSlide(0, {
          headline: 'Updated Headline',
        });
      });

      expect(result.current.sliderContent.slides[0].headline).toBe('Updated Headline');
      expect(result.current.sliderContent.slides[0].subheading).toBe('Sub 1');
      expect(result.current.sliderContent.slides[0].id).toBe('slide-1');
    });

    it('should handle text formatting updates', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.updateSlide(0, {
          headlineFormatting: {
            color: '#003366',
            bold: true,
          },
        });
      });

      expect(result.current.sliderContent.slides[0].headlineFormatting).toEqual({
        color: '#003366',
        bold: true,
      });
    });

    it('should set hasUnsavedChanges to true when updating slide', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.updateSlide(0, { headline: 'New Headline' });
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(true);
    });
  });

  describe('selectSlide', () => {
    it('should update currentSlideIndex', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
          {
            id: 'slide-2',
            order: 1,
            image: { url: 'image2.jpg', source: 'upload' },
            headline: 'Slide 2',
            headlineFormatting: {},
            subheading: 'Sub 2',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.selectSlide(1);
      });

      expect(result.current.formState.currentSlideIndex).toBe(1);
    });
  });

  describe('Form State Management', () => {
    it('should toggle carousel collapse state', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      expect(result.current.formState.isCarouselCollapsed).toBe(false);

      act(() => {
        result.current.toggleCarouselCollapse();
      });

      expect(result.current.formState.isCarouselCollapsed).toBe(true);

      act(() => {
        result.current.toggleCarouselCollapse();
      });

      expect(result.current.formState.isCarouselCollapsed).toBe(false);
    });

    it('should manage unsaved changes flag', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      expect(result.current.formState.hasUnsavedChanges).toBe(false);

      act(() => {
        result.current.setHasUnsavedChanges(true);
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(true);

      act(() => {
        result.current.setHasUnsavedChanges(false);
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(false);
    });

    it('should discard changes and reset form state', () => {
      const initialContent: SliderContent = {
        id: 'slider-1',
        slides: [
          {
            id: 'slide-1',
            order: 0,
            image: { url: 'image1.jpg', source: 'upload' },
            headline: 'Slide 1',
            headlineFormatting: {},
            subheading: 'Sub 1',
            subheadingFormatting: {},
            button: { text: 'Learn More', url: '#' },
          },
        ],
        updatedAt: new Date(),
      };

      const wrapper = ({ children }: { children: React.ReactNode }) => (
        <SliderEditorProvider initialSliderContent={initialContent}>
          {children}
        </SliderEditorProvider>
      );

      const { result } = renderHook(() => useSliderEditor(), { wrapper });

      act(() => {
        result.current.setHasUnsavedChanges(true);
        result.current.selectSlide(0);
      });

      act(() => {
        result.current.discardChanges();
      });

      expect(result.current.formState.hasUnsavedChanges).toBe(false);
    });
  });
});
