"use client"

import { useEffect, useRef, useState } from "react"
import { useQueryClient } from "@tanstack/react-query"
import { File, FileText, Image as ImageIcon, Play } from "lucide-react"
import type { EmailAttachment, EmailAttachmentKind } from "@/lib/email-data"
import { resolveAttachmentKind } from "@/lib/attachment-display"
import {
  mailAttachmentCanThumb,
  useMailAttachmentThumb,
} from "@/lib/api/hooks/use-mail-attachment-thumb"
import { cn } from "@/lib/utils"

function useInView(rootMargin = "120px") {
  const ref = useRef<HTMLDivElement>(null)
  const [inView, setInView] = useState(false)

  useEffect(() => {
    const el = ref.current
    if (!el) return
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry?.isIntersecting) {
          setInView(true)
          observer.disconnect()
        }
      },
      { rootMargin }
    )
    observer.observe(el)
    return () => observer.disconnect()
  }, [rootMargin])

  return { ref, inView }
}

function AttachmentKindFallback({ kind }: { kind: EmailAttachmentKind }) {
  if (kind === "image") {
    return <ImageIcon className="size-11 text-[#9aa0a6]" strokeWidth={1.25} aria-hidden />
  }
  if (kind === "pdf") {
    return (
      <div
        className="rounded border border-border bg-mail-surface px-4 py-5 shadow-sm"
        aria-hidden
      >
        <span className="text-[11px] font-bold leading-none text-[#d93025]">PDF</span>
      </div>
    )
  }
  return <File className="size-11 text-[#9aa0a6]" strokeWidth={1.25} aria-hidden />
}

function ThumbMedia({
  url,
  display,
  onError,
}: {
  url: string
  display: "image" | "video"
  onError: () => void
}) {
  if (display === "video") {
    return (
      <>
        <video
          src={url}
          muted
          playsInline
          preload="metadata"
          className="h-full w-full object-cover"
          onLoadedData={(e) => {
            const v = e.currentTarget
            if (v.currentTime === 0) v.currentTime = 0.1
          }}
          onError={onError}
        />
        <div
          className="pointer-events-none absolute inset-0 flex items-center justify-center bg-black/15"
          aria-hidden
        >
          <div className="flex size-9 items-center justify-center rounded-full bg-black/50 shadow-md">
            <Play className="ml-0.5 size-4 fill-white text-white" />
          </div>
        </div>
      </>
    )
  }

  return (
    <img
      src={url}
      alt=""
      className="h-full w-full object-cover"
      draggable={false}
      onError={onError}
    />
  )
}

export function MailAttachmentThumbnail({
  attachment,
  className,
}: {
  attachment: EmailAttachment
  className?: string
}) {
  const kind = resolveAttachmentKind(attachment.name, attachment.kind)
  const { ref, inView } = useInView()
  const [failed, setFailed] = useState(false)
  const retriedRef = useRef(false)
  const queryClient = useQueryClient()
  const canThumb = mailAttachmentCanThumb(attachment)
  const showThumb = canThumb && !failed
  const { data, isLoading } = useMailAttachmentThumb(attachment, inView && showThumb)

  useEffect(() => {
    retriedRef.current = false
    setFailed(false)
  }, [attachment.id, attachment.drivePath, attachment.name])

  const handleError = () => {
    if (!retriedRef.current && data?.url.startsWith("blob:")) {
      retriedRef.current = true
      void queryClient.invalidateQueries({
        queryKey: ["mail", "attachment-thumb", attachment.id],
      })
      return
    }
    setFailed(true)
  }

  const showFallback = !showThumb || failed || (!data && !isLoading)

  return (
    <div
      ref={ref}
      className={cn(
        "relative flex h-[132px] shrink-0 flex-col items-center justify-center overflow-hidden bg-linear-to-b from-muted to-muted/70 dark:from-[#3c4043] dark:to-[#303134]",
        className
      )}
    >
      {showFallback ? (
        <div className={cn("flex items-center justify-center", isLoading && showThumb && "opacity-40")}>
          <AttachmentKindFallback kind={kind} />
        </div>
      ) : null}

      {showThumb && isLoading ? (
        <div className="absolute inset-0 animate-pulse bg-muted/80" aria-hidden />
      ) : null}

      {showThumb && data ? (
        <div className="absolute inset-0 overflow-hidden bg-[#e8eaed] dark:bg-[#303134]">
          <ThumbMedia url={data.url} display={data.display} onError={handleError} />
        </div>
      ) : null}
    </div>
  )
}

export function MailAttachmentPillThumb({
  attachment,
  className,
}: {
  attachment: EmailAttachment
  className?: string
}) {
  const kind = resolveAttachmentKind(attachment.name, attachment.kind)
  const { ref, inView } = useInView("80px")
  const [failed, setFailed] = useState(false)
  const canThumb = mailAttachmentCanThumb(attachment) && kind === "image"
  const { data, isLoading } = useMailAttachmentThumb(attachment, inView && canThumb && !failed)

  if (!canThumb || failed) {
    if (kind === "pdf") {
      return <FileText className={cn("size-4 shrink-0 text-[#d93025]", className)} strokeWidth={1.5} aria-hidden />
    }
    if (kind === "image") {
      return (
        <ImageIcon
          className={cn(
            "size-4 shrink-0 text-muted-foreground [&_circle]:fill-none [&_path]:fill-none [&_path]:stroke-current [&_rect]:fill-current [&_rect]:opacity-[0.32]",
            className
          )}
          strokeWidth={1.5}
          aria-hidden
        />
      )
    }
    return <File className={cn("size-4 shrink-0 text-[#5f6368]", className)} strokeWidth={1.5} aria-hidden />
  }

  return (
    <span
      ref={ref}
      className={cn(
        "relative flex size-6 shrink-0 overflow-hidden rounded-full bg-muted",
        isLoading && "animate-pulse",
        className
      )}
    >
      {data ? (
        <img
          src={data.url}
          alt=""
          className="size-full object-cover"
          draggable={false}
          onError={() => setFailed(true)}
        />
      ) : null}
    </span>
  )
}
