/**
 * 子端（iframe 内）到宿主的客户端方法集合。
 * - 负责与父窗口建立并缓存 Penpal 连接
 * - 提供便捷的客户端调用：navigate/close/ready
 */
import { connectToParent } from 'penpal';
import type { HostApi, ChildApi } from './types.js';
import { isEmbedded } from './path.js';
import { log } from './logger.js';

// Cached Penpal connections
// 缓存与宿主的连接，以避免重复握手
let clientHostApiPromise: Promise<HostApi> | null = null;

/** Create a Penpal connection from child to parent and cache the Host API. */
/**
 * 建立从子端到父端的 Penpal 连接，并返回宿主 HostApi（带缓存）。
 * @param options.parentOrigin 可选，宿主的 origin（默认使用当前 window.location.origin）。
 */
export function getClientHostApi(options?: { parentOrigin?: string }): Promise<HostApi> {
  if (!isEmbedded()) {
    log('getClientHostApi() aborted: not embedded');
    return Promise.reject(new Error('Not embedded'));
  }
  if (!clientHostApiPromise) {
    const parentOrigin = options?.parentOrigin ?? window.location.origin;
    log('getClientHostApi() connecting to parent', { parentOrigin });
    clientHostApiPromise = connectToParent<HostApi>({ parentOrigin }).promise.then((host) => {
      log('getClientHostApi() connected', {
        hasNavigate: typeof host.navigate === 'function',
        hasClose: typeof host.close === 'function',
      });
      return host;
    });
  }
  return clientHostApiPromise;
}

/**
 * 请求宿主进行导航。
 * @param to 目标路径（会由宿主自行处理前缀与实际路由规则）
 */
export async function clientNavigate(to: string): Promise<void> {
  log('clientNavigate() begin', { to });
  const host = await getClientHostApi();
  await host.navigate(to);
  log('clientNavigate() done', { to });
}

/**
 * 请求宿主执行关闭或返回操作。
 */
export async function clientClose(): Promise<void> {
  log('clientClose() begin');
  const host = await getClientHostApi();
  log('clientClose() host api', {
    hasClose: typeof host.close === 'function',
  });
  await host.close();
  log('clientClose() done');
}

/**
 * 通知宿主：子端已就绪（可携带 agentId 等信息）。
 */
export async function clientReady(payload?: any): Promise<void> {
  log('clientReady() begin', { payload });
  const host = await getClientHostApi();
  const agentReady = host.agentReady;
  const hasAgentReady = typeof agentReady === 'function';
  log('clientReady() host agentReady', { hasAgentReady });
  if (hasAgentReady) await agentReady!(payload);
  log('clientReady() done');
}

/**
 * 子应用初始化：暴露 ChildApi 给宿主，并获取宿主 HostApi（用于后续 clientNavigate、clientClose 等）。
 * 如果已调用过 getClientHostApi，会复用同一连接。
 */
/**
 * 子应用初始化：
 * - 暴露 ChildApi 给宿主（如 changeLanguage）
 * - 并获取宿主 HostApi（复用同一连接）
 */
export function initChildBridge(params: {
  methods?: ChildApi;
  parentOrigin?: string;
}) {
  const parentOrigin = params.parentOrigin ?? window.location.origin;
  log('initChildBridge() start', { parentOrigin, hasMethods: !!params.methods });
  const connection = connectToParent<HostApi>({ parentOrigin, methods: params.methods as any });
  // 设置并复用 clientHostApiPromise
  clientHostApiPromise = connection.promise;
  connection.promise
    .then(() => log('initChildBridge() parent connected'))
    .catch((err) => log('initChildBridge() connect error', err));
  return connection.promise;
}