import { describe, test, expect, vi } from 'vitest';
import React from 'react';
import { createRoot, Root } from 'react-dom/client';
import { act } from 'react-dom/test-utils';
import { PageProvider, usePages } from './PageContext';

/**
 * PKG-H: `updatePageSeo(pageId, seo)` merges `seo` fields onto the target
 * page's existing `seo` (creating it if absent), leaving every other page
 * and every other field on the target page untouched -- mirrors
 * `renamePage`'s existing merge-by-id pattern.
 */
vi.mock('@craftjs/core', () => ({
  useEditor: () => ({
    query: { serialize: () => '{}' },
    actions: { deserialize: vi.fn() },
  }),
}));

let container: HTMLDivElement;
let root: Root;

function render(ui: React.ReactElement) {
  container = document.createElement('div');
  document.body.appendChild(container);
  act(() => {
    root = createRoot(container);
    root.render(ui);
  });
}

function unmount() {
  act(() => {
    root.unmount();
  });
  container.remove();
}

describe('PageContext.updatePageSeo', () => {
  test('sets seo on a page that previously had none', async () => {
    let ctx: ReturnType<typeof usePages> | null = null;
    const Consumer: React.FC = () => {
      ctx = usePages();
      return null;
    };

    render(
      <PageProvider>
        <Consumer />
      </PageProvider>,
    );

    expect(ctx!.pages[0].seo).toBeUndefined();

    act(() => {
      ctx!.updatePageSeo(ctx!.pages[0].id, { metaTitle: 'Hello World', noindex: true });
    });

    expect(ctx!.pages[0].seo).toEqual({ metaTitle: 'Hello World', noindex: true });

    unmount();
  });

  test('merges new fields onto existing seo without clobbering untouched fields', async () => {
    let ctx: ReturnType<typeof usePages> | null = null;
    const Consumer: React.FC = () => {
      ctx = usePages();
      return null;
    };

    render(
      <PageProvider>
        <Consumer />
      </PageProvider>,
    );

    act(() => {
      ctx!.updatePageSeo(ctx!.pages[0].id, { metaTitle: 'First', metaDescription: 'Desc' });
    });
    act(() => {
      ctx!.updatePageSeo(ctx!.pages[0].id, { metaTitle: 'Second' });
    });

    expect(ctx!.pages[0].seo).toEqual({ metaTitle: 'Second', metaDescription: 'Desc' });

    unmount();
  });

  test('only touches the targeted page, leaving other pages untouched', async () => {
    let ctx: ReturnType<typeof usePages> | null = null;
    const Consumer: React.FC = () => {
      ctx = usePages();
      return null;
    };

    render(
      <PageProvider>
        <Consumer />
      </PageProvider>,
    );

    act(() => {
      ctx!.addPage('About', 'about');
    });

    const homeId = ctx!.pages[0].id;
    const aboutId = ctx!.pages[1].id;

    act(() => {
      ctx!.updatePageSeo(aboutId, { metaTitle: 'About Us' });
    });

    expect(ctx!.pages.find((p) => p.id === aboutId)?.seo).toEqual({ metaTitle: 'About Us' });
    expect(ctx!.pages.find((p) => p.id === homeId)?.seo).toBeUndefined();

    unmount();
  });
});
