import styled from '@emotion/styled';
import { Dispatch, SetStateAction, useEffect, useRef, useState } from 'react';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import { useWorkspaces } from '@/app/(root)/chat/useWorkspaces';
import { useBreakpointMd } from '@/hooks/useBreakpoint';
import {
  CaretRightIcon,
  CheckIcon,
  CloseIcon,
  LibraryIcon,
  MoreHorizontalIcon,
  PlusIcon,
  StudioIcon,
  UserIcon,
} from '@/icons';
import { ProjectMetadataSchema } from '@/state/projectStore';
import { getRelativeTime } from '@/utils/utils';

import Button, {
  ButtonShape,
  ButtonSize,
  ButtonVariant,
} from '../button/Button';
import {
  ContextMenuItem,
  ContextMenuTrigger,
} from '../contextMenu/ContextMenu';
import ImageWithFallback from '../image/ImageWithFallback';
import SpinnerSVG from '../svg/SpinnerSVG';

const SpecialRowWrapper = styled.button<{ compact?: boolean }>`
  cursor: pointer;
  color: var(--color-foreground-primary);
  background-color: var(--color-background-secondary);
  padding: 8px 16px;
  border-radius: 16px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  .hover-only {
    opacity: 0;
  }
  &:hover {
    .hover-only {
      opacity: 1;
    }
  }
`;

const WorkspaceRowTitleWrapper = styled.div`
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
`;
const WorkspaceRowTitle = styled.span<{ selected?: boolean }>`
  font-size: 14px;
  font-weight: 500;
  display: flex;
  align-items: center;
  text-align: left;
  gap: 4px;
  color: ${(props) =>
    props.selected ? 'var(--color-accent-brand)' : 'inherit'};
`;
const WorkspaceRowTitleText = styled.span`
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
`;
const WorkspaceRowLastUpdated = styled.span`
  font-size: 12px;
  font-weight: normal;
  color: var(--color-foreground-secondary);
  text-align: left;
`;
export const WorkspaceRowSongCount = styled.span`
  font-size: 12px;
  padding: 4px 8px;
  font-weight: normal;
  color: var(--color-foreground-primary-on-dark);
  border-radius: 32px;
  background-color: var(--color-background-smoke-thick);
  backdrop-filter: blur(12px);
  position: absolute;
  bottom: 4px;
  right: 4px;
  white-space: nowrap;
`;

const WorkspaceImageWrapper = styled.div`
  position: relative;
  transition:
    0.2s filter ease-in-out,
    0.2s -webkit-filter ease-in-out;
`;

const WorkspaceRowWrapper = styled.div<{
  compact?: boolean;
  selected?: boolean;
  pending?: boolean;
}>`
  color: var(--color-foreground-primary);
  border-radius: 16px;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: ${(props) => (props.compact ? '2px 8px 2px 2px' : '8px')};
  width: 100%;
  font-weight: medium;
  animation: fadeIn 0.15s ease;
  opacity: ${(props) => (props.pending ? '0.75' : '1.0')};
  background-color: ${(props) =>
    props.selected ? 'var(--color-background-fog-thin)' : 'transparent'};

  :hover {
    background-color: ${(props) =>
      props.pending ? 'transparent' : 'var(--color-background-fog-thin)'};

    ${WorkspaceImageWrapper} {
      filter: ${(props) => (props.pending ? 'none' : 'brightness(0.75)')};
    }
  }
  cursor: ${(props) => (props.pending ? 'auto' : 'pointer')};
`;
const WorkspaceRowControls = styled.div`
  flex: 1;
  display: flex;
  flex-direction: row-reverse;
  font-size: 12px;
  color: var(--color-foreground-tertiary);
`;
const WorkspaceListWrapper = styled.div<{
  compact?: boolean;
}>`
  display: flex;
  flex-direction: column;
  gap: ${(props) => (props.compact ? '2px' : '4px')};
  padding-bottom: 110px;
`;

const getAuraURLForProject = (project: ProjectMetadataSchema) => {
  const auraIndex = (parseInt(project.id.split('-')[0], 16) % 16) + 1;
  return `https://cdn1.suno.ai/sAura${auraIndex}.jpg`;
};

