// 🎯 STANDARDIZED RIVERPOD SERVICE TEMPLATE
//
// Use this template to create consistent Riverpod services throughout the app.
// This ensures all services follow the same patterns for initialization, testing, and usage.

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

part 'service_template.g.dart';

// =============================================================================
// 1. STATE CLASS - Always immutable with copyWith and convenience getters
// =============================================================================

class ServiceTemplateState {
  final bool isLoading;
  final String? error;
  final DateTime? lastUpdated;
  // Add your specific state properties here

  const ServiceTemplateState({
    this.isLoading = false,
    this.error,
    this.lastUpdated,
  });

  ServiceTemplateState copyWith({
    bool? isLoading,
    String? error,
    DateTime? lastUpdated,
  }) {
    return ServiceTemplateState(
      isLoading: isLoading ?? this.isLoading,
      error: error ?? this.error,
      lastUpdated: lastUpdated ?? this.lastUpdated,
    );
  }

  // Convenience getters - always include these
  bool get hasError => error != null;
  bool get isIdle => !isLoading && error == null;
  bool get isReady => !isLoading && error == null;
}

// =============================================================================
// 2. MAIN SERVICE - Always use @riverpod class pattern
// =============================================================================

@riverpod
class ServiceTemplate extends _$ServiceTemplate {
  @override
  ServiceTemplateState build() {
    // Initialize with default state
    return const ServiceTemplateState();
  }

  // =============================================================================
  // PUBLIC API METHODS - Always async with consistent error handling
  // =============================================================================

  /// Standard async operation pattern
  Future<void> performAction() async {
    state = state.copyWith(isLoading: true, error: null);

    try {
      // TODO: Implement your business logic here
      await Future.delayed(const Duration(milliseconds: 100));

      state = state.copyWith(
        isLoading: false,
        lastUpdated: DateTime.now(),
      );
    } catch (e) {
      state = state.copyWith(
        isLoading: false,
        error: e.toString(),
      );
      rethrow; // Optional: rethrow if caller needs to handle
    }
  }

  /// Standard sync operation pattern
  void updateSetting(String value) {
    try {
      // TODO: Implement your logic here

      state = state.copyWith(
        lastUpdated: DateTime.now(),
      );
    } catch (e) {
      state = state.copyWith(error: e.toString());
    }
  }

  // =============================================================================
  // UTILITY METHODS - Standard helper methods all services should have
  // =============================================================================

  /// Clear error state
  void clearError() {
    state = state.copyWith(error: null);
  }

  /// Reset to initial state
  void reset() {
    state = const ServiceTemplateState();
  }

  /// Force refresh/reload
  Future<void> refresh() async {
    await performAction(); // Or implement specific refresh logic
  }

  // =============================================================================
  // CONVENIENCE GETTERS - Easy access to common state properties
  // =============================================================================

  bool get isLoading => state.isLoading;
  String? get error => state.error;
  bool get hasError => state.hasError;
  bool get isIdle => state.isIdle;
  DateTime? get lastUpdated => state.lastUpdated;
}

// =============================================================================
// 3. CONVENIENCE PROVIDERS - Quick access to commonly used state parts
// =============================================================================

/// Quick access to loading state
@riverpod
bool serviceTemplateIsLoading(Ref ref) {
  return ref.watch(serviceTemplateProvider).isLoading;
}

/// Quick access to error state
@riverpod
String? serviceTemplateError(Ref ref) {
  return ref.watch(serviceTemplateProvider).error;
}

/// Quick access to idle state (not loading, no error)
@riverpod
bool serviceTemplateIsReady(Ref ref) {
  return ref.watch(serviceTemplateProvider).isReady;
}

// =============================================================================
// 4. BRIDGE INTEGRATION (if needed for external services)
// =============================================================================

@riverpod
ServiceTemplateBridge serviceTemplateBridge(Ref ref) {
  return ServiceTemplateBridge();
}

class ServiceTemplateBridge {
  /// External service integration
  Future<String> callExternalApi() async {
    // TODO: Implement actual external service call
    await Future.delayed(const Duration(milliseconds: 100));
    return 'result';
  }
}

// =============================================================================
// 5. TESTING SUPPORT - Mock implementations and test helpers
// =============================================================================

/// Mock service for testing - extends the real service
class MockServiceTemplate extends ServiceTemplate {
  MockServiceTemplate() : super();

  @override
  ServiceTemplateState build() {
    return const ServiceTemplateState();
  }

  /// Test helper to set specific state
  void setMockState(ServiceTemplateState newState) {
    state = newState;
  }

  /// Test helper to simulate loading
  void setLoading(bool loading) {
    state = state.copyWith(isLoading: loading);
  }

  /// Test helper to simulate error
  void setError(String error) {
    state = state.copyWith(error: error, isLoading: false);
  }
}

// =============================================================================
// 6. TEST UTILITIES - Standard test helpers for all services
// =============================================================================

class ServiceTemplateTestHelper {
  /// Create test container for unit tests
  static ProviderContainer createTestContainer({
    List<Override> overrides = const [],
  }) {
    return ProviderContainer(
      overrides: [
        // Add standard test overrides here if needed
        ...overrides,
      ],
    );
  }

  /// Create test container with mock service
  static ProviderContainer createMockContainer() {
    final mockService = MockServiceTemplate();
    return ProviderContainer(
      overrides: [
        serviceTemplateProvider.overrideWith(() => mockService),
      ],
    );
  }

  /// Create test container for production testing (UncontrolledProviderScope)
  static ProviderContainer createProductionTestContainer({
    List<Override> overrides = const [],
  }) {
    return ProviderContainer(
      overrides: overrides,
    );
  }
}

// =============================================================================
// USAGE EXAMPLES:
// =============================================================================
//
// In widgets:
//   final service = ref.watch(serviceTemplateProvider);
//   final isLoading = ref.watch(serviceTemplateIsLoadingProvider);
//
//   await ref.read(serviceTemplateProvider.notifier).performAction();
//
// In tests:
//   final container = ServiceTemplateTestHelper.createTestContainer();
//   final service = container.read(serviceTemplateProvider.notifier);
//   await service.performAction();
//   expect(container.read(serviceTemplateProvider).isReady, true);
//
// =============================================================================