export interface ApprovalResult {
  readonly action: string;
  readonly resolvedBy: string;
}

export interface PendingApproval {
  readonly messageId: string;
  readonly chatId: string;
  readonly resolve: (result: ApprovalResult) => void;
}

export interface ApprovalManagerOptions {
  readonly timeoutMs?: number;
}

export class ApprovalManager {
  private readonly timeoutMs: number;
  private pending = new Map<string, PendingApproval>();

  constructor(options: ApprovalManagerOptions = {}) {
    this.timeoutMs = options.timeoutMs ?? 5 * 60 * 1000;
  }

  register(messageId: string, chatId: string): Promise<ApprovalResult> {
    return new Promise<ApprovalResult>((resolve, reject) => {
      const timeout = setTimeout(() => {
        this.pending.delete(messageId);
        reject(new Error(`approval timed out after ${this.timeoutMs}ms`));
      }, this.timeoutMs);
      const unref = (timeout as { unref?: () => void }).unref;
      if (unref !== undefined) unref.call(timeout);

      this.pending.set(messageId, {
        messageId,
        chatId,
        resolve: (result) => {
          clearTimeout(timeout);
          resolve(result);
        },
      });
    });
  }

  resolve(messageId: string, action: string, resolvedBy: string): void {
    const pending = this.pending.get(messageId);
    if (pending === undefined) return;
    this.pending.delete(messageId);
    pending.resolve({ action, resolvedBy });
  }

  hasPending(messageId: string): boolean {
    return this.pending.has(messageId);
  }
}
