/* eslint jsx-a11y/click-events-have-key-events: warn */

/* eslint jsx-a11y/no-static-element-interactions: warn */
import { observer } from 'mobx-react-lite';
import { useEffect, useRef, useState } from 'react';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '@/components/button/Button';
import Modal from '@/components/modal/Modal';
import { useContextSelector } from '@/hooks/useContextSelector';
import { GenresIcon, MoreHorizontalIcon, TrashIcon } from '@/icons';
import { getRelativeTime } from '@/utils/utils';

import CreateFormContext from '../../v2/CreateFormContext';
import { CreateModes } from '../../v2/types';
import { DeleteSavedPromptModal } from '../modals/DeleteSavedPromptModal';

export enum PromptsType {
  Styles = 'styles',
  Lyrics = 'lyrics',
}

export const SavedPromptsModal = observer(
  ({
    promptsType,
    isOpen,
    onClose,
  }: {
    promptsType: PromptsType;
    isOpen: boolean;
    onClose: () => void;
  }) => {
    const { createV2 } = useStores();
    const setActiveModal = useContextSelector(
      CreateFormContext,
      (context) => context.setActiveModal
    );
    const [_styles, setStyles] = useContextSelector(
      CreateFormContext,
      (context) => context.selectState<string>([CreateModes.CUSTOM, 'styles'])
    );
    const loadNextPage = useContextSelector(CreateFormContext, (context) =>
      promptsType === PromptsType.Lyrics
        ? context.loadLyricsPromptsNextPage
        : context.loadTagsPromptsNextPage
    );
    const deletePromptFromCache = useContextSelector(
      CreateFormContext,
      (context) => context.deletePromptFromCache
    );
    const [_lyrics, setLyrics] = useContextSelector(
      CreateFormContext,
      (context) => context.selectState<string>([CreateModes.CUSTOM, 'lyrics'])
    );
    //const [localSearchText, setLocalSearchText] = useState('');
    const promptsForType = useContextSelector(CreateFormContext, (context) =>
      promptsType === PromptsType.Styles
        ? context.tagsPrompts
        : context.lyricsPrompts
    );
    const [shouldInfiniteLoad, setShouldInfiniteLoad] = useState(true);
    const [openMenuIndex, setOpenMenuIndex] = useState<number | null>(null);
    const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
    const menuRefs = useRef<{ [key: number]: HTMLDivElement | null }>({});
    const { ref: loaderRef } = useInView({
      threshold: 0,
      onChange: async (inView) => {
        if (inView && shouldInfiniteLoad) {
          const data = await loadNextPage();
          if (!data?.prompts?.length) {
            setShouldInfiniteLoad(false);
          }
        }
      },
    });

    // Close menu when clicking outside
    useEffect(() => {
      const handleClickOutside = (event: MouseEvent) => {
        if (openMenuIndex !== null) {
          const menuElement = menuRefs.current[openMenuIndex];
          if (menuElement && !menuElement.contains(event.target as Node)) {
            setOpenMenuIndex(null);
          }
        }
      };

      if (openMenuIndex !== null) {
        document.addEventListener('mousedown', handleClickOutside);
        return () => {
          document.removeEventListener('mousedown', handleClickOutside);
        };
      }
    }, [openMenuIndex]);

    const handleDeleteClick = (promptId: string) => {
      createV2.pendingDeletePromptId = promptId;
      setOpenMenuIndex(null);
      setIsDeleteModalOpen(true);
    };

    const handleDeleteModalClose = (wasConfirmed: boolean = false) => {
      const deletedId = createV2.pendingDeletePromptId;
      setIsDeleteModalOpen(false);
      createV2.pendingDeletePromptId = null;
      if (wasConfirmed && deletedId) {
        deletePromptFromCache(deletedId);
      }
    };

    return !isOpen ? null : (
      <Modal
        onClose={onClose}
        wrapperClasses='flex flex-col'
        closeButtonClasses={`absolute right-0 top-0 z-[200000]`}
      >
        <div
          className={`flex flex-col ${
            promptsForType.length > 3 ? 'max-h-[400px] overflow-y-auto' : ''
          }`}
        >
          {promptsForType.length === 0 ? (
            <div className='py-8 text-center text-foreground-tertiary'>
              {promptsType === PromptsType.Styles
                ? 'You do not have any styles saved.'
                : 'You do not have any lyrics saved.'}
            </div>
          ) : (
            promptsForType.map((prompt, i) => {
              const isLast = i === promptsForType.length - 1;
              return (
                <div
                  key={i}
                  className={`flex cursor-pointer flex-row items-center gap-2 p-4 hover:bg-background-secondary ${
                    !isLast ? 'border-b border-background-secondary' : ''
                  }`}
                  onClick={() => {
                    // Don't select prompt if clicking on menu
                    if (openMenuIndex === i) {
                      return;
                    }
                    if (promptsType === PromptsType.Styles && prompt.tags) {
                      setStyles(prompt.tags);
                    } else if (
                      promptsType === PromptsType.Lyrics &&
                      prompt.lyrics
                    ) {
                      setLyrics(prompt.lyrics);
                    }
                    setActiveModal(null);
                  }}
                >
                  <GenresIcon className='h-6 w-6 min-w-6' />
                  <div className='flex flex-col'>
                    <span className='line-clamp-1'>
                      {promptsType === PromptsType.Styles
                        ? prompt.tags
                        : prompt.lyrics}
                    </span>
                    <span className='text-xs text-foreground-tertiary'>
                      {getRelativeTime(prompt.updated_at)}
                    </span>
                  </div>
                  <div className='relative flex flex-1 flex-row-reverse'>
                    <Button
                      variant={ButtonVariant.Tertiary}
                      size={ButtonSize.Mini}
                      icon={MoreHorizontalIcon}
                      shape={ButtonShape.Rounded}
                      onClick={(e) => {
                        e.stopPropagation();
                        setOpenMenuIndex(openMenuIndex === i ? null : i);
                      }}
                      className='h-6 w-6'
                    />
                    {openMenuIndex === i && (
                      <div
                        ref={(el) => {
                          menuRefs.current[i] = el;
                        }}
                        className='absolute top-8 right-0 z-50 min-w-[120px] rounded-lg border border-border-primary bg-background-secondary py-1 shadow-lg'
                        onClick={(e) => e.stopPropagation()}
                      >
                        <Button
                          variant={ButtonVariant.Tertiary}
                          size={ButtonSize.Small}
                          icon={TrashIcon}
                          onClick={(e) => {
                            e.stopPropagation();
                            if (prompt.saved_prompt_id) {
                              handleDeleteClick(prompt.saved_prompt_id);
                            }
                          }}
                          className='w-full justify-start gap-2 px-3 py-2 text-sm text-accent-error-on-primary hover:bg-background-tertiary'
                        >
                          Delete
                        </Button>
                      </div>
                    )}
                  </div>
                </div>
              );
            })
          )}
          {shouldInfiniteLoad && promptsForType.length > 0 ? (
            <div className='py-4' ref={loaderRef}></div>
          ) : null}
        </div>
        <DeleteSavedPromptModal
          isOpen={isDeleteModalOpen}
          onClose={handleDeleteModalClose}
        />
      </Modal>
    );
  }
);
