import MergingProcess, { RevealOptions } from '../../../protection-plan/domain/models/merging-process/merging-process';
import { DataAsset } from '../../../../../core/modules/data-assets';
import { PlanMergeProcessView } from '../../../protection-plan/domain/models/merging-process/plan-merge-process-view';
import { MergePersonalProtectionPlanOrchestratorUseCase, RunMergeCallbacks } from './merge-personal-protection-plan-orchestrator-use-case';
import { StartMergeProcessUseCase, StartMergeProcessInput } from './start-merge-process-use-case';
import { AbortMergeProcessUseCase } from './abort-merge-process-use-case';
import { CollectColdSharesProcessUseCase, CollectColdSharesCallbacks } from './plan-shares/collection/collect-cold-shares-process-use-case';
import { CollectReleasedMobileSharesUseCase } from './plan-shares/collection/collect-released-mobile-shares-use-case';
import { RevealPlanDataUseCase } from './reveal-plan-data-use-case';
import MergingProcessRepository from '../../../protection-plan/domain/repositories/merging-process-repository';
import PlanProtocolServicesRegistry from '../../../protection-plan/domain/services/plan-protocol-services-registry';
import { InitializeMergingProcessUseCase } from './initialize-merging-process-use-case';
import { CollectMobileSharesUseCase } from './plan-shares/collection/collect-mobile-shares-use-case';
import MergeAuthorityProtectionPlanRepository from '../../../protection-plan/domain/repositories/merge-authority-protection-plan-repository';
export interface MergePersonalProtectionPlanDeps {
    orchestrator: MergePersonalProtectionPlanOrchestratorUseCase;
    startProcess: StartMergeProcessUseCase;
    abortProcess: AbortMergeProcessUseCase;
    maRepo: MergeAuthorityProtectionPlanRepository;
    collectReleasedMobileShares: CollectReleasedMobileSharesUseCase;
    revealData?: RevealPlanDataUseCase;
    collectColdShares?: CollectColdSharesProcessUseCase;
    mergeRepo: MergingProcessRepository;
    initializeProcess: InitializeMergingProcessUseCase;
    collectMobileShares: CollectMobileSharesUseCase;
    registry: PlanProtocolServicesRegistry;
}
/**
 * Options for the real-time event subscription.
 * Pass via `subscribe()` for an always-on subscription, or inline as `listen` in
 * `MergePersonalProtectionPlanCallbacks` to have `run()` manage the lifecycle automatically.
 */
export interface MergeListenOptions {
    isMergeAuthority: boolean;
    /**
     * Called whenever the process changes due to a real-time event.
     * Use this as a signal to refresh the view: call `getView(planId)` and update local state.
     * In React, wire this to `queryClient.refetchQueries`.
     */
    onProcessChanged?: () => void | Promise<void>;
    /**
     * Called when the MA has approved shares collection.
     * Use as a signal to refresh the shares-collection check.
     */
    onSharesCollectionApproved?: () => void | Promise<void>;
}
/**
 * Callbacks for the reveal step — the final step of the merge flow.
 * Pass via `MergePersonalProtectionPlanCallbacks.reveal` to have `run()` handle reveal automatically
 * after the orchestrator completes.
 */
