import { useAuth } from '@clerk/nextjs';
import { observer } from 'mobx-react-lite';
import { usePathname } from 'next/navigation';
import { Suspense, lazy } from 'react';

import { useStores } from '@/app/(root)/AppProviders';
import AddToProjectModal from '@/components/modal/AddToProjectModal';
import ConfirmationModalV2 from '@/components/modal/ConfirmationModalV2';
import CopyrightInfringementWarningModal from '@/components/modal/CopyrightInfringementWarningModal';
import CreatePersonaModal from '@/components/modal/CreatePersonaModal';
import CrowModal from '@/components/modal/CrowModal';
import LazyLoadedModal, {
  ModalLoadingFallback,
} from '@/components/modal/LazyLoadedModal';
import RemixPermissionModal from '@/components/modal/RemixPermissionModal';
import { ModalTypes } from '@/components/modal/constants/ModalTypes';
import UpsellCardModal from '@/components/modal/upsell-cards/UpsellCardModal';
import { useModalContext } from '@/context/ModalContext';
import ModalErrorBoundary from '@/error-boundaries/ModalErrorBoundary';
import { useUsagePlanDescriptionsResponse } from '@/hooks/usePricing';
import { FeatureKey, UsagePlanSchema } from '@/state/sessionStore';
import { DEFAULT_PROJECT_ID, ROUTES } from '@/utils/constants';

const AddToPlaylistModal = lazy(
  () => import('@/components/modal/AddToPlaylistModal')
);
const ConfirmationModal = lazy(
  () => import('@/components/modal/ConfirmationModal')
);

const CommercialRightsModal = lazy(
  () => import('@/components/modal/CommercialRightsModal')
);
const DownloadSuccessModal = lazy(
  () => import('@/components/modal/DownloadSuccessModal')
);
const CreateHookModal = lazy(
  () => import('@/app/(root)/hooks/create/CreateHookModal')
);
const EditHookMetadataModal = lazy(
  () => import('@/app/(root)/hooks/edit/EditHookMetadataModal')
);
const FeedbackForm = lazy(() => import('@/components/sidebar/FeedbackForm'));
const DeleteClipModal = lazy(
  () => import('@/components/modal/DeleteClipModal')
);

const OmniplayerModal = lazy(
  () => import('@/components/omniplayer/OmniplayerModal')
);
const InviteFriendModal = lazy(
  () => import('@/components/modal/InviteFriendModal')
);
const StemsModal = lazy(() => import('@/app/(root)/stems/StemsModal'));
const PublishSongModal = lazy(
  () => import('@/components/modal/PublishSongModal')
);
const FlagModal = lazy(() => import('@/components/modal/FlagModal'));
const CopyrightFlagModal = lazy(
  () => import('@/components/modal/CopyrightFlagModal')
);
const ShareModal = lazy(() => import('@/components/modal/ShareModal'));
const ShareWithFriendsModal = lazy(
  () => import('@/components/modal/ShareWithFriendsModal')
);
const ClipJsonModal = lazy(() => import('@/components/modal/ClipJsonModal'));

const LibrarySelectModal = lazy(
  () => import('@/components/modal/LibrarySelectModal')
);
const ClipFeedbackModal = lazy(
  () => import('@/components/modal/ClipFeedbackModal')
);
const SongQueueModal = lazy(() => import('@/components/modal/SongQueueModal'));
const DownloadWavModal = lazy(
  () => import('@/components/modal/DownloadWavModal')
);
const DownloadShareAssetModal = lazy(
  () => import('@/components/modal/DownloadShareAssetModal')
);

const UpsampleModelSelectModal = lazy(
  () => import('@/components/modal/UpsampleModelSelectModal')
);
const RemasterModal = lazy(() => import('@/components/modal/RemasterModal'));
const UnpublishSongModal = lazy(
  () => import('@/components/modal/UnpublishSongModal')
);
const CreditsPurchaseModal = lazy(
  () => import('@/components/modal/CreditsPurchaseModal')
);
const RenewSubscriptionModal = lazy(
  () => import('@/components/modal/RenewSubscriptionModal')
);
const CancelChangesModal = lazy(
  () => import('@/components/modal/CancelChangesModal')
);
const MarketplaceCreateProjectModal = lazy(
  () => import('@/components/marketplace/modal/MarketplaceCreateProjectModal')
);
const MarketplaceUploadMediaModal = lazy(
  () => import('@/components/marketplace/modal/MarketplaceUploadMediaModal')
);
const ParticipantReviewsModal = lazy(
  () => import('@/components/marketplace/project/ParticipantReviewsModal')
);
const MarketplaceEditListingModal = lazy(
  () => import('@/components/marketplace/modal/MarketplaceEditListingModal')
);
const GenerateCoverArtModal = lazy(
  () => import('@/components/modal/GenerateCoverArtModal')
);
const JoinSunoModal = lazy(() => import('@/components/modal/JoinSunoModal'));

