'use client';

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

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

import { useStores } from '@/app/(root)/AppProviders';
import { CaretDownIcon, CaretUpIcon } from '@/icons';
import { Project } from '@/state/projectStore';
import {
  DEFAULT_PROJECT_ID,
  DEFAULT_PROJECT_NAME,
  SMALL_IMAGE,
} from '@/utils/constants';
import { eventLogger } from '@/utils/event-logger';
import { EventNames } from '@/utils/event-names';
import { getProjectName } from '@/utils/utils';

import { ButtonSize } from '../button/Button';
import CloseButton from '../button/CloseButton';
import ImageWithFallback from '../image/ImageWithFallback';
import CreateProjectModal from '../modal/CreateProjectModal';
import SpinnerSVG from '../svg/SpinnerSVG';

type ProjectsDropdownProps = {
  editMode?: boolean;
  flush?: boolean;
};

const ProjectsDropdown = observer(
  ({ editMode = false, flush = false }: ProjectsDropdownProps) => {
    const { project, session } = useStores();
    const pathname = usePathname();
    const [isOpen, setIsOpen] = useState(false);
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [selectedProject, setSelectedProject] = useState<Project | null>(
      null
    );
    const [isLoading, setIsLoading] = useState(false);
    const dropdownRef = useRef<HTMLDivElement>(null);
    const dropdownContentRef = useRef<HTMLDivElement>(null);
    const [currentPage, setCurrentPage] = useState(1);
    const [hasMore, setHasMore] = useState(true);
    const [localProjects, setLocalProjects] = useState<Project[]>([]);
    const scrollContainerRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
      fetchProjects(true);
    }, []);

    useEffect(() => {
      if (isOpen) {
        setCurrentPage(1);
        setHasMore(true);
        fetchProjects(true);
      }
    }, [isOpen]);

    useEffect(() => {
      if (currentPage > 1) {
        fetchProjects(false);
      }
    }, [currentPage]);

    const { ref: spinnerRef } = useInView({
      threshold: 0,
      onChange: async (inView: boolean) => {
        if (inView && hasMore && !isLoading) {
          setCurrentPage((prev) => prev + 1);
        }
      },
    });

    const closeModal = () => {
      setIsModalOpen(false);
    };

    const fetchProjects = async (overwrite: boolean = false) => {
      setIsLoading(true);
      try {
        const { projects, numTotalResults } = (await project.fetchProjectsList(
          currentPage
        )) as unknown as {
          projects: Project[];
          numTotalResults: number;
        };

        if (projects.length === 0) {
          setHasMore(false);
        } else {
          const scrollContainer = scrollContainerRef.current;
          const scrollPosition = scrollContainer?.scrollTop;

          const newProjects = overwrite
            ? projects
            : [...localProjects, ...projects];

          setLocalProjects(newProjects);
          setHasMore(newProjects.length < numTotalResults);

          if (scrollPosition && scrollContainer) {
            requestAnimationFrame(() => {
              scrollContainer.scrollTop = scrollPosition;
            });
          }
        }
      } catch (error) {
        console.error('Error fetching projects:', error);
      } finally {
        setIsLoading(false);
      }
    };

    const toggleDropdown = () => {
      if (!isOpen) {
        eventLogger.segmentTrack(EventNames.webPageEvent, {
          userId: session?.userId,
          element: 'project_dropdown',
          eventType: 'open',
          pageUrl: pathname,
        });
      } else {
        eventLogger.segmentTrack(EventNames.webPageEvent, {
          userId: session?.userId,
          element: 'project_dropdown',
          eventType: 'close',
          pageUrl: pathname,
        });
      }
      setIsOpen(!isOpen);
    };

    const openModal = () => {
      setIsModalOpen(true);
      setIsOpen(false);
      eventLogger.segmentTrack(EventNames.webPageEvent, {
        userId: session?.userId,
        element: 'create_project_modal',
        secondaryElement: 'project_dropdown',
        eventType: 'click',
        pageUrl: pathname,
      });
    };

    const handleProjectSelect = (proj: Project) => {
      project.clearFilters();
      if (editMode) {
        const url = new URL(window.location.href);
        url.searchParams.set('wid', proj.id);
        window.history.replaceState(null, '', url.toString());
      } else {
        window.history.pushState(null, '', `/create?wid=${proj.id}`);
      }
      project.setUserSelectedProjectId(proj.id, proj.name);
      setSelectedProject(proj);
      setIsOpen(false);

      eventLogger.segmentTrack(EventNames.webPageEvent, {
        userId: session?.userId,
        element: 'project_selected',
        secondaryElement: 'project_dropdown',
        entityId: proj?.id,
        eventType: 'click',
        pageUrl: pathname,
      });
    };

    const handleProjectClear = (event: React.MouseEvent) => {
      event.stopPropagation();

      if (project.currentProjectId === DEFAULT_PROJECT_ID) {
        return;
      }
      if (editMode) {
        project.silentlySyncURLWithProjectId(DEFAULT_PROJECT_ID);
      } else {
        window.history.pushState(null, '', `/create?wid=${DEFAULT_PROJECT_ID}`);
      }
      project.setUserSelectedProjectId(
        DEFAULT_PROJECT_ID,
        DEFAULT_PROJECT_NAME
      );
      setSelectedProject(null);

      eventLogger.segmentTrack(EventNames.webPageEvent, {
        userId: session?.userId,
        element: 'project_cleared',
        secondaryElement: 'project_dropdown',
        pageUrl: pathname,
      });
    };

    useEffect(() => {
      const handleClickOutside = (event: MouseEvent) => {
        if (
          dropdownRef.current &&
          !dropdownRef.current.contains(event.target as Node)
        ) {
          setIsOpen(false);
        }
      };

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

    useEffect(() => {
      if (project.currentProjectId) {
        const currentProject = project.projectsById[project.currentProjectId];
        if (currentProject) {
          // Convert to full Project type
          const fullProject = {
            clip_count: 0,
            last_updated_clip: '',
            ...currentProject,
            project_clips: [],
            is_owned: true,
            is_trashed: false,
            current_page: 1,
            image_url: null,
          } as Project;
          setSelectedProject(fullProject);
        }
      } else {
        setSelectedProject(null);
      }
    }, [project.currentProjectId, project.projectsById, session.flags]);

    const renderProjectList = (projects: Project[]) => (
      <>
        {projects.length === 0 ? (
          <>
            <p>No Workspaces</p>
            <p className='text-sm'>
              Workspaces help you organize your songs into collections.
            </p>
          </>
        ) : (
          projects.map((proj) => (
            <div
              key={proj.id}
              className='group flex cursor-pointer items-center justify-between rounded-lg p-2 hover:bg-secondary/20'
              onClick={() => handleProjectSelect(proj)}
            >
              <div className='flex items-center gap-[8px] overflow-hidden'>
                <div className='relative h-[24px] w-[32px] shrink-0'>
                  <div className='h-[24px] w-[32px] overflow-hidden rounded-[4px]'>
                    <ImageWithFallback
                      imageSize={SMALL_IMAGE}
                      src={project.getAuraImageForProject(proj.id)}
                      alt={`Project image for ${proj.name}`}
                      className='h-full w-full object-cover'
                    />
                  </div>
                </div>
                <div className='min-w-0 flex-1 font-sans text-sm font-medium'>
                  <div className='truncate'>
                    {getProjectName(proj as any as Project)}
                    <span className='text-[#8F8B8A]'>
                      {' '}
                      - {proj?.clip_count || 0} clip
                      {(proj?.clip_count && proj?.clip_count > 1) ||
                      proj?.clip_count === 0
                        ? 's'
                        : ''}
                    </span>
                  </div>
                </div>
              </div>
            </div>
          ))
        )}
        {hasMore && (
          <div
            className='flex h-20 items-center justify-center'
            ref={spinnerRef}
          >
            <SpinnerSVG />
          </div>
        )}
      </>
    );

    return (
      <div
        className={`${flush ? 'md:mx-0' : 'md:mx-2'} relative pb-2 font-sans`}
        ref={dropdownRef}
      >
        <div className='py-3 font-sans text-[15px]'>Workspace</div>
        <div
          className={`flex h-[48px] cursor-pointer items-center justify-between rounded-md border border-border-primary bg-background-secondary px-3 text-sm ${selectedProject ? '' : 'hover:bg-secondary/20'}`}
          onClick={toggleDropdown}
        >
          <div className='flex items-center'>
            {selectedProject ? (
              <>
                <div className='relative mr-2 h-[24px] w-[32px]'>
                  <div className='h-[24px] w-[32px] overflow-hidden rounded-[4px]'>
                    <ImageWithFallback
                      imageSize={SMALL_IMAGE}
                      className='h-full w-full object-cover'
                      src={project.getAuraImageForProject(selectedProject.id)}
                      alt={`Workspace picture for ${selectedProject.name}`}
                    />
                  </div>
                </div>
                <span>
                  <div className='font-sans text-sm font-medium'>
                    {getProjectName(selectedProject as any as Project)}
                  </div>
                </span>
              </>
            ) : (
              <>
                <div className='relative mr-2 h-[24px] w-[32px]'>
                  <div className='h-[24px] w-[32px] overflow-hidden rounded-[4px]'>
                    <ImageWithFallback
                      imageSize={SMALL_IMAGE}
                      className='h-full w-full object-cover'
                      src={project.getAuraImageForProject(DEFAULT_PROJECT_ID)}
                      alt={`Workspace picture for ${DEFAULT_PROJECT_NAME}`}
                    />
                  </div>
                </div>
                <span>
                  <div className='font-sans text-sm font-medium'>
                    {DEFAULT_PROJECT_NAME}
                  </div>
                </span>
              </>
            )}
          </div>
          {selectedProject && selectedProject.id !== DEFAULT_PROJECT_ID ? (
            <CloseButton
              onClick={(event: any) => handleProjectClear(event)}
              size={ButtonSize.Medium}
            />
          ) : (
            <button>
              {isOpen ? (
                <CaretUpIcon className='z-10000 ml-2 h-4 w-4 fill-foreground-primary' />
              ) : (
                <CaretDownIcon className='z-10000 ml-2 h-4 w-4 fill-foreground-primary' />
              )}
            </button>
          )}
        </div>
        <div
          ref={dropdownContentRef}
          className={clsx(
            'mt-2 flex h-auto w-full overflow-hidden transition-all duration-300 ease-in-out',
            { 'max-h-0': !isOpen, 'max-h-[400px]': isOpen }
          )}
        >
          <div className='flex w-full flex-grow-1 flex-col rounded-lg border border-border-primary bg-background-secondary text-foreground-primary shadow-xl'>
            <div
              ref={scrollContainerRef}
              className='custom-scrollbar-transparent min-h-0 w-full flex-1 overflow-y-auto p-4'
            >
              {isLoading && localProjects.length === 0 ? (
                <div className='flex h-20 items-center justify-center'>
                  <SpinnerSVG />
                </div>
              ) : (
                renderProjectList(localProjects)
              )}
            </div>
            <div className='bottom-0 mt-auto h-auto justify-center bg-background-secondary p-4'>
              <div
                className='cursor-pointer rounded-full border border-primary px-4 py-2 font-sans text-sm text-foreground-primary hover:bg-secondary/20'
                onClick={openModal}
              >
                Create a Workspace
              </div>
            </div>
          </div>
        </div>
        <CreateProjectModal
          project={project}
          isOpen={isModalOpen}
          onClose={closeModal}
          onProjectCreated={(newProject: Project) => {
            handleProjectSelect(newProject);
          }}
        />
      </div>
    );
  }
);

export default ProjectsDropdown;