export interface RevealCallbacks {
    /** Reveal options (timeout). @default { timeoutMinutes: 5 } */
    options?: RevealOptions;
    /**
     * When true, reveal is triggered automatically as soon as the process completes.
     * When false, `run()` waits for `onRequestReveal` to resolve before revealing.
     * @default true
     */
    auto?: boolean;
    /**
     * Called when the process is complete and awaiting user confirmation (only when auto=false).
     * Resolve with options to override defaults, or void/undefined to use defaults.
     */
    onRequestReveal?: (process: MergingProcess) => Promise<RevealOptions | void>;
    /** Called just before the reveal fetch begins — use to set a loading state. */
    onRevealStart?: () => void;
    /** Called with the revealed data assets on success. */
    onRevealed?: (data: DataAsset[] | null) => void;
    /** Called when reveal throws. */
    onRevealError?: (error: Error) => void;
}
export interface MergePersonalProtectionPlanCallbacks {
    /** Emitted after each step starts and on completion, or on error */
    onViewUpdate?: (view: PlanMergeProcessView) => void;
    onStepStart?: RunMergeCallbacks['onStepStart'];
    onStepComplete?: RunMergeCallbacks['onStepComplete'];
    onError?: RunMergeCallbacks['onError'];
    /** Cold-device interaction callbacks (used for COLLECT_COLD_PLAN_SHARES and cold MA shares) */
    coldShares?: CollectColdSharesCallbacks;
    /**
     * Called when waiting for mobile beneficiaries to release their shares.
     * The use case resolves internally via the subscription; this is a status signal only.
     */
    onWaitForMobileShares?: () => void;
    /**
     * Called when waiting for the merge authority to release their mobile share.
     * The use case resolves internally via the subscription; this is a status signal only.
     */
    onWaitForMaShare?: () => void;
    /**
     * When provided, `run()` automatically subscribes to real-time events at the start
     * and unsubscribes in a `finally` block — no manual `subscribe()`/`unsubscribe()` needed.
     * Ignored if a subscription is already active (e.g. set up via `subscribe()`).
     */
    listen?: MergeListenOptions;
    /**
     * When provided, `run()` handles the reveal step automatically after the orchestrator
     * completes. The subscription (if any) remains active during reveal.
     */
    reveal?: RevealCallbacks;
}
/**
 * Primary entry point for the full plan merge flow.
 *
 * Combines:
 *  - Sequential orchestration (MergePersonalProtectionPlanOrchestratorUseCase)
 *  - Cold-shares collection (CollectColdSharesProcessUseCase)
 *  - Real-time event subscription (absorbed from MergeProcessListenerUseCase)
 *  - Reveal flow as the final step (RevealPlanDataUseCase)
 *
 * Vanilla TS usage:
 *   const useCase = container.getService<MergePersonalProtectionPlanUseCase>('MergePersonalProtectionPlanUseCase');
 *
 *   await useCase.build(plan);
 *   await useCase.start({ planId, presentBeneficiaries });
 *   await useCase.run(planId, {
 *       listen: { isMergeAuthority: true, onProcessChanged: async () => { const v = await useCase.getView(planId); updateUI(v); } },
 *       coldShares: { onConnectDevice: async (share) => promptForPin(share) },
 *       onWaitForMobileShares: () => { ui.showWaitingForShares(); },
 *       reveal: {
 *           auto: false,
 *           onRequestReveal: async () => promptTimeoutChoice(),   // resolves when user picks
 *           onRevealStart: () => { ui.showRevealing(); },
 *           onRevealed: (data) => { ui.showData(data); },
 *           onRevealError: (e) => { ui.showError(e); },
 *       },
 *   });
 *
 * React: use `useMergePersonalProtectionPlan` — a thin wrapper over this class.
 */
export declare class MergePersonalProtectionPlanUseCase {
    private deps;
    /** Resolved when all plan triggers are validated and the process can advance. */
    private pendingTriggerActivationResolve;
    /** Resolved by the MA subscription handler when all additional mobile shares are collected. */
    private pendingMobileSharesResolve;
    /** Resolved by the MA subscription handler when the MA share is collected. */
    private pendingMaShareResolve;
    /** Active listen options set by subscribe(); used inside subscription handlers. */
    private listenOptions;
    constructor(deps: MergePersonalProtectionPlanDeps);
    /**
     * Ensures a local merging process record exists for the given plan.
     * Fetches the plan from the MA repository internally.
     */
    build(planId: string): Promise<void>;
    /**
     * Subscribes to real-time merge process events with role-based handlers.
     * Must be called before `run()` when using mobile/MA share waiting steps.
     */
    subscribe(planId: string, processId: string, options: MergeListenOptions): void;
    unsubscribe(planId: string, processId: string): void;
    private getListener;
    private buildMAHandlers;
    private buildShareholderHandlers;
    /**
     * Returns the current view built from all three data sources:
     * the MA plan, the local merge process, and the active trigger state.
     */
    getView(planId: string): Promise<PlanMergeProcessView>;
    start(input: StartMergeProcessInput): Promise<void>;
    abort(planId: string): Promise<void>;
    validateTrigger(planId: string, code: string): Promise<void>;
    retryTrigger(planId: string): Promise<void>;
    /**
     * Reveals the plan data and records the merge expiration on the process.
     * The expiration save ensures the reveal timeout is persisted locally.
     */
    reveal(process: MergingProcess, options: RevealOptions): Promise<DataAsset[] | null>;
    /**
     * Runs the full merge flow: orchestration steps + optional reveal as the final step.
     *
     * If `callbacks.listen` is provided and no subscription is already active,
     * `run()` automatically subscribes at the start and unsubscribes in a `finally`
     * block — the subscription remains active through the reveal step.
     *
     * If `callbacks.reveal` is provided and the process completes successfully,
     * `run()` calls `runReveal()` as the final step before returning.
     */
    run(planId: string, callbacks?: MergePersonalProtectionPlanCallbacks): Promise<void>;
    private runReveal;
    /**
     * Computes countdown/timeout view state from the current view + reveal options.
     * Uses `planRevealInfo` from the view so callers don't need to hold a `PersonalProtectionPlan`.
     */
    computeRevealView(baseView: PlanMergeProcessView | undefined, options: RevealOptions): {
        remainingTime: number;
        timeoutMinutesForClose: number;
    };
}
