import { uploadFile, createWhatsappTemplate } from '../api';

// Mock fetch
global.fetch = jest.fn();

describe('HAPTIC API Integration Tests', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    fetch.mockClear();
  });

  describe('uploadFile with HAPTIC parameters', () => {
    it('should append HAPTIC-specific parameters to FormData', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        phoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
        baseUrl: 'https://api.whatsapp.com/v1',
      };

      // Mock successful response
      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      // Verify fetch was called
      expect(fetch).toHaveBeenCalledTimes(1);

      const fetchCall = fetch.mock.calls[0];
      const url = fetchCall[0];
      const options = fetchCall[1];

      expect(url).toContain('/assets/whatsapp');
      expect(options.method).toBe('POST');

      // Verify FormData contains HAPTIC parameters
      const formData = options.body;
      expect(formData).toBeInstanceOf(FormData);

      // Check that FormData contains the file
      expect(formData.get('file')).not.toBeNull();

      // Check that FormData contains HAPTIC parameters
      expect(formData.get('source')).toBe('whatsapp');
      expect(formData.get('wabaId')).toBe('waba-123');
      expect(formData.get('accessToken')).toBe('haptic-token'); // Note: API converts access_token to accessToken
      expect(formData.get('phoneId')).toBe('phone-456');
      expect(formData.get('hostName')).toBe('hapticwhatsappbulk');
      expect(formData.get('baseUrl')).toBe('https://api.whatsapp.com/v1');
    });

    it('should handle missing HAPTIC parameters gracefully', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        // Missing parameters
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('source')).toBe('whatsapp');
      expect(formData.get('wabaId')).toBe('undefined');
      expect(formData.get('accessToken')).toBe('undefined');
      expect(formData.get('phoneId')).toBe('undefined');
      expect(formData.get('hostName')).toBe('undefined');
      expect(formData.get('baseUrl')).toBe('undefined');
    });

    it('should handle undefined whatsappParams', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        // whatsappParams is undefined
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('file')).not.toBeNull();
      // When whatsappParams is undefined, no whatsapp-specific fields are added
      expect(formData.get('source')).toBeNull();
      expect(formData.get('wabaId')).toBeNull();
      expect(formData.get('accessToken')).toBeNull();
      expect(formData.get('phoneId')).toBeNull();
      expect(formData.get('hostName')).toBeNull();
      expect(formData.get('baseUrl')).toBeNull();
    });

    it('should handle empty string parameters', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: '',
        access_token: '',
        phoneId: '',
        hostName: '',
        baseUrl: '',
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('wabaId')).toBe('');
      expect(formData.get('accessToken')).toBe('');
      expect(formData.get('phoneId')).toBe('');
      expect(formData.get('hostName')).toBe('');
      expect(formData.get('baseUrl')).toBe('');
    });

    it('should handle null parameters', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: null,
        access_token: null,
        phoneId: null,
        hostName: null,
        baseUrl: null,
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('wabaId')).toBe('null');
      expect(formData.get('accessToken')).toBe('null');
      expect(formData.get('phoneId')).toBe('null');
      expect(formData.get('hostName')).toBe('null');
    });
  });

  describe('createWhatsappTemplate with HAPTIC payload', () => {
    it('should create FormData with HAPTIC payload structure', () => {
      const payload = {
        name: 'HAPTIC Test Template',
        category: 'MARKETING',
        content: 'Hello {{1}}',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        PhoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
        hapticFileHandle: 'haptic-handle-123',
        status: 'unsubmitted',
      };

      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      createWhatsappTemplate({ payload, gupshupMediaFile: mockFile });

      const fetchCall = fetch.mock.calls[0];
      const url = fetchCall[0];
      const options = fetchCall[1];

      expect(url).toContain('/templates/WHATSAPP');
      expect(options.method).toBe('POST');

      const formData = options.body;
      expect(formData).toBeInstanceOf(FormData);

      // Check payload JSON
      const payloadJson = JSON.parse(formData.get('payload'));
      expect(payloadJson).toEqual(payload);

      // Check file
      expect(formData.get('gupshupMediaFile')).toBe(mockFile);
    });

    it('should handle missing media file', () => {
      const payload = {
        name: 'HAPTIC Test Template',
        category: 'MARKETING',
        content: 'Hello {{1}}',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        PhoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      createWhatsappTemplate({ payload });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('payload')).toBe(JSON.stringify(payload));
      expect(formData.get('gupshupMediaFile')).toBe('undefined');
    });

    it('should handle array of media files', () => {
      const payload = {
        name: 'HAPTIC Test Template',
        category: 'MARKETING',
        content: 'Hello {{1}}',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        PhoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
      };

      const mockFiles = [
        new File(['test1'], 'test1.jpg', { type: 'image/jpeg' }),
        new File(['test2'], 'test2.jpg', { type: 'image/jpeg' }),
      ];

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      createWhatsappTemplate({ payload, gupshupMediaFile: mockFiles });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('gupshupMediaFile_0')).toBe(mockFiles[0]);
      expect(formData.get('gupshupMediaFile_1')).toBe(mockFiles[1]);
    });
  });

  describe('Parameter validation', () => {
    it('should validate required HAPTIC parameters', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        phoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      // All required parameters should be present
      expect(formData.get('wabaId')).toBe('waba-123');
      expect(formData.get('accessToken')).toBe('haptic-token');
      expect(formData.get('phoneId')).toBe('phone-456');
      expect(formData.get('hostName')).toBe('hapticwhatsappbulk');
    });

    it('should handle mixed parameter types', () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        phoneId: '', // empty string
        hostName: null, // null value
      };

      fetch.mockResolvedValueOnce({
        status: 200,
        json: () => Promise.resolve({ success: true }),
      });

      uploadFile({
        file: mockFile,
        assetType: 'whatsapp',
        whatsappParams,
      });

      const fetchCall = fetch.mock.calls[0];
      const formData = fetchCall[1].body;

      expect(formData.get('wabaId')).toBe('waba-123');
      expect(formData.get('accessToken')).toBe('haptic-token');
      expect(formData.get('phoneId')).toBe('');
      expect(formData.get('hostName')).toBe('null');
    });
  });

  describe('Error handling', () => {
    it('should handle API errors gracefully', async () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        phoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
      };

      fetch.mockRejectedValueOnce(new Error('Network error'));

      try {
        await uploadFile({
          file: mockFile,
          assetType: 'whatsapp',
          whatsappParams,
        });
      } catch (error) {
        expect(error.message).toBe('Network error');
      }
    });

    it('should handle HTTP error responses', async () => {
      const mockFile = new File(['test content'], 'test.jpg', { type: 'image/jpeg' });
      const whatsappParams = {
        source: 'whatsapp',
        wabaId: 'waba-123',
        access_token: 'haptic-token',
        phoneId: 'phone-456',
        hostName: 'hapticwhatsappbulk',
      };

      fetch.mockResolvedValueOnce({
        status: 400,
        statusText: 'Bad Request',
        json: () => Promise.resolve({ error: 'Invalid parameters' }),
      });

      try {
        await uploadFile({
          file: mockFile,
          assetType: 'whatsapp',
          whatsappParams,
        });
      } catch (error) {
        expect(error.status).toBe(400);
        expect(error.statusText).toBe('Bad Request');
      }
    });
  });
});
