import {
  Dispatch,
  SetStateAction,
  memo,
  useCallback,
  useEffect,
  useState,
} from 'react';

import { useContextSelector } from '@/hooks/useContextSelector';
import {
  AudioFileIcon,
  EditIcon,
  MoreHorizontalIcon,
  MoreVerticalIcon,
  PlusIcon,
  ShareArrowIcon,
} from '@/icons';
import logWebUserEvent from '@/logging/logWebUserEvent';
import { SMALL_IMAGE } from '@/utils/constants';

import Button, { ButtonShape, ButtonVariant } from '../button/Button';
import {
  ContextMenuItem,
  ContextMenuTrigger,
} from '../contextMenu/ContextMenu';
import ImageWithFallback from '../image/ImageWithFallback';
import StudioContext from './StudioContext';
import { StudioProjectManagementContext } from './StudioProjectManagementContext';
import StudioShareProjectModal from './StudioShareProjectModal';
import getStudioProjectAura from './getStudioProjectAura';

export default memo(function ProjectNameButton({
  setVersionsVisible,
  setProjectsModalOpen,
}: {
  setVersionsVisible: Dispatch<SetStateAction<boolean>>;
  setProjectsModalOpen: Dispatch<SetStateAction<boolean>>;
}) {
  const stateRef = useContextSelector(
    StudioContext,
    (context) => context.stateRef
  );

  const saveProject = useContextSelector(
    StudioProjectManagementContext,
    (context) => context.saveProject
  );

  const projectTitle = useContextSelector(
    StudioProjectManagementContext,
    (context) => context.loadedProject?.title || 'Untitled Project'
  );
  const setProjectTitle = useCallback(
    (title: string) => {
      saveProject(stateRef.current, title);
    },
    [saveProject, stateRef]
  );
  const createAndLoadNewStudioProject = useContextSelector(
    StudioProjectManagementContext,
    (context) => context.createAndLoadNewStudioProject
  );
  const studioProjectId = useContextSelector(
    StudioContext,
    (context) => context.studioProjectId
  );

  const latestVersionId = useContextSelector(
    StudioProjectManagementContext,
    (context) => context.latestVersionId
  );

  const [isEditingTitle, setIsEditingTitle] = useState(false);
  const [localTitle, setLocalTitle] = useState(projectTitle);
  useEffect(() => {
    setLocalTitle(projectTitle);
  }, [projectTitle]);
  const [shareProjectModalOpen, setShareProjectModalOpen] = useState(false);

  const handleOpenVersions = useCallback(() => {
    // Save current state before opening versions panel
    const currentState = stateRef.current;

    // Save the current project
    saveProject(currentState, projectTitle);

    setVersionsVisible(true);
  }, [saveProject, projectTitle, stateRef]);

  return (
    <>
      {isEditingTitle ? (
        <input
          type='text'
          autoFocus
          value={localTitle}
          onChange={(e) => setLocalTitle(e.target.value)}
          onBlur={() => {
            setIsEditingTitle(false);
            setProjectTitle(localTitle);
          }}
          onKeyDown={(e) => {
            if (e.key === 'Enter') {
              setIsEditingTitle(false);
              setProjectTitle(localTitle);
            } else if (e.key === 'Escape') {
              setLocalTitle(projectTitle);
              setIsEditingTitle(false);
            }
          }}
        />
      ) : (
        <ContextMenuTrigger
          placement='bottom-right'
          ButtonComponent={(props) => (
            <Button
              {...props}
              icon={MoreHorizontalIcon}
              shape={ButtonShape.Pill}
              variant={ButtonVariant.Secondary}
              className='whitespace-nowrap'
            >
              <ImageWithFallback
                className='h-[22px] w-[22px] rounded-full'
                src={getStudioProjectAura(studioProjectId)}
                alt='Studio Project Image'
                imageSize={SMALL_IMAGE}
                loading='lazy'
              />
              {localTitle}
            </Button>
          )}
          ContentsComponent={() => (
            <>
              <ContextMenuItem
                onClick={() => setProjectsModalOpen(true)}
                icon={AudioFileIcon}
              >
                Open Project
              </ContextMenuItem>
              <ContextMenuItem
                onClick={async () => {
                  const project = await createAndLoadNewStudioProject();
                  if (project?.id) {
                    logWebUserEvent({
                      actionName: 'CreatedNewStudioProject',
                      context: {
                        studioProjectId: project.id,
                        trigger: 'project_name_button_menu',
                      },
                    });
                  }
                }}
                icon={PlusIcon}
              >
                New Project
              </ContextMenuItem>
              <ContextMenuItem
                onClick={() => setIsEditingTitle(true)}
                icon={EditIcon}
              >
                Rename
              </ContextMenuItem>
              <ContextMenuItem
                onClick={handleOpenVersions}
                icon={MoreVerticalIcon}
              >
                Versions
              </ContextMenuItem>
              <ContextMenuItem
                onClick={() => setShareProjectModalOpen(true)}
                icon={ShareArrowIcon}
              >
                Share Project
              </ContextMenuItem>
            </>
          )}
        />
      )}

      <StudioShareProjectModal
        isOpen={shareProjectModalOpen}
        onClose={() => setShareProjectModalOpen(false)}
        projectTitle={localTitle}
        projectId={studioProjectId || ''}
        onProjectTitleChange={(title) => {
          setLocalTitle(title);
          setProjectTitle(title);
        }}
        latestVersionId={latestVersionId}
      />
    </>
  );
});
