import { useMemo, useState } from "react";
import { FileIcon, Globe, Loader2, Plus, X } from "lucide-react";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
import type { LinkPreviewEntry } from "@/hooks/use-link-metadata";
import {
  AttachmentLightbox,
  getAttachmentHandler,
  type AttachmentItem,
} from "@/features/attachments/attachment-lightbox";
import { platform } from "@/lib/platform";

export interface PendingAttachment {
  id: string;
  file: File;
  thumbnailUrl?: string;
  status: "pending" | "uploading" | "uploaded" | "error";
}

interface AttachmentStripProps {
  attachments: PendingAttachment[];
  onRemove: (id: string) => void;
  onAddClick: () => void;
  linkPreviews?: LinkPreviewEntry[];
}

function pendingToItem(p: PendingAttachment): AttachmentItem {
  return {
    id: p.id,
    filename: p.file.name,
    mimeType: p.file.type || "application/octet-stream",
    sizeBytes: p.file.size,
    source: { kind: "local", file: p.file },
  };
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function AttachmentThumbnail({
  attachment,
  onRemove,
  onPreview,
}: {
  attachment: PendingAttachment;
  onRemove: () => void;
  onPreview?: () => void;
}) {
  const isImage = attachment.file.type.startsWith("image/");
  const isUploading = attachment.status === "uploading";
  const isError = attachment.status === "error";
  const previewable = getAttachmentHandler(attachment.file.type) === "lightbox";

  return (
    <div
      role={previewable ? "button" : undefined}
      tabIndex={previewable ? 0 : undefined}
      onClick={previewable && onPreview ? onPreview : undefined}
      className={cn(
        "group relative flex h-16 w-16 shrink-0 items-center justify-center overflow-hidden rounded-lg bg-white/10",
        previewable && "cursor-pointer",
        isError && "ring-1 ring-red-400/50",
      )}
    >
      {isImage && attachment.thumbnailUrl ? (
        <img
          src={attachment.thumbnailUrl}
          alt={attachment.file.name}
          className="h-full w-full object-cover"
        />
      ) : (
        <div className="flex flex-col items-center gap-0.5 px-1">
          <FileIcon className="size-5 text-white/60" />
          <span className="max-w-full truncate text-[9px] text-white/50">
            {attachment.file.name}
          </span>
          <span className="text-[9px] text-white/40">
            {formatFileSize(attachment.file.size)}
          </span>
        </div>
      )}

      {isUploading && (
        <div className="absolute inset-0 flex items-center justify-center bg-black/50">
          <Loader2 className="size-4 animate-spin text-white/70" />
        </div>
      )}

      <button
        type="button"
        onClick={(e) => {
          e.stopPropagation();
          onRemove();
        }}
        className="absolute right-0.5 top-0.5 hidden rounded-full bg-black/70 p-0.5 text-white/70 hover:text-white group-hover:block"
      >
        <X className="size-3" />
      </button>
    </div>
  );
}

function LinkPreviewThumbnail({ entry }: { entry: LinkPreviewEntry }) {
  if (entry.isLoading) {
    return (
      <div className="flex h-16 w-28 shrink-0 flex-col gap-1.5 rounded-lg bg-white/10 p-2">
        <Skeleton className="h-2 w-16 bg-white/10" />
        <Skeleton className="h-3 w-24 bg-white/10" />
      </div>
    );
  }

  if (!entry.metadata) return null;

  const { metadata } = entry;

  return (
    <button
      type="button"
      onClick={() => platform.link.openExternal(metadata.url)}
      className="flex h-16 w-28 shrink-0 flex-col justify-center gap-1 overflow-hidden rounded-lg bg-white/10 px-2 py-1.5 text-left transition-colors hover:bg-white/15"
    >
      <div className="flex items-center gap-1 text-[10px] text-white/40">
        {metadata.favicon ? (
          <img
            src={metadata.favicon}
            alt=""
            className="size-3 rounded-sm"
            onError={(e) => {
              (e.target as HTMLImageElement).style.display = "none";
            }}
          />
        ) : (
          <Globe className="size-3" />
        )}
        <span className="truncate">{metadata.domain}</span>
      </div>
      {metadata.title && (
        <p className="line-clamp-2 text-[11px] font-medium leading-tight text-white/80">
          {metadata.title}
        </p>
      )}
    </button>
  );
}

export function AttachmentStrip({
  attachments,
  onRemove,
  onAddClick,
  linkPreviews,
}: AttachmentStripProps) {
  const hasLinks = linkPreviews && linkPreviews.length > 0;

  // Lightbox state — only previewable attachments go in.
  const previewable = useMemo(
    () => attachments.filter((a) => getAttachmentHandler(a.file.type) === "lightbox"),
    [attachments],
  );
  const items = useMemo(() => previewable.map(pendingToItem), [previewable]);
  const [openIndex, setOpenIndex] = useState<number | null>(null);

  if (attachments.length === 0 && !hasLinks) return null;

  return (
    <>
      <ScrollArea className="w-full">
        <div className="flex items-center gap-2 py-2">
          {attachments.map((a) => (
            <AttachmentThumbnail
              key={a.id}
              attachment={a}
              onRemove={() => onRemove(a.id)}
              onPreview={() => {
                const idx = previewable.indexOf(a);
                if (idx >= 0) setOpenIndex(idx);
              }}
            />
          ))}

          {linkPreviews?.map((entry) => (
            <LinkPreviewThumbnail key={entry.url} entry={entry} />
          ))}

          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation();
              onAddClick();
            }}
            className="flex h-16 w-16 shrink-0 items-center justify-center rounded-lg border border-dashed border-white/20 text-white/40 transition-colors hover:border-white/40 hover:text-white/60"
          >
            <Plus className="size-5" />
          </button>
        </div>
        <ScrollBar orientation="horizontal" />
      </ScrollArea>

      {items.length > 0 && (
        <AttachmentLightbox
          items={items}
          openIndex={openIndex}
          onOpenChange={setOpenIndex}
          onRemove={(item) => onRemove(item.id)}
        />
      )}
    </>
  );
}
