import { cloneDeep } from 'lodash';
import { describe, test, expect } from 'vitest';

import type { WidgetProps6, WidgetProps7 } from '../../../types/index.js';
import containerV4 from '../../../utils/pageFixtures/v4/container.js';
import { migrate4to5 } from '../v4to5.js';
import { migrate5to6 } from '../v5to6.js';
import { migrateToDimensions } from './migrateToDimensions.js';
import { migrateToSections } from './migrateToSections.js';

describe('version 7 to version 8', () => {
  test('should migrate a page with a container widget', () => {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const v7 = migrateToSections(migrate5to6(migrate4to5(cloneDeep(containerV4 as any))));
    const v8 = migrateToDimensions(cloneDeep(v7));

    // What are we testing?
    // Check that each Widget that is a child has a left, top, width, height
    // Check that each CanvasWidget has a layoutType, gridColumn
    // Check that minHeight has been migrated to a Dimension object of type 'gridUnit'
    // Check that snapColumns, snapRows have been migrated to gridColumns and don't exist anymore
    // Do this for all children recursively

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const checkWidget = (parent: any, old: any) => {
      if (parent.children) {
        parent.children.forEach((child: WidgetProps7) => {
          const children = child.children;

          const oldChild = old.children.find((c: WidgetProps6) => c.widgetId === child.widgetId) as WidgetProps6;

          // Use the following to debug to see what is being compared
          // console.log(child, oldChild);

          if (child.type === 'CANVAS_WIDGET') {
            expect(child).toHaveProperty('layout');
            expect(child).toHaveProperty('gridColumns');
          }

          if (parent.type === 'CANVAS_WIDGET' && parent.layout === 'FIXED_GRID') {
            expect(child).toHaveProperty('left');
            expect(child).toHaveProperty('top');
            expect(child).toHaveProperty('width');
            expect(child).toHaveProperty('height');

            // Assert minHeight has been migrated to a Dimension object of type 'gridUnit'
            if (child.minHeight) {
              expect(child.minHeight).toHaveProperty('mode');
              expect(child.minHeight.mode).toEqual('gridUnit');
            }

            // assert CONTAINERS
            if (parent.type === 'CONTAINER_WIDGET' || parent.type === 'FORM_WIDGET' || parent.type === 'TABS_WIDGET') {
              expect(child).toHaveProperty('padding');
              expect(child.padding?.left?.value).toEqual(16);
              expect(child.padding?.top?.value).toEqual(12);
              expect(child.padding?.right?.value).toEqual(16);
              expect(child.padding?.bottom?.value).toEqual(12);
            } else {
              // there should be no padding
              expect(child).not.toHaveProperty('padding');
            }

            // Assert left, top, width, height === old values
            expect(child.left.value).toEqual(oldChild.leftColumn);
            expect(child.left.value + child.width.value).toEqual(oldChild.rightColumn);
            expect(child.top.value).toEqual(oldChild.topRow);
            expect(child.top.value + child.height.value).toEqual(oldChild.bottomRow);
          }

          expect(child).not.toHaveProperty('snapColumns');
          expect(child).not.toHaveProperty('snapRows');
          expect(child).not.toHaveProperty('leftColumn');
          expect(child).not.toHaveProperty('rightColumn');
          expect(child).not.toHaveProperty('topRow');
          expect(child).not.toHaveProperty('bottomRow');
          expect(child).not.toHaveProperty('widgetLastChange');

          checkWidget(
            { ...child, children },
            old.children.find((c: { widgetId: string }) => c.widgetId === child.widgetId)
          );
        });
      }
    };
    checkWidget({ children: [v8] }, { children: [v7] });
  });
});
