import { DownloadIcon, LoaderIcon, PackageIcon } from "lucide-react";
import { useCallback, useState } from "react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import {
  Card,
  CardAction,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuItem,
  ContextMenuTrigger,
} from "@/components/ui/context-menu";
import { urlOfArtifact } from "@/core/artifacts/utils";
import { useI18n } from "@/core/i18n/hooks";
import { installSkill } from "@/core/skills/api";
import { dispatchMentionReference } from "@/core/threads/reference-events";
import {
  getFileExtensionDisplayName,
  getFileIcon,
  getFileName,
} from "@/core/utils/files";
import { cn, truncateMiddle } from "@/lib/utils";

import { useArtifacts } from "./context";

export function ArtifactFileList({
  className,
  files,
  threadId,
}: {
  className?: string;
  files: string[];
  threadId: string;
}) {
  const { t } = useI18n();
  const { select: selectArtifact, setOpen } = useArtifacts();
  const [installingFile, setInstallingFile] = useState<string | null>(null);

  const handleClick = useCallback(
    (filepath: string) => {
      selectArtifact(filepath);
      setOpen(true);
    },
    [selectArtifact, setOpen],
  );

  const handleInstallSkill = useCallback(
    async (e: React.MouseEvent, filepath: string) => {
      e.stopPropagation();
      e.preventDefault();

      if (!threadId) return;
      if (installingFile) return;

      setInstallingFile(filepath);
      try {
        const result = await installSkill({
          thread_id: threadId,
          path: filepath,
        });
        if (result.success) {
          toast.success(result.message);
        } else {
          toast.error(result.message || "Failed to install skill");
        }
      } catch (error) {
        console.error("Failed to install skill:", error);
        toast.error("Failed to install skill");
      } finally {
        setInstallingFile(null);
      }
    },
    [threadId, installingFile],
  );

  return (
    <ul
      className={cn("flex w-full flex-col gap-4", className)}
      data-testid="artifact-file-list"
    >
      {files.map((file) => (
        <ContextMenu key={file}>
          <ContextMenuTrigger asChild>
            <Card
              className="relative cursor-pointer p-4"
              data-testid="artifact-file-card"
              onClick={() => handleClick(file)}
            >
              <CardHeader className="pr-2 pl-1">
                <CardTitle className="relative overflow-hidden pl-10">
                  <div
                    className="text-sm font-normal text-ellipsis whitespace-nowrap"
                    title={getFileName(file)}
                  >
                    {truncateMiddle(getFileName(file), 50)}
                  </div>
                </CardTitle>
                <div className="absolute top-5 left-4">
                  {getFileIcon(
                    file,
                    "size-9 stroke-1 text-ws-fg-primary stroke-current",
                  )}
                </div>
                <CardDescription className="pl-10 text-xs">
                  {getFileExtensionDisplayName(file)} file
                </CardDescription>
                <CardAction>
                  {file.endsWith(".skill") && (
                    <Button
                      variant="ghost"
                      disabled={!threadId || installingFile === file}
                      onClick={(e) => handleInstallSkill(e, file)}
                    >
                      {installingFile === file ? (
                        <LoaderIcon className="size-4 animate-spin" />
                      ) : (
                        <PackageIcon className="size-4" />
                      )}
                      {t.common.install}
                    </Button>
                  )}
                  {threadId ? (
                    <a
                      href={urlOfArtifact({
                        filepath: file,
                        threadId,
                        download: true,
                      })}
                      target="_blank"
                      onClick={(e) => e.stopPropagation()}
                    >
                      <Button
                        variant="ghost"
                        className="text-muted-foreground h-full! hover:bg-transparent! hover:text-ws-fg-primary!"
                      >
                        <DownloadIcon className="size-4" />
                        {t.common.download}
                      </Button>
                    </a>
                  ) : (
                    <Button variant="ghost" disabled>
                      <DownloadIcon className="size-4" />
                      {t.common.download}
                    </Button>
                  )}
                </CardAction>
              </CardHeader>
            </Card>
          </ContextMenuTrigger>
          <ContextMenuContent className="min-w-[120px]">
            <ContextMenuItem
              onClick={() => {
                dispatchMentionReference({
                  threadId,
                  filename: getFileName(file),
                  path: file,
                  ref_source: "artifact",
                });
              }}
            >
              {t.common.reference}
            </ContextMenuItem>
          </ContextMenuContent>
        </ContextMenu>
      ))}
    </ul>
  );
}
