'use client';

import React from 'react';
import { useCallback, useEffect } from 'react';
import { useMobileIframeHandler } from '../hooks';
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import {
  setComponents,
  setDataSources,
  setDesignMode,
  setDraggingActive,
  setPlaceholders,
  setResponsive,
  setSelectedComponentId,
  setSelectedPlaceholder,
  setSelectedWidget
} from '../redux/reducers/widget';
import { LoggerPopup } from './logger-popup';
import { LoggerProvider } from '../hooks/use-logger-context';
import { ToastContainer } from './toast';
import * as Sentry from '@sentry/nextjs';
import { initSentry } from '../sentry';

export default function ClientRoot({
  children,
  sessionId
}: {
  children: React.ReactNode;
  sessionId?: string;
}) {
  const { preventPageRender } = useMobileIframeHandler({
    sessionId: sessionId || ''
  });
  const { components } = useAppSelector((state) => state.widget);
  const dispatch = useAppDispatch();

  const postMessage = (message: {
    type: string;
    data: Record<string, unknown>;
  }) => {
    window.parent.postMessage(message, '*');
  };

  const handleWidgetMessage = useCallback(
    (event: MessageEvent) => {
      if (event.data.type === 'UPDATE_COMPONENTS') {
        const { components } = event.data.data;

        dispatch(setComponents(components));
      } else if (event.data.type === 'UPDATE_WIDGET_SYSTEM') {
        const {
          responsive,
          designMode,
          selectedComponentId,
          placeholders,
          dataSources
        } = event.data.data;

        dispatch(setResponsive(responsive));
        dispatch(setDesignMode(designMode));
        dispatch(setSelectedComponentId(selectedComponentId));
        dispatch(setPlaceholders(placeholders));
        dispatch(setDataSources(dataSources));
      } else if (event.data.type === 'SELECT_PLACEHOLDER') {
        const { placeholderSlug } = event.data.data;

        dispatch(setSelectedPlaceholder(placeholderSlug));
      } else if (event.data.type === 'SELECT_WIDGET') {
        const { widgetSlug } = event.data.data;

        dispatch(setSelectedWidget(widgetSlug));

        postMessage({
          type: 'SELECT_COMPONENT',
          data: {
            componentId: null
          }
        });
      } else if (event.data.type === 'DRAG_START') {
        dispatch(setDraggingActive(true));
      } else if (event.data.type === 'DRAG_END') {
        dispatch(setDraggingActive(false));
      } else if (event.data.type === 'GET_DROP_TARGET') {
        const { x, y, component } = event.data.data;
        const elements = document.elementsFromPoint(x, y);
        const dropTargetId = elements
          .find((element) => element.hasAttribute('data-component'))
          ?.getAttribute('data-id');

        postMessage({
          type: 'DROP_TARGET_RESPONSE',
          data: {
            targetId: dropTargetId,
            component
          }
        });
      } else if (event.data.type === 'SET_COOKIE') {
        const { key, value } = event.data.data.value;

        if (key && value) {
          let cookieString = '';
          if (window.parent !== window) {
            cookieString = `${key}=${value}; path=/; SameSite=None; Secure`;
          } else if (key === 'widget_builder') {
            cookieString = `${key}=false; path=/; SameSite=None; Secure`;
          }

          if (cookieString) {
            document.cookie = cookieString;
          }
        }
      }
    },
    [dispatch, components]
  );

  useEffect(() => {
    window.addEventListener('message', handleWidgetMessage);

    if (window.parent === window) {
      document.cookie = 'widget_builder=false; path=/; SameSite=None; Secure';
    }

    return () => {
      window.removeEventListener('message', handleWidgetMessage);
    };
  }, [handleWidgetMessage]);

  const initializeSentry = async () => {
    const response = await fetch('/api/sentry', { next: { revalidate: 0 } });
    const data = await response.json();

    const options = {
      dsn: data.dsn
    };

    initSentry('Client', options);
  };

  useEffect(() => {
    if (!Sentry.isInitialized()) {
      initializeSentry();
    }
  }, []);

  if (preventPageRender) {
    return null;
  }

  return (
    <LoggerProvider>
      {children}
      <LoggerPopup />
      <ToastContainer />
    </LoggerProvider>
  );
}
