import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';

import { ImageBlock } from './ImageBlock';

// ReactNodeViewRenderer が React に依存するため View をモックする
vi.mock('./components/ImageBlockView', () => ({
  ImageBlockView: vi.fn(),
}));

beforeAll(() => {
  (global as unknown as { ACMS: { Config: { eid: number } } }).ACMS = {
    Config: { eid: 1 },
  };
});

afterAll(() => {
  vi.unstubAllGlobals();
});

/**
 * ImageBlock を載せた Editor を生成する。
 * @param getImageDefaultLightbox 拡大表示のデフォルトを返す getter。未指定なら拡張のデフォルト（常に true）。
 */
const createEditor = (getImageDefaultLightbox?: () => boolean) => {
  const imageBlock = getImageDefaultLightbox ? ImageBlock.configure({ getImageDefaultLightbox }) : ImageBlock;
  return new Editor({
    extensions: [StarterKit, imageBlock],
    content: '',
  });
};

/** ドキュメント内の最初の imageBlock ノードの属性を返す */
const findImageBlockAttrs = (editor: Editor): Record<string, unknown> | null => {
  let attrs: Record<string, unknown> | null = null;
  editor.state.doc.descendants((node) => {
    if (node.type.name === 'imageBlock' && attrs === null) {
      attrs = node.attrs;
      return false;
    }
    return undefined;
  });
  return attrs;
};

describe('ImageBlock 拡大表示デフォルト', () => {
  it('getImageDefaultLightbox が true のとき、setImageBlock 挿入で noLightbox は "false"（拡大表示オン）', () => {
    const editor = createEditor(() => true);
    editor.commands.setImageBlock({ src: 'https://example.com/a.jpg' });

    const attrs = findImageBlockAttrs(editor);
    expect(attrs?.noLightbox).toBe('false');

    editor.destroy();
  });

  it('getImageDefaultLightbox が false のとき、setImageBlock 挿入で noLightbox は "true"（拡大表示オフ）', () => {
    const editor = createEditor(() => false);
    editor.commands.setImageBlock({ src: 'https://example.com/a.jpg' });

    const attrs = findImageBlockAttrs(editor);
    expect(attrs?.noLightbox).toBe('true');

    editor.destroy();
  });

  it('setImageBlockAt も設定値に従って noLightbox を設定する', () => {
    const editor = createEditor(() => false);
    editor.commands.setImageBlockAt({ src: 'https://example.com/a.jpg', pos: 0 });

    const attrs = findImageBlockAttrs(editor);
    expect(attrs?.noLightbox).toBe('true');

    editor.destroy();
  });

  it('getter を渡さない場合は現行動作（拡大表示オン = noLightbox "false"）を維持する', () => {
    const editor = createEditor();
    editor.commands.setImageBlock({ src: 'https://example.com/a.jpg' });

    const attrs = findImageBlockAttrs(editor);
    expect(attrs?.noLightbox).toBe('false');

    editor.destroy();
  });

  it('getter は挿入ごとに評価され、後から変えた値が反映される（SWR 遅延を模倣）', () => {
    let lightbox = true;
    const editor = createEditor(() => lightbox);

    editor.commands.setImageBlock({ src: 'https://example.com/a.jpg' });
    expect(findImageBlockAttrs(editor)?.noLightbox).toBe('false');

    // 設定が後から届いて false になったケース
    lightbox = false;
    editor.commands.setContent('');
    editor.commands.setImageBlock({ src: 'https://example.com/b.jpg' });
    expect(findImageBlockAttrs(editor)?.noLightbox).toBe('true');

    editor.destroy();
  });
});
