import { getOwner } from '../-internals/owner/index.js';
import '../object/index.js';
import { FrameworkObject } from '../object/-internals.js';
import { c as computed, g as get, p as inject$1 } from '../../shared-chunks/cache-DtDz7X5V.js';
import '../-internals/meta/lib/meta.js';
import '../debug/index.js';
import '../../@glimmer/validator/index.js';
import { s as symbol } from '../../shared-chunks/to-string-DaIn5NlY.js';
import '../../shared-chunks/mandatory-setter-CXNsxygN.js';
import '../../@glimmer/destroyable/index.js';
import '../../@glimmer/manager/index.js';
import '@embroider/macros';
import '../../shared-chunks/env-DxZ20QzS.js';
import Mixin from '../object/mixin.js';
import '../-internals/runtime/lib/mixins/registry_proxy.js';
import '../-internals/runtime/lib/mixins/container_proxy.js';
import '../-internals/runtime/lib/mixins/comparable.js';
import ActionHandler from '../-internals/runtime/lib/mixins/action_handler.js';
import '../-internals/runtime/lib/mixins/-proxy.js';
import '../enumerable/mutable.js';
import '../-internals/runtime/lib/mixins/target_action_support.js';
import '../-internals/runtime/lib/ext/rsvp.js';

const MODEL = symbol('MODEL');

/**
@module @ember/controller
*/

/**
  @class ControllerMixin
  @namespace Ember
  @uses Ember.ActionHandler
  @private
*/

const ControllerMixin = Mixin.create(ActionHandler, {
  /* ducktype as a controller */
  isController: true,
  concatenatedProperties: ['queryParams'],
  target: null,
  store: null,
  init() {
    this._super(...arguments);
    let owner = getOwner(this);
    if (owner) {
      this.namespace = owner.lookup('application:main');
      this.target = owner.lookup('router:main');
    }
  },
  model: computed({
    get() {
      return this[MODEL];
    },
    set(_key, value) {
      return this[MODEL] = value;
    }
  }),
  queryParams: null,
  /**
   This property is updated to various different callback functions depending on
   the current "state" of the backing route. It is used by
   `Controller.prototype._qpChanged`.
    The methods backing each state can be found in the `Route.prototype._qp` computed
   property return value (the `.states` property). The current values are listed here for
   the sanity of future travelers:
    * `inactive` - This state is used when this controller instance is not part of the active
     route hierarchy. Set in `Route.prototype._reset` (a `router.js` microlib hook) and
     `Route.prototype.actions.finalizeQueryParamChange`.
   * `active` - This state is used when this controller instance is part of the active
     route hierarchy. Set in `Route.prototype.actions.finalizeQueryParamChange`.
   * `allowOverrides` - This state is used in `Route.prototype.setup` (`route.js` microlib hook).
     @method _qpDelegate
    @private
  */
  _qpDelegate: null,
  // set by route

  /**
   During `Route#setup` observers are created to invoke this method
   when any of the query params declared in `Controller#queryParams` property
   are changed.
    When invoked this method uses the currently active query param update delegate
   (see `Controller.prototype._qpDelegate` for details) and invokes it with
   the QP key/value being changed.
     @method _qpChanged
    @private
  */
  _qpChanged(controller, _prop) {
    let dotIndex = _prop.indexOf('.[]');
    let prop = dotIndex === -1 ? _prop : _prop.slice(0, dotIndex);
    let delegate = controller._qpDelegate;
    let value = get(controller, prop);
    delegate(prop, value);
  }
});

// NOTE: This doesn't actually extend EmberObject.
/**
  @class Controller
  @extends EmberObject
  @uses Ember.ControllerMixin
  @public
*/

class Controller extends FrameworkObject.extend(ControllerMixin) {}

/**
  Creates a property that lazily looks up another controller in the container.
  Can only be used when defining another controller.

  Example:

  ```app/controllers/post.js
  import Controller, {
    inject as controller
  } from '@ember/controller';

  export default class PostController extends Controller {
    @controller posts;
  }
  ```

  Classic Class Example:

  ```app/controllers/post.js
  import Controller, {
    inject as controller
  } from '@ember/controller';

  export default Controller.extend({
    posts: controller()
  });
  ```

  This example will create a `posts` property on the `post` controller that
  looks up the `posts` controller in the container, making it easy to reference
  other controllers.

  @method inject
  @static
  @for @ember/controller
  @since 1.10.0
  @param {String} name (optional) name of the controller to inject, defaults to
         the property's name
  @return {ComputedDecorator} injection decorator instance
  @public
*/

function inject(...args) {
  return inject$1('controller', ...args);
}

/**
  A type registry for Ember `Controller`s. Meant to be declaration-merged so string
  lookups resolve to the correct type.

  Blueprints should include such a declaration merge for TypeScript:

  ```ts
  import Controller from '@ember/controller';

  export default class ExampleController extends Controller {
  // ...
  }

  declare module '@ember/controller' {
    export interface Registry {
      example: ExampleController;
    }
  }
  ```

  Then `@inject` can check that the service is registered correctly, and APIs
  like `owner.lookup('controller:example')` can return `ExampleController`.
*/
// eslint-disable-next-line @typescript-eslint/no-empty-object-type

export { ControllerMixin, Controller as default, inject };