const WorkspaceListRow = ({
  project,
  onSelectProject,
  compact,
  selected,
  isTrashed,
  isPending,
  archiveWorkspace,
  unarchiveWorkspace,
}: {
  project: ProjectMetadataSchema;
  onSelectProject: () => void;
  compact?: boolean;
  selected?: boolean;
  isTrashed?: boolean;
  isPending?: boolean;
  archiveWorkspace: (workspaceId: string) => void;
  unarchiveWorkspace: (workspaceId: string) => void;
}) => {
  return (
    <WorkspaceRowWrapper
      onClick={isPending ? undefined : onSelectProject}
      className='group'
      compact={compact}
      selected={selected}
      pending={isPending}
      role='button'
      aria-disabled={isPending ? true : undefined}
      tabIndex={isPending ? -1 : 0}
      onKeyDown={(e) => {
        if (isPending) {
          return;
        }
        if (e.key === 'Enter' || e.key === ' ') {
          e.preventDefault();
          onSelectProject();
        }
      }}
    >
      <WorkspaceImageWrapper>
        <ImageWithFallback
          src={getAuraURLForProject(project)}
          alt={`Cover image for ${project.name}`}
          className={
            'h-[50px] min-h-[50px] w-[60px] min-w-[60px] rounded-lg object-cover'
          }
          fallbackSrc='https://cdn-o.suno.com/auras/Aura-01.png'
        />
      </WorkspaceImageWrapper>
      <WorkspaceRowTitleWrapper>
        <WorkspaceRowTitle selected={selected}>
          <WorkspaceRowTitleText>{project.name}</WorkspaceRowTitleText>
          {project.shared && (
            <UserIcon className='h-4 w-4 text-foreground-primary' />
          )}
        </WorkspaceRowTitle>
        {!!(project.last_updated_clip ?? project.created_at) ? (
          <WorkspaceRowLastUpdated>
            {project.clip_count} Songs ·{' '}
            {getRelativeTime(
              project.last_updated_clip ?? project.created_at ?? ''
            )}
          </WorkspaceRowLastUpdated>
        ) : null}
      </WorkspaceRowTitleWrapper>
      <WorkspaceRowControls>
        {project.id !== 'default' && !isPending && (
          <ContextMenuTrigger
            placement='bottom-left'
            ButtonComponent={(props) => {
              return (
                <Button
                  variant={ButtonVariant.Standard}
                  size={ButtonSize.Small}
                  shape={ButtonShape.Pill}
                  icon={MoreHorizontalIcon}
                  className='opacity-0 transition-opacity duration-200 ease-in group-hover:opacity-100'
                  {...props}
                />
              );
            }}
            ContentsComponent={() => {
              return isTrashed ? (
                <ContextMenuItem
                  onClick={(e) => {
                    e.stopPropagation();
                    unarchiveWorkspace(project.id);
                  }}
                >
                  Restore Workspace
                </ContextMenuItem>
              ) : (
                <ContextMenuItem
                  onClick={(e) => {
                    e.stopPropagation();
                    archiveWorkspace(project.id);
                  }}
                >
                  Move to Trash
                </ContextMenuItem>
              );
            }}
          />
        )}
      </WorkspaceRowControls>
    </WorkspaceRowWrapper>
  );
};

const StudioSessionsRow = ({
  onSelect,
  compact,
}: {
  onSelect: () => void;
  compact?: boolean;
}) => {
  return (
    <SpecialRowWrapper onClick={onSelect} className='group' compact={compact}>
      <WorkspaceRowTitleWrapper>
        <WorkspaceRowTitle>
          <StudioIcon className='h-6 w-6' />
          Studio Projects
        </WorkspaceRowTitle>
      </WorkspaceRowTitleWrapper>
      <Button
        className='hover-only'
        shape={ButtonShape.Pill}
        size={ButtonSize.Small}
        variant={ButtonVariant.Standard}
        icon={<CaretRightIcon className='h-6 w-6' />}
      />
    </SpecialRowWrapper>
  );
};

const AllSongsRow = ({
  onSelect,
  compact,
}: {
  onSelect: () => void;
  compact?: boolean;
}) => {
  return (
    <SpecialRowWrapper onClick={onSelect} className='group' compact={compact}>
      <WorkspaceRowTitleWrapper>
        <WorkspaceRowTitle>
          <LibraryIcon className='h-6 w-6' />
          All Songs
        </WorkspaceRowTitle>
      </WorkspaceRowTitleWrapper>
      <Button
        className='hover-only'
        shape={ButtonShape.Pill}
        size={ButtonSize.Small}
        variant={ButtonVariant.Standard}
        icon={<CaretRightIcon className='h-6 w-6' />}
      />
    </SpecialRowWrapper>
  );
};

