import { FIND_ONE_PAGE_LAYOUT } from '@/dashboards/graphql/queries/findOnePageLayout';
import { DEFAULT_COMPANY_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultCompanyRecordPageLayout';
import { DEFAULT_COMPANY_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultCompanyRecordPageLayoutId';
import { DEFAULT_NOTE_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultNoteRecordPageLayout';
import { DEFAULT_NOTE_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultNoteRecordPageLayoutId';
import { DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultOpportunityRecordPageLayout';
import { DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultOpportunityRecordPageLayoutId';
import { DEFAULT_PERSON_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultPersonRecordPageLayout';
import { DEFAULT_PERSON_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultPersonRecordPageLayoutId';
import { DEFAULT_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultRecordPageLayout';
import { DEFAULT_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultRecordPageLayoutId';
import { DEFAULT_TASK_RECORD_PAGE_LAYOUT } from '@/page-layout/constants/DefaultTaskRecordPageLayout';
import { DEFAULT_TASK_RECORD_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultTaskRecordPageLayoutId';
import { DEFAULT_WORKFLOW_PAGE_LAYOUT } from '@/page-layout/constants/DefaultWorkflowPageLayout';
import { DEFAULT_WORKFLOW_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultWorkflowPageLayoutId';
import { DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT } from '@/page-layout/constants/DefaultWorkflowRunPageLayout';
import { DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultWorkflowRunPageLayoutId';
import { DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT } from '@/page-layout/constants/DefaultWorkflowVersionPageLayout';
import { DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT_ID } from '@/page-layout/constants/DefaultWorkflowVersionPageLayoutId';
import { usePageLayoutWithRelationWidgets } from '@/page-layout/hooks/usePageLayoutWithRelationWidgets';
import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState';
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
import { pageLayoutIsInitializedComponentState } from '@/page-layout/states/pageLayoutIsInitializedComponentState';
import { pageLayoutPersistedComponentState } from '@/page-layout/states/pageLayoutPersistedComponentState';
import { type PageLayout } from '@/page-layout/types/PageLayout';
import { convertPageLayoutToTabLayouts } from '@/page-layout/utils/convertPageLayoutToTabLayouts';
import { transformPageLayout } from '@/page-layout/utils/transformPageLayout';
import { useRecoilComponentCallbackState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackState';
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useQuery } from '@apollo/client';
import { useEffect } from 'react';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';

const getDefaultLayoutById = (layoutId: string): PageLayout => {
  switch (layoutId) {
    case DEFAULT_COMPANY_RECORD_PAGE_LAYOUT_ID:
      return DEFAULT_COMPANY_RECORD_PAGE_LAYOUT;
    case DEFAULT_PERSON_RECORD_PAGE_LAYOUT_ID:
      return DEFAULT_PERSON_RECORD_PAGE_LAYOUT;
    case DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT_ID:
      return DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT;
    case DEFAULT_NOTE_RECORD_PAGE_LAYOUT_ID:
      return DEFAULT_NOTE_RECORD_PAGE_LAYOUT;
    case DEFAULT_TASK_RECORD_PAGE_LAYOUT_ID:
      return DEFAULT_TASK_RECORD_PAGE_LAYOUT;
    case DEFAULT_WORKFLOW_PAGE_LAYOUT_ID:
      return DEFAULT_WORKFLOW_PAGE_LAYOUT;
    case DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT_ID:
      return DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT;
    case DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT_ID:
      return DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT;
    case DEFAULT_RECORD_PAGE_LAYOUT_ID:
    default:
      return DEFAULT_RECORD_PAGE_LAYOUT;
  }
};

type PageLayoutInitializationQueryEffectProps = {
  pageLayoutId: string;
  onInitialized?: (pageLayout: PageLayout) => void;
};

export const PageLayoutInitializationQueryEffect = ({
  pageLayoutId,
  onInitialized,
}: PageLayoutInitializationQueryEffectProps) => {
  const [isInitialized, setIsInitialized] = useRecoilComponentState(
    pageLayoutIsInitializedComponentState,
  );

  const isDefaultLayout =
    pageLayoutId === DEFAULT_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_COMPANY_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_PERSON_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_OPPORTUNITY_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_NOTE_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_TASK_RECORD_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_WORKFLOW_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_WORKFLOW_VERSION_PAGE_LAYOUT_ID ||
    pageLayoutId === DEFAULT_WORKFLOW_RUN_PAGE_LAYOUT_ID;

  const { data } = useQuery(FIND_ONE_PAGE_LAYOUT, {
    variables: {
      id: pageLayoutId,
    },
    skip: isDefaultLayout,
  });

  const basePageLayout: PageLayout | undefined = isDefaultLayout
    ? getDefaultLayoutById(pageLayoutId)
    : data?.getPageLayout
      ? transformPageLayout(data.getPageLayout)
      : undefined;

  const pageLayout = usePageLayoutWithRelationWidgets(basePageLayout);

  const pageLayoutPersistedComponentCallbackState =
    useRecoilComponentCallbackState(pageLayoutPersistedComponentState);

  const pageLayoutDraftComponentCallbackState = useRecoilComponentCallbackState(
    pageLayoutDraftComponentState,
  );

  const pageLayoutCurrentLayoutsComponentCallbackState =
    useRecoilComponentCallbackState(pageLayoutCurrentLayoutsComponentState);

  const initializePageLayout = useRecoilCallback(
    ({ set, snapshot }) =>
      (layout: PageLayout) => {
        const currentPersisted = getSnapshotValue(
          snapshot,
          pageLayoutPersistedComponentCallbackState,
        );

        if (!isDeeplyEqual(layout, currentPersisted)) {
          set(pageLayoutPersistedComponentCallbackState, layout);
          set(pageLayoutDraftComponentCallbackState, {
            id: layout.id,
            name: layout.name,
            type: layout.type,
            objectMetadataId: layout.objectMetadataId,
            tabs: layout.tabs,
          });

          const tabLayouts = convertPageLayoutToTabLayouts(layout);
          set(pageLayoutCurrentLayoutsComponentCallbackState, tabLayouts);
        }
      },
    [
      pageLayoutCurrentLayoutsComponentCallbackState,
      pageLayoutDraftComponentCallbackState,
      pageLayoutPersistedComponentCallbackState,
    ],
  );

  useEffect(() => {
    if (!isInitialized && isDefined(pageLayout)) {
      initializePageLayout(pageLayout);
      onInitialized?.(pageLayout);
      setIsInitialized(true);
    }
  }, [
    initializePageLayout,
    isInitialized,
    pageLayout,
    onInitialized,
    setIsInitialized,
  ]);

  return null;
};
