import { mergeMindSpacePagePatch, normalizeMindSpacePagePatchInput } from './mindspace-page-patch.mjs';

export function createPageLiveEditService({ pageService, resolveUserIdForAgentSession }) {
  /** @type {Map<string, { userId: string, pageId: string, boundAt: number }>} */
  const sessionBindings = new Map();
  /** @type {Map<string, number>} */
  const liveRevisions = new Map();

  const bumpRevision = (pageId) => {
    liveRevisions.set(pageId, (liveRevisions.get(pageId) ?? 0) + 1);
  };

  return {
    bindSession({ userId, sessionId, pageId, parentSessionId = null }) {
      if (!userId || !sessionId || !pageId) {
        throw Object.assign(new Error('缺少绑定参数'), { code: 'invalid_request' });
      }
      sessionBindings.set(String(sessionId), {
        userId: String(userId),
        pageId: String(pageId),
        parentSessionId: parentSessionId ? String(parentSessionId) : null,
        boundAt: Date.now(),
      });
      return {
        sessionId: String(sessionId),
        pageId: String(pageId),
        ...(parentSessionId ? { parentSessionId: String(parentSessionId) } : {}),
      };
    },

    unbindSession(sessionId) {
      sessionBindings.delete(String(sessionId));
    },

    getBinding(sessionId) {
      return sessionBindings.get(String(sessionId)) ?? null;
    },

    getLiveRevision(pageId) {
      return liveRevisions.get(String(pageId)) ?? 0;
    },

    async applyAgentPatch(input) {
      const sessionId = String(input?.sessionId ?? input?.session_id ?? '').trim();
      const pageId = String(input?.pageId ?? input?.page_id ?? '').trim();
      if (!sessionId || !pageId) {
        throw Object.assign(new Error('缺少 session_id 或 page_id'), { code: 'invalid_request' });
      }

      const userId = await resolveUserIdForAgentSession(sessionId);
      if (!userId) {
        throw Object.assign(new Error('无效的 Agent 会话'), { code: 'forbidden' });
      }

      const binding = sessionBindings.get(sessionId);
      if (binding && binding.pageId !== pageId) {
        throw Object.assign(new Error('当前会话未绑定该页面'), { code: 'page_binding_mismatch' });
      }
      if (binding && binding.userId !== userId) {
        throw Object.assign(new Error('会话与用户不匹配'), { code: 'forbidden' });
      }

      const patch = normalizeMindSpacePagePatchInput(input);
      if (!patch) {
        throw Object.assign(new Error('缺少 title / summary / content 变更'), { code: 'invalid_request' });
      }

      const page = await pageService.getPage(userId, pageId);
      const merged = mergeMindSpacePagePatch(
        {
          title: page.title,
          summary: page.summary ?? '',
          content: page.content ?? '',
        },
        patch,
      );

      const updated = await pageService.updatePage(userId, pageId, {
        expectedVersion: input?.expectedVersion ?? input?.expected_version ?? page.versionNo,
        title: merged.title,
        summary: merged.summary,
        content: merged.content,
        templateId: page.templateId,
        changeNote: String(input?.changeNote ?? input?.change_note ?? 'Agent 对话修改').slice(0, 255),
      });

      bumpRevision(pageId);
      return {
        page: updated,
        liveRevision: liveRevisions.get(pageId) ?? 0,
      };
    },

    async getRevisionSnapshot(userId, pageId) {
      const page = await pageService.getPage(userId, pageId);
      return {
        pageId: page.id,
        versionNo: page.versionNo,
        updatedAt: page.updatedAt,
        liveRevision: liveRevisions.get(pageId) ?? 0,
      };
    },
  };
}
