/**
 * Tests for the Daily Notification plugin
 */

import { registerPlugin } from '@capacitor/core';
import { DailyNotificationPlugin, NotificationOptions, NotificationStatus, NotificationResponse, NotificationSettings } from '../src/definitions';
import { describe, it, expect, beforeEach, jest } from '@jest/globals';

const DailyNotification = registerPlugin<DailyNotificationPlugin>('DailyNotification');

describe('DailyNotification Plugin', () => {
  const mockOptions: NotificationOptions = {
    url: 'https://api.example.com/daily-content',
    time: '08:00',
    title: 'Test Notification',
    body: 'This is a test notification'
  };

  beforeEach(() => {
    // Reset mocks before each test
    jest.clearAllMocks();
  });

  describe('scheduleDailyNotification', () => {
    it('should schedule a basic notification', async () => {
      await DailyNotification.scheduleDailyNotification(mockOptions);
      // Verify the native implementation was called with correct parameters
      expect(DailyNotification.scheduleDailyNotification).toHaveBeenCalledWith(mockOptions);
    });

    it('should handle network errors gracefully', async () => {
      const errorOptions: NotificationOptions = {
        ...mockOptions,
        url: 'https://invalid-url.com'
      };

      await expect(DailyNotification.scheduleDailyNotification(errorOptions))
        .rejects
        .toThrow('Network error');
    });

    it('should validate required parameters', async () => {
      const invalidOptions = {
        time: '08:00'
      } as NotificationOptions;

      await expect(DailyNotification.scheduleDailyNotification(invalidOptions))
        .rejects
        .toThrow('URL is required');
    });
  });

  describe('getLastNotification', () => {
    it('should return the last notification', async () => {
      const mockResponse: NotificationResponse = {
        title: 'Last Notification',
        body: 'This was the last notification',
        timestamp: new Date().toISOString()
      };

      const result = await DailyNotification.getLastNotification();
      expect(result).toEqual(mockResponse);
    });

    it('should return null when no notifications exist', async () => {
      const result = await DailyNotification.getLastNotification();
      expect(result).toBeNull();
    });
  });

  describe('cancelAllNotifications', () => {
    it('should cancel all scheduled notifications', async () => {
      await DailyNotification.cancelAllNotifications();
      // Verify the native implementation was called
      expect(DailyNotification.cancelAllNotifications).toHaveBeenCalled();
    });
  });

  describe('getNotificationStatus', () => {
    it('should return current notification status', async () => {
      const mockStatus: NotificationStatus = {
        isScheduled: true,
        nextNotificationTime: '2024-03-20T08:00:00Z',
        lastNotificationTime: '2024-03-19T08:00:00Z'
      };

      const result = await DailyNotification.getNotificationStatus();
      expect(result).toEqual(mockStatus);
    });

    it('should handle error status', async () => {
      const mockErrorStatus: NotificationStatus = {
        isScheduled: false,
        error: 'Failed to schedule notification'
      };

      const result = await DailyNotification.getNotificationStatus();
      expect(result).toEqual(mockErrorStatus);
    });
  });

  describe('updateSettings', () => {
    it('should update notification settings', async () => {
      const settings: NotificationSettings = {
        time: '09:00',
        sound: false,
        priority: 'normal'
      };

      await DailyNotification.updateSettings(settings);
      // Verify the native implementation was called with correct parameters
      expect(DailyNotification.updateSettings).toHaveBeenCalledWith(settings);
    });

    it('should validate settings before updating', async () => {
      const invalidSettings = {
        time: 'invalid-time'
      };

      await expect(DailyNotification.updateSettings(invalidSettings))
        .rejects
        .toThrow('Invalid time format');
    });
  });

  describe('Integration Tests', () => {
    it('should handle full notification lifecycle', async () => {
      // Schedule notification
      await DailyNotification.scheduleDailyNotification(mockOptions);

      // Check status
      const status = await DailyNotification.getNotificationStatus();
      expect(status.isScheduled).toBe(true);

      // Update settings
      const settings: NotificationSettings = {
        time: '09:00',
        priority: 'normal'
      };
      await DailyNotification.updateSettings(settings);

      // Verify update
      const updatedStatus = await DailyNotification.getNotificationStatus();
      expect(updatedStatus.nextNotificationTime).toContain('09:00');

      // Cancel notifications
      await DailyNotification.cancelAllNotifications();

      // Verify cancellation
      const finalStatus = await DailyNotification.getNotificationStatus();
      expect(finalStatus.isScheduled).toBe(false);
    });
  });
});