import { useMemo, useState, MouseEvent } from 'react';
import { Link } from 'react-router-dom';
import { MessageSquare, Link as LinkIcon } from 'lucide-react';
import type { SharedLinksResponse, TSharedLink } from 'librechat-data-provider';
import { useDeleteSharedLinkMutation, useSharedLinksInfiniteQuery } from '~/data-provider';
import { useAuthContext, useLocalize, useNavScrolling } from '~/hooks';
import { NotificationSeverity } from '~/common';
import { useToastContext } from '~/Providers';
import { cn } from '~/utils';
import {
  Spinner,
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
  TrashIcon,
} from '~/components';

function SharedLinkDeleteButton({
  shareId,
  setIsDeleting,
}: {
  shareId: string;
  setIsDeleting: (isDeleting: boolean) => void;
}) {
  const localize = useLocalize();
  const { showToast } = useToastContext();
  const mutation = useDeleteSharedLinkMutation({
    onError: () => {
      showToast({
        message: localize('com_ui_share_delete_error'),
        severity: NotificationSeverity.ERROR,
        showIcon: true,
      });
      setIsDeleting(false);
    },
  });

  const handleDelete = async (e: MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    if (mutation.isLoading) {
      return;
    }
    setIsDeleting(true);
    await mutation.mutateAsync({ shareId });
    setIsDeleting(false);
  };
  return (
    <TooltipProvider delayDuration={250}>
      <Tooltip>
        <TooltipTrigger asChild>
          <span onClick={handleDelete}>
            <TrashIcon />
          </span>
        </TooltipTrigger>
        <TooltipContent side="top" sideOffset={0}>
          {localize('com_ui_delete')}
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}
function SourceChatButton({ conversationId }: { conversationId: string }) {
  const localize = useLocalize();

  return (
    <TooltipProvider delayDuration={250}>
      <Tooltip>
        <TooltipTrigger asChild>
          <Link to={`/c/${conversationId}`} target="_blank" rel="noreferrer">
            <MessageSquare className="h-4 w-4 hover:text-gray-300" />
          </Link>
        </TooltipTrigger>
        <TooltipContent side="top" sideOffset={0}>
          {localize('com_nav_source_chat')}
        </TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
}

function ShareLinkRow({ sharedLink }: { sharedLink: TSharedLink }) {
  const [isDeleting, setIsDeleting] = useState(false);

  return (
    <tr
      key={sharedLink.conversationId}
      className="border-b border-gray-200 text-sm font-normal dark:border-white/10"
    >
      <td
        className={cn(
          'flex items-center py-3 text-blue-800/70 dark:text-blue-500',
          isDeleting && 'opacity-50',
        )}
      >
        <Link to={`/share/${sharedLink.shareId}`} target="_blank" rel="noreferrer" className="flex">
          <LinkIcon className="mr-1 h-5 w-5" />
          {sharedLink.title}
        </Link>
      </td>
      <td className="p-3">
        <div className="flex justify-between">
          <div className={cn('flex justify-start dark:text-gray-200', isDeleting && 'opacity-50')}>
            {new Date(sharedLink.createdAt).toLocaleDateString('en-US', {
              month: 'long',
              day: 'numeric',
              year: 'numeric',
            })}
          </div>
          <div
            className={cn(
              'flex items-center justify-end gap-3 text-gray-400',
              isDeleting && 'opacity-50',
            )}
          >
            {sharedLink.conversationId && (
              <>
                <SourceChatButton conversationId={sharedLink.conversationId} />
                <div className={cn('h-4 w-4 cursor-pointer', !isDeleting && 'hover:text-gray-300')}>
                  <SharedLinkDeleteButton
                    shareId={sharedLink.shareId}
                    setIsDeleting={setIsDeleting}
                  />
                </div>
              </>
            )}
          </div>
        </div>
      </td>
    </tr>
  );
}
export default function ShareLinkTable({ className }: { className?: string }) {
  const localize = useLocalize();
  const { isAuthenticated } = useAuthContext();
  const [showLoading, setShowLoading] = useState(false);

  const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isError, isLoading } =
    useSharedLinksInfiniteQuery({ pageNumber: '1', isPublic: true }, { enabled: isAuthenticated });

  const { containerRef } = useNavScrolling<SharedLinksResponse>({
    setShowLoading,
    hasNextPage: hasNextPage,
    fetchNextPage: fetchNextPage,
    isFetchingNextPage: isFetchingNextPage,
  });

  const sharedLinks = useMemo(() => data?.pages.flatMap((page) => page.sharedLinks) || [], [data]);
  const classProp: { className?: string } = {
    className: 'p-1 hover:text-black dark:hover:text-white',
  };
  if (className) {
    classProp.className = className;
  }

  if (isLoading) {
    return <Spinner className="m-1 mx-auto mb-4 h-4 w-4 text-black dark:text-white" />;
  }

  if (isError) {
    return (
      <div className="rounded-md border border-red-500 bg-red-500/10 px-3 py-2 text-sm text-gray-600 dark:text-gray-200">
        {localize('com_ui_share_retrieve_error')}
      </div>
    );
  }
  if (!sharedLinks || sharedLinks.length === 0) {
    return <div className="text-gray-300">{localize('com_nav_shared_links_empty')}</div>;
  }

  return (
    <div
      className={cn(
        'grid w-full gap-2',
        '-mr-2 flex-1 flex-col overflow-y-auto pr-2 transition-opacity duration-500',
        'max-h-[350px]',
      )}
      ref={containerRef}
    >
      <table className="table-fixed text-left">
        <thead className="sticky top-0 bg-white dark:bg-gray-700">
          <tr className="border-b border-gray-200 text-sm font-semibold text-gray-500 dark:border-white/10 dark:text-gray-200">
            <th className="p-3">{localize('com_nav_shared_links_name')}</th>
            <th className="p-3">{localize('com_nav_shared_links_date_shared')}</th>
          </tr>
        </thead>
        <tbody>
          {sharedLinks.map((sharedLink) => (
            <ShareLinkRow key={sharedLink.shareId} sharedLink={sharedLink} />
          ))}
        </tbody>
      </table>
      {(isFetchingNextPage || showLoading) && (
        <Spinner className={cn('m-1 mx-auto mb-4 h-4 w-4 text-black dark:text-white')} />
      )}
    </div>
  );
}