export const AppModals = observer(() => {
  const { session, menus, project } = useStores();
  const { closeModal, isModalOpen } = useModalContext();
  const pathname = usePathname();
  const { isSignedIn } = useAuth();

  const proPlan = session.isSubLoaded
    ? session.sub.plans?.find(
        (plan: UsagePlanSchema) => plan.plan_key === 'pro'
      )
    : null;
  const premierPlan = session.isSubLoaded
    ? session.sub.plans?.find(
        (plan: UsagePlanSchema) => plan.plan_key === 'premier'
      )
    : null;

  let plans = [];
  if (proPlan) {
    plans.push(proPlan);
  }
  if (premierPlan) {
    plans.push(premierPlan);
  }

  const { data: descriptionsResponse } = useUsagePlanDescriptionsResponse();
  const usagePlanDescriptions = descriptionsResponse?.usage_plan_descriptions;

  return (
    <>
      {/* TODO: modals below need to be refactored & potentially lazy loaded. Lazy load all new modals!! */}
      <AddToProjectModal
        isOpen={isModalOpen(ModalTypes.ADD_TO_PROJECT)}
        onClose={() => closeModal(ModalTypes.ADD_TO_PROJECT)}
        isInCreate={!!pathname?.startsWith(ROUTES.CREATE)}
        onProjectClick={(clips, targetProjectId) => {
          const isInCreate = !!pathname?.startsWith(ROUTES.CREATE);
          const sourceProjectId = isInCreate
            ? project.currentProjectId
            : DEFAULT_PROJECT_ID;
          if (sourceProjectId === DEFAULT_PROJECT_ID && isInCreate) {
            project.addClipsToProject(clips, targetProjectId, false);
          } else {
            project.moveClipsToProject(
              clips,
              targetProjectId,
              sourceProjectId,
              isInCreate
            );
          }
          menus.setSelected(new Set([]));
        }}
      />
      {isModalOpen(ModalTypes.CREATE_PERSONA) ? (
        <CreatePersonaModal
          isOpen={isModalOpen(ModalTypes.CREATE_PERSONA)}
          onClose={() => closeModal(ModalTypes.CREATE_PERSONA)}
          initialClip={menus.currentClip || undefined}
        />
      ) : null}

      {!!menus.confirmationModalOptions?.onConfirmFn ? (
        <ConfirmationModalV2
          isOpen={isModalOpen(ModalTypes.GENERIC_CONFIRM)}
          onClose={() => {
            closeModal(ModalTypes.GENERIC_CONFIRM);
            menus.confirmationModalOptions?.onCloseFn?.();
          }}
          onConfirm={menus.confirmationModalOptions?.onConfirmFn}
          onAction={menus.confirmationModalOptions?.onActionFn}
          title={menus.confirmationModalOptions?.title}
          icon={menus.confirmationModalOptions?.icon}
          renderMessage={
            menus.confirmationModalOptions?.renderMessage || undefined
          }
          confirmButtonText={menus.confirmationModalOptions?.confirmButtonText}
          actionButtonText={menus.confirmationModalOptions?.actionButtonText}
          actionButtonClassName={
            menus.confirmationModalOptions?.actionButtonClassName
          }
        />
      ) : null}
      {session.sessionIsLoaded &&
        session.userConfigIsLoaded &&
        isSignedIn &&
        !session.hasSetRemixPerm &&
        !session.roles?.['is_day_zero_user'] && (
          <RemixPermissionModal
            isOpen={isModalOpen(ModalTypes.REMIX_PERMISSION)}
            onClose={() => closeModal(ModalTypes.REMIX_PERMISSION)}
          />
        )}
      <CopyrightInfringementWarningModal
        isOpen={isModalOpen(ModalTypes.COPYRIGHT_WARNING)}
        onClose={() => closeModal(ModalTypes.COPYRIGHT_WARNING)}
        clipId={menus.currentClip?.id || ''}
      />
      {isModalOpen(ModalTypes.DOWNLOAD_QUOTA) && (
        <Suspense fallback={<ModalLoadingFallback />}>
          <CommercialRightsModal
            onClose={() => {
              closeModal(ModalTypes.DOWNLOAD_QUOTA);
              menus.clearDownloadQuotaModalOptions();
            }}
            clipId={menus.downloadQuotaModalOptions?.clipId || ''}
            onDownload={
              menus.downloadQuotaModalOptions?.onDownload || (() => {})
            }
          />
        </Suspense>
      )}
      {isModalOpen(ModalTypes.COMMERCIAL_RIGHTS_SUCCESS) && (
        <Suspense fallback={<ModalLoadingFallback />}>
          <DownloadSuccessModal
            onClose={() => {
              closeModal(ModalTypes.COMMERCIAL_RIGHTS_SUCCESS);
              menus.clearDownloadSuccessModalOptions();
            }}
            title='Rights purchased'
            songTitle={menus.downloadSuccessModalOptions?.songTitle}
            message={menus.downloadSuccessModalOptions?.message}
            subMessage={menus.downloadSuccessModalOptions?.subMessage}
            onDownload={
              menus.downloadSuccessModalOptions?.onDownload || (() => {})
            }
          />
        </Suspense>
      )}
      {isModalOpen(ModalTypes.SUBSCRIPTION_SUCCESS) && (
        <Suspense fallback={<ModalLoadingFallback />}>
          <DownloadSuccessModal
            onClose={() => {
              closeModal(ModalTypes.SUBSCRIPTION_SUCCESS);
              menus.clearDownloadSuccessModalOptions();
            }}
            title='Successfully subscribed'
            songTitle={menus.downloadSuccessModalOptions?.songTitle}
            message={menus.downloadSuccessModalOptions?.message}
            subMessage={menus.downloadSuccessModalOptions?.subMessage}
            onDownload={
              menus.downloadSuccessModalOptions?.onDownload || (() => {})
            }
          />
        </Suspense>
      )}
      <UpsellCardModal
        isOpen={isModalOpen(ModalTypes.UPSELL_MODAL)}
        onClose={() => closeModal(ModalTypes.UPSELL_MODAL)}
        features={menus.featureUpsellConfig || {}}
        currentUpsellFeature={menus.currentUpsellFeature || FeatureKey.PERSONAS}
        currentSubscription={session.sub}
        usagePlanDescriptions={usagePlanDescriptions || {}}
        plans={plans}
      />
      <CrowModal />
      {/* Start of lazy loaded modals */}
      <ModalErrorBoundary>
        <LazyLoadedModal
          modalType={ModalTypes.SELECT_HOOK_SONG}
          Component={CreateHookModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.EDIT_HOOK_METADATA}
          Component={EditHookMetadataModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.FEEDBACK_FORM}
          Component={FeedbackForm}
          onClose={() => closeModal(ModalTypes.FEEDBACK_FORM)}
        />
        <LazyLoadedModal
          modalType={ModalTypes.OMNIPLAYER}
          Component={OmniplayerModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.INVITE_FRIEND}
          Component={InviteFriendModal}
        />
        <LazyLoadedModal modalType={ModalTypes.STEMS} Component={StemsModal} />
        <LazyLoadedModal
          modalType={ModalTypes.DELETE_CLIP}
          Component={DeleteClipModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.ADD_TO_PLAYLIST}
          Component={AddToPlaylistModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.UPDATE_CLIP_METADATA}
          Component={PublishSongModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.PUBLISH_SONG}
          Component={PublishSongModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.FLAG_CLIP}
          Component={FlagModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.COPYRIGHT_FLAG}
          Component={CopyrightFlagModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.CLIP_FEEDBACK}
          Component={ClipFeedbackModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.SHARE_CLIP}
          Component={ShareModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.SHARE_WITH_FRIENDS}
          Component={ShareWithFriendsModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.CLIP_JSON}
          Component={ClipJsonModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.DOWNLOAD_FILE}
          Component={DownloadWavModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.DOWNLOAD_SHARE_ASSET}
          Component={DownloadShareAssetModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.UPSAMPLE_MODEL_SELECT}
          Component={UpsampleModelSelectModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.REMASTER_MODAL}
          Component={RemasterModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.CONFIRM_PIN_REPLACEMENT}
          Component={ConfirmationModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.SONG_QUEUE}
          Component={SongQueueModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.UNPUBLISH_SONG}
          Component={UnpublishSongModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.LIBRARY_SELECT}
          Component={LibrarySelectModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.CREDITS_PURCHASE}
          Component={CreditsPurchaseModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.RENEW_SUBSCRIPTION}
          Component={RenewSubscriptionModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.CANCEL_SUBSCRIPTION_CHANGES}
          Component={CancelChangesModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.MARKETPLACE_CREATE_PROJECT}
          Component={MarketplaceCreateProjectModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.MARKETPLACE_UPLOAD_MEDIA}
          Component={MarketplaceUploadMediaModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.MARKETPLACE_PARTICIPANT_REVIEWS}
          Component={ParticipantReviewsModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.MARKETPLACE_EDIT_LISTING}
          Component={MarketplaceEditListingModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.GENERATE_COVER_ART}
          Component={GenerateCoverArtModal}
        />
        <LazyLoadedModal
          modalType={ModalTypes.JOIN_SUNO}
          Component={JoinSunoModal}
        />
      </ModalErrorBoundary>
    </>
  );
});

export default AppModals;
