// ๐Ÿงช STANDARDIZED RIVERPOD SERVICE TEST TEMPLATE
//
// Use this template for consistent testing across all Riverpod services.
// All tests follow the same structure for initialization, mocking, and validation.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

// Import your service files here
// import 'package:services/provider/xxx/xxx_service.dart';
// import 'package:services/provider/xxx/xxx_service_state.dart';

/// Template for service unit tests
void runServiceTemplateUnitTests() {
  group('ServiceTemplate Tests (Standardized Pattern)', () {
    late ProviderContainer container;

    // =============================================================================
    // STANDARD SETUP - All tests follow this pattern
    // =============================================================================

    setUp(() {
      // Create test container with any required overrides
      container = ProviderContainer(
        overrides: [
          // Add any overrides needed for testing here
          // e.g., sharedPreferencesProvider.overrideWithValue(mockPrefs),
        ],
      );
    });

    tearDown(() {
      // Always dispose container to prevent memory leaks
      container.dispose();
    });

    // =============================================================================
    // INITIALIZATION TESTS - Verify proper startup
    // =============================================================================

    group('Initialization Tests', () {
      test('should initialize with default state', () {
        // final state = container.read(serviceTemplateProvider);

        // Standard assertions for initial state
        // expect(state.isLoading, false);
        // expect(state.error, null);
        // expect(state.hasError, false);
      });

      test('should support ProviderScope', () {
        // Test that service works in production ProviderScope
        expect(() => ProviderScope(child: Container()), returnsNormally);
      });

      test('should support UncontrolledProviderScope', () {
        // Test that service works in testing UncontrolledProviderScope
        final testContainer = ProviderContainer();
        expect(
          () => UncontrolledProviderScope(container: testContainer, child: Container()),
          returnsNormally,
        );
        testContainer.dispose();
      });
    });

    // =============================================================================
    // CORE FUNCTIONALITY TESTS - Test main service operations
    // =============================================================================

    group('Core Functionality Tests', () {
       test('should perform main action successfully', () async {
         final service = container.read(serviceTemplateProvider.notifier);
      
         await service.performAction();
      
         final state = container.read(serviceTemplateProvider);
         expect(state.isLoading, false);
         expect(state.hasError, false);
       });

       test('should handle errors gracefully', () async {
         // Use mock to simulate error
         final mockService = MockServiceTemplate();
         final testContainer = ProviderContainer(
           overrides: [
             serviceTemplateProvider.overrideWith(() => mockService),
           ],
         );
      
         mockService.setError('Test error');
      
         final state = testContainer.read(serviceTemplateProvider);
         expect(state.hasError, true);
         expect(state.error, 'Test error');
      
         testContainer.dispose();
       });
    });

    // =============================================================================
    // STATE MANAGEMENT TESTS - Test state transitions
    // =============================================================================

    group('State Management Tests', () {
       test('should handle loading states correctly', () async {
         final service = container.read(serviceTemplateProvider.notifier);
      
         // Verify initial state
         expect(container.read(serviceTemplateProvider).isLoading, false);
      
         // Start async operation and verify loading state
         final future = service.performAction();
         // Note: State might be loading or already completed depending on async timing
      
         await future;
         expect(container.read(serviceTemplateProvider).isLoading, false);
       });

       test('should clear errors when requested', () {
         final service = container.read(serviceTemplateProvider.notifier);
      
         // Set an error state (using mock)
         service.setError('Test error');
         expect(container.read(serviceTemplateProvider).hasError, true);
      
         // Clear error
         service.clearError();
         expect(container.read(serviceTemplateProvider).hasError, false);
       });

       test('should reset to initial state', () {
         final service = container.read(serviceTemplateProvider.notifier);
      
         // Modify state somehow
         service.setError('Test error');
      
         // Reset
         service.reset();
      
         final state = container.read(serviceTemplateProvider);
         expect(state.isLoading, false);
         expect(state.error, null);
       });
    });

    // =============================================================================
    // CONVENIENCE PROVIDERS TESTS - Test helper providers
    // =============================================================================

    group('Convenience Providers Tests', () {
       test('loading provider should return correct state', () {
         final service = container.read(serviceTemplateProvider.notifier);
      
         service.setLoading(true);
         expect(container.read(serviceTemplateIsLoadingProvider), true);
      
         service.setLoading(false);
         expect(container.read(serviceTemplateIsLoadingProvider), false);
       });

       test('error provider should return correct state', () {
         final service = container.read(serviceTemplateProvider.notifier);
      
         service.setError('Test error');
         expect(container.read(serviceTemplateErrorProvider), 'Test error');
      
         service.clearError();
         expect(container.read(serviceTemplateErrorProvider), null);
       });
    });

    // =============================================================================
    // INTEGRATION TESTS - Test interactions with other services
    // =============================================================================

    group('Integration Tests', () {
       test('should work with other services', () async {
         // Test integration with other providers/services
         // This is where you test the real-world usage patterns
       });

       test('should handle dependencies correctly', () {
         // Test that service dependencies are properly injected
         // final bridge = container.read(serviceTemplateBridgeProvider);
         // expect(bridge, isNotNull);
       });
    });

    // =============================================================================
    // MOCK AND TESTING UTILITIES TESTS
    // =============================================================================

    group('Testing Utilities Tests', () {
       test('mock service should work correctly', () {
         final mockService = MockServiceTemplate();
      
         mockService.setMockState(ServiceTemplateState(error: 'Mock error'));
         expect(mockService.error, 'Mock error');
       });

       test('test helper should create containers correctly', () {
         final testContainer = ServiceTemplateTestHelper.createTestContainer();
         expect(testContainer, isNotNull);
         testContainer.dispose();
      
         final mockContainer = ServiceTemplateTestHelper.createMockContainer();
         expect(mockContainer, isNotNull);
         mockContainer.dispose();
       });
    });
  });
}

// =============================================================================
// TESTING BEST PRACTICES CHECKLIST:
// =============================================================================
//
// โœ… Always dispose ProviderContainer in tearDown()
// โœ… Test both ProviderScope and UncontrolledProviderScope compatibility
// โœ… Test initial state
// โœ… Test loading states
// โœ… Test error handling
// โœ… Test state transitions
// โœ… Test convenience providers
// โœ… Test integration with other services
// โœ… Use mocks for external dependencies
// โœ… Test edge cases and error conditions
// โœ… Keep tests focused and isolated
//
// =============================================================================