export const WorkspaceList = ({
  isSearching,
  isCreatingNewWorkspace,
  setIsCreatingNewWorkspace,
  projects,
  numTotalProjects,
  onSelectProject,
  onSelectStudioSessions,
  onSelectAllSongs,
  onLoadNextPage,
  onCreateNewWorkspace,
  onOpenCreateProjectModal,
  compact,
  isTrashed,
  archiveWorkspace,
  unarchiveWorkspace,
  createNewWorkspaceButtonText,
}: {
  isSearching: boolean;
  isCreatingNewWorkspace: boolean;
  setIsCreatingNewWorkspace: Dispatch<SetStateAction<boolean>>;
  projects: ProjectMetadataSchema[];
  numTotalProjects: number;
  onSelectProject: (project: ProjectMetadataSchema) => void;
  onSelectStudioSessions?: () => void;
  onSelectAllSongs?: () => void;
  onLoadNextPage?: () => void;
  onCreateNewWorkspace?: () => void;
  onOpenCreateProjectModal?: () => void;
  compact?: boolean;
  isTrashed?: boolean;
  archiveWorkspace: (workspaceId: string) => void;
  unarchiveWorkspace: (workspaceId: string) => void;
  createNewWorkspaceButtonText?: string;
}) => {
  const { project: projectStore } = useStores();
  const { ref: infiniteLoaderRef } = useInView({
    threshold: 0,
    onChange: (inView) => {
      if (inView && onLoadNextPage) {
        onLoadNextPage();
      }
    },
  });
  const createWorkspaceRowRef = useRef<HTMLDivElement>(null);
  const { createWorkspace } = useWorkspaces();
  const [newWorkspaceName, setNewWorkspaceName] = useState<string>('');
  const isMobile = !useBreakpointMd();

  useEffect(() => {
    if (isCreatingNewWorkspace) {
      setNewWorkspaceName('');
    }
  }, [isCreatingNewWorkspace]);

  return (
    <WorkspaceListWrapper compact={compact}>
      {/* New Workspace button - first row on mobile only */}

      {onSelectAllSongs && (
        <AllSongsRow onSelect={onSelectAllSongs} compact={compact} />
      )}

      {onSelectStudioSessions && (
        <StudioSessionsRow
          onSelect={onSelectStudioSessions}
          compact={compact}
        />
      )}

      {onCreateNewWorkspace && onOpenCreateProjectModal && (
        <WorkspaceRowWrapper
          ref={createWorkspaceRowRef}
          onClick={
            isCreatingNewWorkspace
              ? () => {}
              : isMobile
                ? onOpenCreateProjectModal
                : onCreateNewWorkspace
          }
          className='group'
          compact={compact}
          role='button'
          tabIndex={0}
          onKeyDownCapture={(e) => {
            if (e.key === 'Enter' && !isCreatingNewWorkspace) {
              e.preventDefault();
              if (isMobile) {
                onOpenCreateProjectModal();
              } else {
                onCreateNewWorkspace();
              }
            }
          }}
        >
          <div className='relative flex items-center justify-center'>
            <div className='flex h-[50px] w-[60px] items-center justify-center rounded-lg bg-background-fog-thick'>
              {isCreatingNewWorkspace ? null : (
                <PlusIcon className='h-6 w-6 text-foreground-secondary' />
              )}
            </div>
          </div>
          <WorkspaceRowTitleWrapper>
            <WorkspaceRowTitle>
              {isCreatingNewWorkspace && !isMobile ? (
                <input
                  type='text'
                  placeholder='Untitled'
                  className='w-full outline-none'
                  autoFocus
                  aria-label='New workspace name'
                  value={newWorkspaceName}
                  onChange={(e) => setNewWorkspaceName(e.target.value)}
                  onKeyDownCapture={(e) => {
                    if (e.key === 'Enter') {
                      setIsCreatingNewWorkspace(false);
                      createWorkspace(
                        newWorkspaceName.trim() === ''
                          ? 'Untitled'
                          : newWorkspaceName
                      );
                    } else if (e.key === 'Escape') {
                      setIsCreatingNewWorkspace(false);
                    }
                  }}
                />
              ) : (
                (createNewWorkspaceButtonText ?? 'Create New Workspace')
              )}
            </WorkspaceRowTitle>
            {isCreatingNewWorkspace && !isMobile ? (
              <WorkspaceRowLastUpdated>
                0 Songs · Just now
              </WorkspaceRowLastUpdated>
            ) : null}
          </WorkspaceRowTitleWrapper>
          {isCreatingNewWorkspace && !isMobile ? (
            <WorkspaceRowControls>
              <Button
                variant={ButtonVariant.Glass}
                icon={CloseIcon}
                onClick={() => setIsCreatingNewWorkspace(false)}
              />
              <Button
                variant={ButtonVariant.Standard}
                shape={ButtonShape.Pill}
                icon={CheckIcon}
                onClick={(e) => {
                  e.stopPropagation();
                  setIsCreatingNewWorkspace(false);
                  createWorkspace(
                    newWorkspaceName.trim() === ''
                      ? 'Untitled'
                      : newWorkspaceName
                  );
                }}
              >
                Confirm
              </Button>
            </WorkspaceRowControls>
          ) : null}
        </WorkspaceRowWrapper>
      )}

      {projects.map((project: ProjectMetadataSchema) => {
        return (
          <WorkspaceListRow
            compact={compact}
            key={project.id}
            project={project}
            onSelectProject={() => onSelectProject(project)}
            selected={projectStore.currentProjectId === project.id}
            isTrashed={isTrashed}
            archiveWorkspace={archiveWorkspace}
            unarchiveWorkspace={unarchiveWorkspace}
            isPending={project.is_pending}
          />
        );
      })}
      {projects.length === 0 &&
        (isSearching ? (
          <div className='flex h-12 w-full items-center justify-center'>
            <SpinnerSVG />
          </div>
        ) : (
          <div className='flex h-full items-center justify-center text-foreground-secondary'>
            No workspaces found.
          </div>
        ))}
      {!projectStore.loadingAllProjects &&
        projects.length > 0 &&
        // allow margin of error of 1 to account for default workspace being excluded
        projects.length < numTotalProjects - 1 && (
          <div
            className='flex h-12 w-full items-center justify-center'
            ref={infiniteLoaderRef}
          >
            <SpinnerSVG />
          </div>
        )}
    </WorkspaceListWrapper>
  );
};
