// ignore: dangling_library_doc_comments
/// Example using cherrypick_annotations together with cherrypick (core) and cherrypick_generator.

///
/// Steps to use this example:
/// 1. Make sure your example/pubspec.yaml contains:
///     - cherrypick_annotations (this package)
///     - cherrypick (core DI engine)
///     - cherrypick_generator (as a dev_dependency)
///     - build_runner (as a dev_dependency)
/// 2. Run code generation to produce DI injectors and mixins:
///    ```sh
///    dart run build_runner build
///    ```
/// 3. The `_$ApiScreen` mixin will be generated automatically.
/// 4. In your app/bootstrap code, install modules and use the generated features.
///
/// See documentation and advanced details at:
/// https://pub.dev/packages/cherrypick_annotations

import 'package:cherrypick_annotations/cherrypick_annotations.dart';
// In a real project, use this import:
// import 'package:cherrypick/cherrypick.dart';

// Temporary stub for demonstration purposes only.
// In real usage, import 'Module' from `package:cherrypick/cherrypick.dart`.
class Module {}

/// This mixin is a stub for documentation and IDE hints only.
/// In a real project, it will be generated by cherrypick_generator after running build_runner.
///
/// Do not implement or edit this by hand!
mixin _$ApiScreen {}

/// Example UI/service class with dependencies to be injected.
///
/// The [@injectable] annotation tells the generator to create an injector mixin for this class.
/// Fields marked with [@inject] will be automatically filled by the code generator (using DI).
@injectable()
class ApiScreen with _$ApiScreen {
  /// The default (main) implementation of the API service.
  @inject()
  late final ApiService apiService;

  /// An alternate API (mock) implementation, injected by name using @named.
  @inject()
  @named('mock')
  late final ApiService mockApiService;

  /// Logger injected from another scope (e.g., global singleton).
  @inject()
  @scope('global')
  late final Logger logger;
}

/// Example DI module using CherryPick annotations.
///
/// The [@module] annotation tells the generator to treat this class as a source of bindings.
/// Methods annotated with [@singleton], [@named], [@provide], [@instance] will be registered into the DI container.
@module()
abstract class AppModule extends Module {
  /// Global singleton logger available throughout the app.
  @singleton()
  Logger provideLogger() => Logger();

  /// Main API implementation, identified with the name 'main'.
  @named('main')
  ApiService createApi() => ApiService();

  /// Mock API implementation, identified as 'mock'.
  @named('mock')
  ApiService createMockApi() => MockApiService();

  /// UserManager is created with runtime parameters, such as per-user session.
  @provide()
  UserManager createManager(@params() Map<String, dynamic> runtimeParams) {
    return UserManager(runtimeParams['id'] as String);
  }
}

// ---------------------------------------------------------------------------
// Example implementations for demonstration only.
// In a real project, these would contain application/service logic.

/// The main API service.
class ApiService {}

/// A mock API implementation (for development or testing).
class MockApiService extends ApiService {}

/// Manages user operations, created using dynamic (runtime) parameters.
class UserManager {
  final String id;
  UserManager(this.id);
}

/// Global logger service.
class Logger {}

void main() {
  // After running code generation, injectors and mixins will be ready to use.
  // Example integration (pseudo-code):
  //
  // import 'package:cherrypick/cherrypick.dart';
  //
  // final scope = CherryPick.openRootScope()..installModules([$AppModule()]);
  // final screen = ApiScreen()..injectFields();
  // print(screen.apiService); // <-- injected!
  //
  // This main() is provided for reference only.
}
