import { __esDecorate, __runInitializers } from "tslib";
/* eslint-disable @typescript-eslint/no-unused-vars */
import { nothing } from 'lit';
import { ActivityLifecycle, IntentResult } from './ActivityManager.js';
import { FragmentManager } from './FragmentManager.js';
import { bound } from '../decorators/bound.js';
import { EventTypes } from '../events/EventTypes.js';
/**
 * ## Activity
 *
 * `Activity` is a core building block of your application, representing a single,
 * focused operation that a user can perform.
 * Activities manage their own lifecycle, UI, and fragments, and communicate with the application
 * and other activities via intents.
 *
 * Activities are managed by the application and can be started, paused, resumed, stopped,
 * and destroyed according to the app's navigation and user actions.
 * They can also start other activities for results, manage fragments, and handle intent
 * events dispatched by hosted web components.
 *
 * ### Lifecycle Methods
 * - `onCreate(intent?)` - Called when the activity is first created.
 * - `onStart()` - Called when the activity becomes visible to the user.
 * - `onResume()` - Called when the activity gains focus and becomes interactive.
 * - `onPause()` - Called when the activity loses focus but is still visible.
 * - `onStop()` - Called when the activity is no longer visible.
 * - `onDestroy()` - Called before the activity is destroyed.
 * - `onRestart()` - Called after the activity has been stopped, just prior to it being started again.
 *
 * ### Example
 * ```typescript
 * class MyActivity extends Activity {
 *   async onCreate(intent?: Intent) {
 *     super.onCreate(intent);
 *     // Initialization logic here
 *   }
 *
 *   render() {
 *     return html`<h1>Hello from MyActivity!</h1>`;
 *   }
 * }
 * ```
 */
