import React, { Suspense, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import classNames from 'clsx';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';

import { PCN_GET_MANAGE_WATCH, PCN_GET_PLAYLIST } from '@/modules/@common/acl/constants';
import {
  MODULE_CHAPTERS,
  MODULE_DESCRIPTION,
  MODULE_HIGHLIGHTS,
  MODULE_SLIDES,
  MODULE_TAGLOG,
  MODULE_THUMBNAIL,
  MODULE_TRANSLATIONS,
} from '@/modules/editorial/aiWorkbench/AiWorkbench/constants';
import { DND_DRAG_OVERLAY_ID, DND_MAIN_LIST_OF_VIDEO_TYPE } from '@/modules/editorial/constants/dnd';
import {
  QUERY_PARAM_CHANNEL,
  QUERY_PARAM_PLAYLIST,
  QUERY_PARAM_PLAYLIST_EDIT,
  QUERY_PARAM_WATCH_ID,
} from '@/modules/editorial/constants/routing';
import { MODE_LIST } from '@/modules/editorial/RightSideBar/common/constants';
import { QUERY_NEW_PLAYLIST_PARAM } from '@/modules/editorial/RightSideBar/TabPlaylist/Edit/constants';

import { dragAndDropEndAction, playlistModeAction } from '../editorialSearchResults/redux/slices';
import { getIsWordpressMode, getIsWPVideoMode } from '@/modules/@common/app/helpers';
import { hasPermission } from '@/modules/@common/user/helpers';
import { getUserPermissionsSelector } from '@/modules/@common/user/redux/selectors';
import { parseDndId } from '@/modules/editorial/helpers/createDndId';
import { getPlaylistsAction, setModeAction } from '@/modules/editorial/RightSideBar/TabPlaylist/redux/slices';
import { openChannelAction } from '@/modules/editorial/RightSideBar/TabWatch/Watches/redux/slices';
import { isMobileApp } from '@/modules/layout/helpers';
import { isOpenVideoVersionUploadSelector } from '@/modules/uploaderNew/redux/selectors';

import EditorialSearchModule from '@/modules/editorial/editorialSearch';
import EditorialSearchFilterModule from '@/modules/editorial/editorialSearchFilter/filterContainer';
import EditorialSearchResultsModule from '@/modules/editorial/editorialSearchResults';
import SideBar from '../RightSideBar';
import { Paper } from '@/mui/components';

import styles from './styles.module.scss';

const VideoVersionUpload = dynamic(
  () => import('@/modules/uploaderNew/components/VideoVersionUpload/VideoVersionUpload'),
  { ssr: false },
);
const PlaylistEdit = dynamic(() => import('@/modules/editorial/RightSideBar/TabPlaylist/Edit/components/CreateForm'), {
  ssr: false,
});
const WatchChannelEdit = dynamic(() => import('@/modules/editorial/RightSideBar/TabWatch/ChannelEdit/components'), {
  ssr: false,
});
const WatchEdit = dynamic(() => import('@/modules/editorial/RightSideBar/TabWatch/Edit/components'), { ssr: false });
const AiWorkbench = dynamic(() => import('@/modules/editorial/aiWorkbench/AiWorkbench/components/AiWorkbench'), {
  ssr: false,
});

const AI_WORKBENCH_MODULES = [
  MODULE_CHAPTERS,
  MODULE_HIGHLIGHTS,
  MODULE_SLIDES,
  MODULE_TRANSLATIONS,
  MODULE_DESCRIPTION,
  MODULE_TAGLOG,
  MODULE_THUMBNAIL,
];

function EditorialLayout() {
  const router = useRouter();
  const dispatch = useDispatch();

  const [showSideBar, setShowSideBar] = useState(!isMobileApp);
  const [isWPVideoMode, setIsWPVideoMode] = useState(false);
  const [isDragVideoOverlayActive, setIsDragVideoOverlayActive] = useState(false);

  const isOpenVideoVersionUpload = useSelector(isOpenVideoVersionUploadSelector);
  const userPermissions = useSelector(getUserPermissionsSelector);

  const sensors = useSensors(
    useSensor(PointerSensor, {
      activationConstraint: {
        distance: 1,
      },
    }),
  );

  const { aiworkbench, videoId } = router.query;

  const watchId = router.query[QUERY_PARAM_WATCH_ID];
  const channel = router.query[QUERY_PARAM_CHANNEL];
  const playlist = router.query[QUERY_PARAM_PLAYLIST];
  const playlistEdit = router.query[QUERY_PARAM_PLAYLIST_EDIT];

  const shouldShowAiWorkbench =
    aiworkbench !== undefined && videoId !== undefined && AI_WORKBENCH_MODULES.includes(aiworkbench);

  const toggleSideBar = () => {
    setShowSideBar(!showSideBar);
  };

  const handleDragStart = ({ active }) => {
    const metadata = parseDndId(active.id);
    if (metadata.type === DND_MAIN_LIST_OF_VIDEO_TYPE) {
      setIsDragVideoOverlayActive(true);
    }
  };

  const handleDragMove = ({ active }) => {
    const $dragOverlay = document.getElementById(DND_DRAG_OVERLAY_ID);

    if ($dragOverlay && !$dragOverlay.firstChild) {
      const { nodeId } = active.data.current;
      const $element = document.getElementById(nodeId);
      const $clone = $element.cloneNode(true);
      $dragOverlay.append($clone);
    }
  };

  const handleDragEnd = ({ active, over }) => {
    const metadata = parseDndId(active.id);
    if (metadata.type === DND_MAIN_LIST_OF_VIDEO_TYPE) {
      setIsDragVideoOverlayActive(false);
    }

    if (over?.id) {
      dispatch(
        dragAndDropEndAction({
          active: { id: active.id },
          over: { id: over.id },
        }),
      );
    }
  };

  useEffect(
    () => () => {
      dispatch(setModeAction(MODE_LIST));
      dispatch(getPlaylistsAction());

      dispatch(openChannelAction({ watchId: null, channelId: null }));
      dispatch(playlistModeAction(MODE_LIST));
      setIsWPVideoMode(getIsWPVideoMode());
    },
    [],
  );

  return (
    <DndContext sensors={sensors} onDragStart={handleDragStart} onDragEnd={handleDragEnd} onDragMove={handleDragMove}>
      <div
        className={classNames(styles.Editorial, {
          [styles.Editorial___withoutHeader]: getIsWordpressMode(),
        })}
        data-id="editorialContainer"
      >
        <div
          data-id="bodyContainer"
          className={classNames(styles.Main, {
            [styles.Main___show]: showSideBar && !isMobileApp,
            [styles.Main___fullWidth]:
              isMobileApp ||
              isWPVideoMode ||
              (!hasPermission(PCN_GET_MANAGE_WATCH, userPermissions) &&
                !hasPermission(PCN_GET_PLAYLIST, userPermissions)),
          })}
        >
          {(watchId || channel) && (
            <Paper className={styles.WatchForm}>{channel ? <WatchChannelEdit /> : <WatchEdit />}</Paper>
          )}

          {((playlist && playlist === QUERY_NEW_PLAYLIST_PARAM) ||
            (playlistEdit && !Number.isNaN(parseInt(playlistEdit, 10)))) && (
            <Paper className={styles.WatchForm}>
              <PlaylistEdit />
            </Paper>
          )}

          {isOpenVideoVersionUpload && <VideoVersionUpload />}

          {shouldShowAiWorkbench && (
            <Suspense fallback={<div />}>
              <AiWorkbench activeModule={aiworkbench} />
            </Suspense>
          )}

          <div data-id="searchContainer" className={styles.Search}>
            <EditorialSearchModule />
          </div>
          <div data-id="searchFilterContainer">
            <EditorialSearchFilterModule setShowSideBar={setShowSideBar} />
          </div>
          <EditorialSearchResultsModule
            isPlaylistSectionOpened={showSideBar}
            isDragVideoOverlayActive={isDragVideoOverlayActive}
          />
        </div>
        {(hasPermission(PCN_GET_PLAYLIST, userPermissions) || hasPermission(PCN_GET_MANAGE_WATCH, userPermissions)) && (
          <SideBar showSideBar={showSideBar} toggleSideBar={toggleSideBar} />
        )}
      </div>
    </DndContext>
  );
}

export default EditorialLayout;