let Activity = (() => {
    let _classSuper = EventTarget;
    let _instanceExtraInitializers = [];
    let _handleIntentEvent_decorators;
    return class Activity extends _classSuper {
        static {
            const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
            _handleIntentEvent_decorators = [bound];
            __esDecorate(this, null, _handleIntentEvent_decorators, { kind: "method", name: "handleIntentEvent", static: false, private: false, access: { has: obj => "handleIntentEvent" in obj, get: obj => obj.handleIntentEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
            if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
        }
        /**
         * The root element where the activity's content should be rendered.
         * Set this if you want to render outside the application's default render root (e.g., for modals).
         */
        renderRoot = __runInitializers(this, _instanceExtraInitializers);
        /**
         * An optional static action name for the activity.
         * Use this as the registration key for referencing the activity in intents.
         *
         * @example
         * ```typescript
         * class LoginActivity extends Activity {
         *   static action = 'login';
         * }
         * ```
         */
        static action;
        /** The current lifecycle state of the activity. */
        lifecycle = ActivityLifecycle.Initialized;
        /** The parent application instance. */
        parent;
        /** The fragment manager for managing fragments within this activity. */
        manager;
        /** Data to be returned as a result to the calling activity. */
        resultData;
        /** The exit code for the activity result. */
        exitCode = IntentResult.RESULT_CANCELED;
        /** Gets the current result code for the activity. */
        get resultCode() {
            return this.exitCode;
        }
        /**
         * Constructs a new Activity.
         * @param parent The parent application instance.
         */
        constructor(parent) {
            super();
            this.parent = parent;
            this.manager = new FragmentManager(this);
        }
        /**
         * Returns the current activity instance.
         * @returns This activity.
         */
        getActivity() {
            return this;
        }
        /**
         * Checks if the activity is in the `Destroyed` state.
         * @returns `true` if destroyed, `false` otherwise.
         */
        isDestroyed() {
            return this.lifecycle === ActivityLifecycle.Destroyed;
        }
        /**
         * Checks if the activity is in the `Resumed` state.
         * @returns `true` if resumed, `false` otherwise.
         */
        isResumed() {
            return this.lifecycle === ActivityLifecycle.Resumed;
        }
        /**
         * Called when the activity is starting. Override to perform initialization logic.
         * @param intent Optional intent data.
         * @example
         * ```typescript
         * async onCreate(intent?: Intent) {
         *   await fetchData();
         * }
         * ```
         */
        onCreate(intent) {
            this.dispatchEvent(new CustomEvent('activity:create', { detail: intent }));
        }
        /**
         * Called when the activity becomes visible to the user.
         * Override to start animations or prepare UI.
         */
        onStart() {
            this.dispatchEvent(new CustomEvent('activity:start', { detail: null }));
        }
        /**
         * Called when the activity gains focus and becomes interactive.
         * Override to start input handling or resume tasks.
         */
        onResume() {
            this.dispatchEvent(new CustomEvent('activity:resume', { detail: null }));
        }
        /**
         * Called when the activity loses focus but is still visible.
         * Override to pause ongoing tasks or save state.
         */
        onPause() {
            this.dispatchEvent(new CustomEvent('activity:pause', { detail: null }));
        }
        /**
         * Called when the activity is no longer visible to the user.
         * Override to stop UI updates or animations.
         */
        onStop() {
            this.dispatchEvent(new CustomEvent('activity:stop', { detail: null }));
        }
        /**
         * Called after the activity has been stopped, just prior to it being started again.
         */
        onRestart() {
            this.dispatchEvent(new CustomEvent('activity:restart', { detail: null }));
        }
        /**
         * Called before the activity is destroyed. Override to clean up resources.
         */
        onDestroy() {
            this.dispatchEvent(new CustomEvent('activity:destroy', { detail: null }));
            this.manager.onDestroy();
        }
        /**
         * Called when a new intent is delivered to the activity.
         * Override to handle new intents.
         * @param intent New intent data.
         */
        onNewIntent(intent) {
            // Override in subclass if needed
        }
        /**
         * Called by the renderer when the activity is rendered for the first time.
         * Override to perform actions after first render.
         */
        onFirstRender() {
            // Override in subclass if needed
        }
        /**
         * Renders the activity's view. Override to provide UI.
         * @returns A Lit TemplateResult or `nothing` if nothing should be rendered.
         * @example
         * ```typescript
         * render() {
         *   return html`<div>Hello, world!</div>`;
         * }
         * ```
         */
        render() {
            return nothing;
        }
        /**
         * Finishes the activity and notifies the application.
         * @example
         * ```typescript
         * await this.finish();
         * ```
         */
        async finish() {
            await this.getApplication().manager.finishActivity(this);
        }
        /**
         * Requests the parent application to update the UI.
         * @param opts Update options.
         * @example
         * ```typescript
         * this.requestUpdate();
         * ```
         */
        requestUpdate(opts = {}) {
            const { activity = true } = opts;
            if (activity) {
                this.manager.updateActiveFragments();
            }
            this.parent.requestUpdate(opts);
        }
        /**
         * Registers a new fragment with this activity.
         * @param key The fragment's key.
         * @param fragment The fragment instance.
         * @param data Optional data to pass to the fragment.
         * @example
         * ```typescript
         * await this.addFragment('profile', new ProfileFragment());
         * ```
         */
        async addFragment(key, fragment, data) {
            await this.manager.attachFragment(key, fragment, this, data);
        }
        /**
         * Shows a registered fragment.
         * @param key The fragment's key.
         * @param root Optional root element to render into.
         */
        async showFragment(key, root) {
            await this.manager.showFragment(key, root);
        }
        /**
         * Hides a registered fragment.
         * @param key The fragment's key.
         */
        async hideFragment(key) {
            const fragment = this.manager.findFragment(key);
            if (fragment) {
                await this.manager.hideFragment(fragment);
            }
        }
        /**
         * Returns the parent application instance.
         * @returns The application.
         */
        getApplication() {
            return this.parent;
        }
        /**
         * Starts a new activity.
         * @param intent The intent to start.
         * @example
         * ```typescript
         * await this.startActivity({ action: 'login' });
         * ```
         */
        async startActivity(intent) {
            const { manager } = this.getApplication();
            return manager.startActivity(intent);
        }
        /**
         * Starts a new activity for a result.
         * @template T The type of the result data expected.
         * @param intent The intent to start.
         * @returns A promise that resolves when the started activity finishes, returning the result Intent with
         * data of type T.
         * @example
         * ```typescript
         * const resultIntent = await this.startActivityForResult<{ userId: string }>({ action: 'pickUser' });
         * if (resultIntent.resultCode === IntentResult.RESULT_OK) {
         *   console.log(resultIntent.data?.userId);
         * }
         * ```
         */
        async startActivityForResult(intent) {
            const { manager } = this.getApplication();
            return manager.startActivityForResult(intent);
        }
        /**
         * Sets the result to be returned to the calling activity.
         * @param resultCode The result code.
         * @param data Optional result data.
         * @example
         * ```typescript
         * this.setResult(IntentResult.RESULT_OK, { userId: 123 });
         * ```
         */
        setResult(resultCode, data) {
            this.exitCode = resultCode;
            this.resultData = data;
        }
        /**
         * Gets the result data set by `setResult`.
         * @returns The result data or `undefined`.
         */
        getResult() {
            return this.resultData;
        }
        /**
         * Handles intent events dispatched by web components hosted by this activity.
         *
         * Usage example:
         * ```html
         * <custom-element @startactivity="${this.handleIntentEvent}"></custom-element>
         * <custom-element @startactivityforresult="${this.handleIntentEvent}"></custom-element>
         * ```
         *
         * @param event The intent event.
         * @throws Error if the event type is not recognized.
         */
        async handleIntentEvent(event) {
            if (event.type === EventTypes.Intent.startActivityForResult) {
                const info = event.detail;
                const result = await this.startActivityForResult(info.intent);
                info.onResult(result.result, result);
            }
            else if (event.type === EventTypes.Intent.startActivity) {
                await this.startActivity(event.detail.intent);
            }
            else {
                throw new Error(`Unrecognized intent event: ${event.type}`);
            }
        }
    };
})();
export { Activity };
//# sourceMappingURL=Activity.js.map