import { useState, useEffect, useRef, useMemo, memo } from 'react'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  User,
  Heart,
  Edit,
  Save,
  X,
  Loader2,
  RefreshCw,
  Video,
  Pin,
  Maximize2,
  Play,
  ImagePlus,
  Lock,
  Image as ImageIcon,
  ExternalLink,
  Link,
  Plus,
  Download,
  AlertTriangle,
  Upload,
  Clock,
  Trash2,
  CheckSquare,
  Check,
  Music,
} from 'lucide-react'
import { api, PaidContentPost, PaidContentAttachment, wsClient } from '../../lib/api'
import TagSearchSelector from '../private-gallery/TagSearchSelector'
import { notificationManager } from '../../lib/notificationManager'
import { decodeHtmlEntities, cleanCaption, formatPlatformName, THUMB_CACHE_V } from '../../lib/utils'

// Platform badge colors: bg class + text class
function getPlatformBadgeClasses(platform: string): string {
  switch (platform?.toLowerCase()) {
    case 'onlyfans': return 'bg-sky-500/15 text-sky-500'
    case 'fansly': return 'bg-cyan-400/15 text-cyan-400'
    case 'instagram': return 'bg-pink-500/15 text-pink-500'
    case 'tiktok': return 'bg-fuchsia-500/15 text-fuchsia-400'
    case 'snapchat': return 'bg-yellow-400/15 text-yellow-500'
    case 'youtube': return 'bg-red-500/15 text-red-500'
    case 'twitch': return 'bg-purple-500/15 text-purple-400'
    case 'pornhub': return 'bg-orange-500/15 text-orange-400'
    case 'xhamster': return 'bg-amber-600/15 text-amber-500'
    case 'patreon': return 'bg-orange-400/15 text-orange-400'
    case 'soundgasm': return 'bg-emerald-500/15 text-emerald-400'
    case 'bellazon': return 'bg-indigo-500/15 text-indigo-400'
    case 'reddit': return 'bg-orange-600/15 text-orange-500'
    case 'hqcelebcorner': return 'bg-rose-500/15 text-rose-400'
    case 'picturepub': return 'bg-teal-500/15 text-teal-400'
    case 'coppermine': return 'bg-lime-500/15 text-lime-400'
    case 'besteyecandy': return 'bg-violet-500/15 text-violet-400'
    case 'candfans': return 'bg-pink-400/15 text-pink-400'
    default: return 'bg-secondary text-muted-foreground'
  }
}

// Truncate long filenames (e.g. story keys)
function truncateFilename(name: string, maxLen: number = 17): string {
  if (!name || name.length <= maxLen) return name
  const dotIdx = name.lastIndexOf('.')
  const ext = dotIdx > 0 ? name.slice(dotIdx) : ''
  const base = dotIdx > 0 ? name.slice(0, dotIdx) : name
  const keep = maxLen - ext.length - 3
  return base.slice(0, keep) + '...' + ext
}

// Format file size helper
function formatFileSize(bytes: number | null): string {
  if (!bytes) return ''
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
}

// Format duration helper
function formatDuration(seconds: number | null): string {
  if (!seconds) return ''
  const hrs = Math.floor(seconds / 3600)
  const mins = Math.floor((seconds % 3600) / 60)
  const secs = Math.floor(seconds % 60)
  if (hrs > 0) {
    return `${hrs}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
  }
  return `${mins}:${secs.toString().padStart(2, '0')}`
}



interface PostDetailViewProps {
  post: PaidContentPost
  onClose?: () => void
  onPostUpdated?: (updatedPost?: Partial<PaidContentPost>) => void
  onOpenLightbox: (attachmentIndex: number, isVideo?: boolean, startTime?: number, wasPlaying?: boolean) => void
  videoReturnState?: { attachmentId: number; time: number; wasPlaying: boolean } | null
  onVideoReturnStateHandled?: () => void
  /** Compact mode for mobile scroll feed - hides some controls */
  compactMode?: boolean
  /** Custom URL generators for media files (used by private gallery) */
  getVideoUrl?: (attachment: { id: number; local_path?: string | null }) => string | null
  getThumbnailUrl?: (attachment: { id: number }) => string
  getImageUrl?: (attachment: { id: number; local_path?: string | null }) => string | null
  /** Hide edit and favorite controls (for private gallery) */
  hideControls?: boolean
  /** Show all media as thumbnails (no inline video players) */
  thumbnailsOnly?: boolean
  /** Custom edit handler - if provided, shows edit button even with hideControls */
  onEdit?: () => void
  /** Callback to copy post to private gallery */
  onCopyToGallery?: () => void
  /** Highlight background (e.g. for pinned posts) */
  highlighted?: boolean
}

function PostDetailView({
  post,
  onClose: _onClose,
  onPostUpdated,
  onOpenLightbox,
  videoReturnState,
  onVideoReturnStateHandled,
  compactMode = false,
  getVideoUrl: customGetVideoUrl,
  getThumbnailUrl: customGetThumbnailUrl,
  getImageUrl: customGetImageUrl,
  hideControls = false,
  thumbnailsOnly = false,
  onEdit,
  onCopyToGallery,
  highlighted = false,
}: PostDetailViewProps) {
  // Default URL generators for paid content
  const getVideoUrl = customGetVideoUrl || ((att: { id: number; local_path?: string | null; file_token?: string | null }) =>
    att.local_path ? (att.file_token ? `/api/paid-content/files/serve?t=${encodeURIComponent(att.file_token)}` : `/api/paid-content/files/serve?path=${encodeURIComponent(att.local_path)}`) : null
  )
  const getThumbnailUrl = customGetThumbnailUrl || ((att: { id: number; file_hash?: string | null }) =>
    `/api/paid-content/files/thumbnail/${att.id}?size=large&${att.file_hash ? `v=${att.file_hash.slice(0, 8)}` : THUMB_CACHE_V}`
  )
  const useNativeAspect = true
  const isNativePosterPlatform = ['onlyfans', 'fansly'].includes(post.platform?.toLowerCase() || '')
  const getVideoPosterUrl = (att: { id: number; file_hash?: string | null }) =>
    `/api/paid-content/files/thumbnail/${att.id}?size=${isNativePosterPlatform ? 'native' : 'large'}&${att.file_hash ? `v=${att.file_hash.slice(0, 8)}` : THUMB_CACHE_V}`
  void customGetImageUrl // Suppress unused parameter warning (available for future use)
  const [isEditing, setIsEditing] = useState(false)
  const [editTitle, setEditTitle] = useState(post.title || '')
  const [importAttachment, setImportAttachment] = useState<PaidContentAttachment | null>(null)

  // Track video elements by attachment ID
  const videoRefs = useRef<Map<number, HTMLVideoElement>>(new Map())
  const [editContent, setEditContent] = useState(post.content || '')
  const [editDate, setEditDate] = useState(post.published_at?.split('T')[0] || '')
  const [editTags, setEditTags] = useState<number[]>(post.tags?.map(t => t.id) || [])
  const [editTaggedUsers, setEditTaggedUsers] = useState<string[]>(post.tagged_users || [])
  const [newTaggedUser, setNewTaggedUser] = useState('')
  const [suggestionIndex, setSuggestionIndex] = useState(-1)
  const [showSuggestions, setShowSuggestions] = useState(false)
  const suggestionsRef = useRef<HTMLDivElement>(null)
  const blurTimeoutRef = useRef<ReturnType<typeof setTimeout>>()
  const queryClient = useQueryClient()

  // Delete state (mirrors Private Gallery pattern)
  const [deletingAttachmentId, setDeletingAttachmentId] = useState<number | null>(null)
  const [confirmDeleteId, setConfirmDeleteId] = useState<number | null>(null)
  const [selectionMode, setSelectionMode] = useState(false)
  const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set())
  const [isBatchDeleting, setIsBatchDeleting] = useState(false)
  const lastSelectedAttIdx = useRef<number | null>(null)

  // Fetch available tags
  const { data: availableTags = [] } = useQuery({
    queryKey: ['paid-content-tags'],
    queryFn: () => api.paidContent.getTags(),
  })

  // Fetch all known tagged usernames for autocomplete
  const { data: allTaggedUsers = [] } = useQuery({
    queryKey: ['paid-content-tagged-users-all'],
    queryFn: () => api.paidContent.getTaggedUsers(),
  })

  // Filtered suggestions for tagged users autocomplete
  const taggedUserSuggestions = useMemo(() => {
    if (!newTaggedUser.trim()) return []
    const query = newTaggedUser.trim().toLowerCase()
    return allTaggedUsers
      .map(u => u.username)
      .filter(u => u.toLowerCase().includes(query) && !editTaggedUsers.includes(u))
      .sort((a, b) => {
        // Prefer prefix matches
        const aStarts = a.toLowerCase().startsWith(query)
        const bStarts = b.toLowerCase().startsWith(query)
        if (aStarts && !bStarts) return -1
        if (!aStarts && bStarts) return 1
        return a.localeCompare(b)
      })
      .slice(0, 10)
  }, [newTaggedUser, allTaggedUsers, editTaggedUsers])

  // Update edit state when post changes
  useEffect(() => {
    setEditTitle(post.title || '')
    setEditContent(post.content || '')
    setEditDate(post.published_at?.split('T')[0] || '')
    setEditTags(post.tags?.map(t => t.id) || [])
    setEditTaggedUsers(post.tagged_users || [])
    setNewTaggedUser('')
    setIsEditing(false)
    setConfirmDeleteId(null)
    setDeletingAttachmentId(null)
    setSelectionMode(false)
    setSelectedIds(new Set())
  }, [post.id])

  // Handle video state returned from lightbox
  useEffect(() => {
    if (videoReturnState) {
      const video = videoRefs.current.get(videoReturnState.attachmentId)
      if (video) {
        // Set the time position
        video.currentTime = videoReturnState.time
        // Play or pause based on lightbox state
        if (videoReturnState.wasPlaying) {
          video.play().catch(() => {})
        }
      }
      // Clear the return state
      onVideoReturnStateHandled?.()
    }
  }, [videoReturnState, onVideoReturnStateHandled])

  // Mutation for updating post
  const updateMutation = useMutation({
    mutationFn: (data: { title?: string; content?: string; published_at?: string }) =>
      api.put(`/paid-content/feed/${post.id}`, data),
    onSuccess: (_, variables) => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      setIsEditing(false)
      onPostUpdated?.(variables)
    },
  })

  // Mutation for refreshing metadata
  const refreshMutation = useMutation({
    mutationFn: () => api.post(`/paid-content/feed/${post.id}/refresh`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      onPostUpdated?.()
    },
  })

  // Mutation for updating tags
  const tagsMutation = useMutation({
    mutationFn: (tagIds: number[]) => api.paidContent.setPostTags(post.id, tagIds),
    onSuccess: (_, tagIds) => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      setIsEditing(false)
      const updatedTags = availableTags.filter(t => tagIds.includes(t.id))
      onPostUpdated?.({ tags: updatedTags })
    },
  })

  // Mutation for updating tagged users
  const taggedUsersMutation = useMutation({
    mutationFn: (usernames: string[]) => api.paidContent.setPostTaggedUsers(post.id, usernames),
    onSuccess: (updatedUsers) => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      setIsEditing(false)
      onPostUpdated?.({ tagged_users: updatedUsers })
    },
  })

  // Favorite mutation
  const favoriteMutation = useMutation({
    mutationFn: () => api.paidContent.toggleFavorite(post.id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      onPostUpdated?.()
    },
  })

  // Watch later
  const { data: watchLaterIds = [] } = useQuery({
    queryKey: ['paid-content-watch-later-ids'],
    queryFn: () => api.paidContent.getWatchLaterAttachmentIds(),
    staleTime: 30000,
  })
  const watchLaterSet = new Set(watchLaterIds)
  const hasWatchLaterItems = post.attachments?.some(a => a.status === 'completed' && watchLaterSet.has(a.id))
  const firstCompletedAttachment = post.attachments?.find(a => a.status === 'completed')

  const addWatchLaterMutation = useMutation({
    mutationFn: (attachmentId: number) => api.paidContent.addToWatchLater(attachmentId),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['paid-content-watch-later-ids'] }),
  })

  const removeWatchLaterMutation = useMutation({
    mutationFn: (attachmentId: number) => api.paidContent.removeFromWatchLater(attachmentId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['paid-content-watch-later-ids'] })
      queryClient.invalidateQueries({ queryKey: ['paid-content-watch-later'] })
    },
  })

  const toggleWatchLater = () => {
    if (!firstCompletedAttachment) return
    if (hasWatchLaterItems) {
      post.attachments?.filter(a => a.status === 'completed' && watchLaterSet.has(a.id))
        .forEach(a => removeWatchLaterMutation.mutate(a.id))
    } else {
      addWatchLaterMutation.mutate(firstCompletedAttachment.id)
    }
  }

  // Quality recheck state
  const [recheckStatus, setRecheckStatus] = useState<'idle' | 'checking' | 'done'>('idle')
  const [recheckResult, setRecheckResult] = useState<string | null>(null)
  const recheckAttIdsRef = useRef<Set<number>>(new Set())

  const recheckQualityMutation = useMutation({
    mutationFn: (attachmentIds: number[]) => {
      recheckAttIdsRef.current = new Set(attachmentIds)
      return api.paidContent.recheckQuality(attachmentIds)
    },
    onSuccess: (data) => {
      setRecheckStatus('checking')
      setRecheckResult(`Checking ${data.count} video${data.count !== 1 ? 's' : ''} for higher quality...`)
    },
    onError: () => {
      setRecheckStatus('idle')
      setRecheckResult(null)
      notificationManager.error('Quality Recheck', 'Failed to start quality recheck')
    },
  })

  // Listen for WebSocket result — only react if this component triggered it
  useEffect(() => {
    if (recheckStatus !== 'checking') return

    const unsubscribe = wsClient.on('quality_recheck_complete', (data) => {
      // Check if any of the results match our requested attachment IDs
      const results = data.results || []
      const ours = results.filter((r: { attachment_id: number }) => recheckAttIdsRef.current.has(r.attachment_id))
      if (ours.length === 0) return

      const upgraded = ours.filter((r: { upgraded: boolean }) => r.upgraded).length
      const pending = ours.filter((r: { pending?: { width: number; height: number; type: string } }) => r.pending)
      if (upgraded > 0) {
        setRecheckResult(`Upgraded ${upgraded}/${ours.length} to higher quality!`)
        notificationManager.success('Quality Recheck', `Upgraded ${upgraded} video${upgraded !== 1 ? 's' : ''} to higher quality!`)
        queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      } else if (pending.length > 0) {
        const p = pending[0].pending as { width: number; height: number; type: string }
        setRecheckResult(`${p.width}x${p.height} ${p.type} exists but still processing - will auto-retry`)
      } else {
        setRecheckResult(`Already at best available quality`)
      }
      setRecheckStatus('done')
      recheckAttIdsRef.current = new Set()
      setTimeout(() => { setRecheckStatus('idle'); setRecheckResult(null) }, 8000)
    })
    return () => unsubscribe()
  }, [recheckStatus, queryClient])

  const handleSave = async () => {
    const updates: { title?: string; content?: string; published_at?: string } = {}
    const originalTitle = post.title || ''
    const originalContent = post.content || ''
    const originalDate = post.published_at?.split('T')[0] || ''

    if (editTitle !== originalTitle) updates.title = editTitle
    if (editContent !== originalContent) updates.content = editContent
    if (editDate !== originalDate) updates.published_at = editDate ? `${editDate}T12:00:00` : undefined

    const currentTagIds = post.tags?.map(t => t.id) || []
    const tagsChanged = editTags.length !== currentTagIds.length ||
      editTags.some(id => !currentTagIds.includes(id))

    const currentTaggedUsers = post.tagged_users || []
    const taggedUsersChanged = editTaggedUsers.length !== currentTaggedUsers.length ||
      editTaggedUsers.some(u => !currentTaggedUsers.includes(u)) ||
      currentTaggedUsers.some(u => !editTaggedUsers.includes(u))

    if (Object.keys(updates).length > 0) {
      updateMutation.mutate(updates)
    }

    if (tagsChanged) {
      tagsMutation.mutate(editTags)
    }

    if (taggedUsersChanged) {
      taggedUsersMutation.mutate(editTaggedUsers)
    }

    if (Object.keys(updates).length === 0 && !tagsChanged && !taggedUsersChanged) {
      setIsEditing(false)
    }
  }

  // Filter to completed attachments (moved up so delete handlers can reference it)
  const completedAttachments = post.attachments?.filter((a) => a.status === 'completed') || []

  // Delete attachment handler
  const handleDeleteAttachment = async (attachmentId: number) => {
    // If this is the last attachment, offer to delete the entire post
    if (completedAttachments.length === 1) {
      setConfirmDeleteId(null)
      if (confirm('This is the last attachment. Delete the entire post?')) {
        try {
          await api.paidContent.deletePost(post.id)
          queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
          _onClose?.()
        } catch (error) {
          console.error('Failed to delete post:', error)
          alert('Failed to delete post')
        }
      }
      return
    }

    setDeletingAttachmentId(attachmentId)
    setConfirmDeleteId(null)

    try {
      await api.paidContent.deleteAttachment(post.id, attachmentId, true)
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      onPostUpdated?.()
    } catch (error) {
      console.error('Failed to delete attachment:', error)
      alert('Failed to delete attachment')
    } finally {
      setDeletingAttachmentId(null)
    }
  }

  // Batch delete handler
  const handleBatchDelete = async () => {
    if (selectedIds.size === 0) return

    // If deleting all attachments, offer to delete the post
    if (selectedIds.size === completedAttachments.length) {
      if (confirm(`Delete all ${completedAttachments.length} attachments and the entire post? This cannot be undone.`)) {
        try {
          setIsBatchDeleting(true)
          await api.paidContent.deletePost(post.id)
          queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
          _onClose?.()
        } catch (error) {
          console.error('Failed to delete post:', error)
          alert('Failed to delete post')
        } finally {
          setIsBatchDeleting(false)
        }
      }
      return
    }

    if (!confirm(`Delete ${selectedIds.size} selected attachment${selectedIds.size > 1 ? 's' : ''}?`)) return

    setIsBatchDeleting(true)
    try {
      const idsToDelete = Array.from(selectedIds)
      for (const id of idsToDelete) {
        await api.paidContent.deleteAttachment(post.id, id, true)
      }
      setSelectedIds(new Set())
      setSelectionMode(false)
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      onPostUpdated?.()
    } catch (error) {
      console.error('Failed to batch delete:', error)
      alert('Some attachments failed to delete')
    } finally {
      setIsBatchDeleting(false)
    }
  }

  const imageExts = ['jpg', 'jpeg', 'png', 'webp', 'gif']
  // Video preview frames (file_type=video but extension=jpg) are treated as images
  const isPreviewFrame = (a: { file_type?: string | null; extension?: string | null }) =>
    a.file_type === 'video' && imageExts.includes(a.extension?.toLowerCase() || '')
  const videoAttachments = completedAttachments.filter(a => a.file_type === 'video' && !isPreviewFrame(a))
  const audioAttachments = completedAttachments.filter(a => a.file_type === 'audio')
  const imageAttachments = completedAttachments.filter(a => a.file_type === 'image' || isPreviewFrame(a))
  const previewFrameIds = new Set(completedAttachments.filter(isPreviewFrame).map(a => a.id))
  const hasDrmContent = previewFrameIds.size > 0
  const unavailableAttachments = post.attachments?.filter((a) => a.status === 'unavailable') || []

  // Build platform URL for DRM-protected posts
  const getPlatformPostUrl = (): string | null => {
    if (!hasDrmContent || !post.post_id) return null
    if (post.service_id === 'onlyfans_direct' || post.platform === 'onlyfans') {
      return `https://onlyfans.com/${post.post_id}/${post.username}`
    }
    if (post.service_id === 'fansly_direct' || post.platform === 'fansly') {
      return `https://fansly.com/post/${post.post_id}`
    }
    return null
  }
  const platformPostUrl = getPlatformPostUrl()

  // Fansly sub-4K video attachments eligible for quality recheck
  const recheckableAttachments = post.service_id === 'fansly_direct'
    ? (post.attachments || []).filter(a =>
        a.file_type === 'video' &&
        a.width != null && a.height != null &&
        a.width < 3840 && a.height < 3840
      )
    : []

  // Format the date nicely
  const formatPostDate = (dateStr: string | null) => {
    if (!dateStr) return 'Unknown date'
    const date = new Date(dateStr)
    return date.toLocaleDateString('en-US', {
      month: 'long',
      day: 'numeric',
      year: 'numeric'
    })
  }

  const renderActionButtons = () => (
    <>
      {!compactMode && !hideControls && (
        isEditing ? (
          <>
            <button
              onClick={() => setIsEditing(false)}
              className="p-2 rounded-lg hover:bg-secondary transition-colors text-muted-foreground"
              title="Cancel"
            >
              <X className="w-5 h-5" />
            </button>
            <button
              onClick={handleSave}
              disabled={updateMutation.isPending || tagsMutation.isPending}
              className="p-2 rounded-lg hover:bg-secondary transition-colors text-primary"
              title="Save"
            >
              {updateMutation.isPending || tagsMutation.isPending ? (
                <Loader2 className="w-5 h-5 animate-spin" />
              ) : (
                <Save className="w-5 h-5" />
              )}
            </button>
          </>
        ) : (
          <>
            <button
              onClick={() => refreshMutation.mutate()}
              disabled={refreshMutation.isPending}
              className="p-2 rounded-lg hover:bg-secondary transition-colors text-muted-foreground"
              title="Refresh from source"
            >
              {refreshMutation.isPending ? (
                <Loader2 className="w-5 h-5 animate-spin" />
              ) : (
                <RefreshCw className="w-5 h-5" />
              )}
            </button>
            <button
              type="button"
              onClick={(e) => {
                e.stopPropagation()
                if (selectionMode) {
                  setSelectionMode(false)
                  setSelectedIds(new Set())
                } else {
                  setSelectionMode(true)
                }
              }}
              className={`p-2 rounded-lg hover:bg-secondary active:bg-secondary/80 transition-colors min-w-[40px] min-h-[40px] flex items-center justify-center ${
                selectionMode ? 'text-primary bg-primary/10' : 'text-muted-foreground'
              }`}
              style={{ touchAction: 'manipulation', WebkitTapHighlightColor: 'transparent' }}
              title={selectionMode ? 'Cancel selection' : 'Select items to delete'}
            >
              <CheckSquare className="w-5 h-5" />
            </button>
            <button
              onClick={() => setIsEditing(true)}
              className="p-2 rounded-lg hover:bg-secondary transition-colors text-muted-foreground"
              title="Edit"
            >
              <Edit className="w-5 h-5" />
            </button>
            <button
              type="button"
              onClick={async (e) => {
                e.stopPropagation()
                if (confirm('Delete this post and all its media? This cannot be undone.')) {
                  try {
                    await api.paidContent.deletePost(post.id)
                    await queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
                    _onClose?.()
                  } catch (error) {
                    console.error('Failed to delete post:', error)
                    alert('Failed to delete post')
                  }
                }
              }}
              className="flex p-2 rounded-lg hover:bg-destructive/20 transition-colors min-w-[40px] min-h-[40px] items-center justify-center"
              title="Delete post"
            >
              <Trash2 className="w-5 h-5 text-destructive" />
            </button>
          </>
        )
      )}
      {!compactMode && hideControls && onEdit && (
        <button
          onClick={onEdit}
          className="p-2 rounded-lg hover:bg-secondary transition-colors text-muted-foreground"
          title="Edit"
        >
          <Edit className="w-5 h-5" />
        </button>
      )}
    </>
  )

  return (
    <div className={`h-full overflow-y-auto ${highlighted ? 'bg-amber-50/60 dark:bg-amber-900/15' : 'bg-card'}`}>
      {/* Creator Header - Fansly style */}
      <div className={`p-4 border-b border-border sticky top-0 z-10 ${highlighted ? 'bg-amber-50/80 dark:bg-amber-900/25' : 'bg-card'}`}>
        <div className="flex items-center justify-between">
          <div className="flex items-center space-x-3">
            <div className="w-12 h-12 rounded-full bg-gradient-to-br from-pink-500 to-violet-500 p-0.5">
              <div className="w-full h-full rounded-full overflow-hidden bg-card">
                {post.profile_image_url ? (
                  <img src={post.profile_image_url} alt="" className="w-full h-full object-cover" />
                ) : (
                  <div className="w-full h-full flex items-center justify-center bg-secondary">
                    <User className="w-6 h-6 text-muted-foreground" />
                  </div>
                )}
              </div>
            </div>
            <div>
              <div className="flex items-center gap-2">
                <span className="font-semibold text-foreground">{post.display_name || post.username}</span>
              </div>
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <span>@{post.username}</span>
                <span className="hidden sm:inline">·</span>
                <span className={`px-1.5 py-0.5 rounded-full text-xs font-medium ${getPlatformBadgeClasses(post.platform)}`}>
                  {formatPlatformName(post.platform)}
                </span>
                {post.is_pinned === 1 && (
                  <>
                    <span className="sm:hidden">·</span>
                    <span className="flex items-center gap-1 text-amber-500 sm:hidden">
                      <Pin className="w-3 h-3" />
                      Pinned
                    </span>
                  </>
                )}
                <span className="hidden sm:inline">·</span>
                <span className="hidden sm:inline">{formatPostDate(post.published_at)}</span>
                {post.is_pinned === 1 && (
                  <span className="hidden sm:flex items-center gap-1 text-amber-500">
                    <span>·</span>
                    <Pin className="w-3 h-3 ml-1" />
                    Pinned
                  </span>
                )}
              </div>
              <div className="flex items-center gap-2 text-sm text-muted-foreground sm:hidden">
                <span>{formatPostDate(post.published_at)}</span>
              </div>
            </div>
          </div>
          <div className="hidden lg:flex items-center gap-1">
            {!isEditing && post.tags && post.tags.length > 0 && (
              <div className="flex flex-wrap gap-1 mr-2">
                {[...post.tags].sort((a, b) => {
                  const aIsPpv = a.slug === 'ppv' || a.name === 'PPV' ? -1 : 0
                  const bIsPpv = b.slug === 'ppv' || b.name === 'PPV' ? -1 : 0
                  return aIsPpv - bIsPpv
                }).map((tag) => (
                  <span
                    key={tag.id}
                    className="px-2 py-0.5 rounded-full text-xs font-medium"
                    style={{ backgroundColor: tag.color, color: '#fff' }}
                  >
                    {tag.name}
                  </span>
                ))}
              </div>
            )}
            {renderActionButtons()}
          </div>
        </div>
        {/* Mobile: action buttons on separate row */}
        <div className="lg:hidden flex items-center gap-1 mt-2 ml-[3.75rem]">
          {renderActionButtons()}
        </div>
        {/* Tags row - mobile only */}
        {!isEditing && (post.tags?.length || hasDrmContent) ? (
          <div className="lg:hidden flex flex-wrap gap-1 mt-1 ml-[3.75rem]">
            {(post.tags || []).filter(t => t.slug === 'ppv' || t.name === 'PPV').map((tag) => (
              <span
                key={tag.id}
                className="px-2 py-0.5 rounded-full text-xs font-medium"
                style={{ backgroundColor: tag.color, color: '#fff' }}
              >
                {tag.name}
              </span>
            ))}
            {hasDrmContent && (
              <span className="inline-flex items-center gap-0.5 px-2 py-0.5 rounded-full text-xs font-medium bg-amber-500/15 text-amber-600 dark:text-amber-400">
                <Lock className="w-2.5 h-2.5" />
                DRM
              </span>
            )}
            {(post.tags || []).filter(t => t.slug !== 'ppv' && t.name !== 'PPV').map((tag) => (
              <span
                key={tag.id}
                className="px-2 py-0.5 rounded-full text-xs font-medium"
                style={{ backgroundColor: tag.color, color: '#fff' }}
              >
                {tag.name}
              </span>
            ))}
          </div>
        ) : null}
      </div>

      {/* Content */}
      <div className="p-4 space-y-4">
          {/* Post Content/Description */}
          {isEditing ? (
            <div className="space-y-4">
              <div className="space-y-2">
                <label className="text-sm font-medium text-foreground">Title</label>
                <input
                  type="text"
                  value={editTitle}
                  onChange={(e) => setEditTitle(e.target.value)}
                  className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
                  placeholder="Post title"
                />
              </div>
              <div className="space-y-2">
                <label className="text-sm font-medium text-foreground">Date</label>
                <input
                  type="date"
                  value={editDate}
                  onChange={(e) => setEditDate(e.target.value)}
                  className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-primary"
                />
              </div>
              <div className="space-y-2">
                <label className="text-sm font-medium text-foreground">Description</label>
                <textarea
                  value={editContent}
                  onChange={(e) => setEditContent(e.target.value)}
                  className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-foreground focus:outline-none focus:ring-2 focus:ring-primary min-h-[150px] resize-y"
                  placeholder="Post description"
                />
              </div>
              <div className="space-y-2">
                <TagSearchSelector
                  tags={availableTags}
                  selectedTagIds={editTags}
                  onChange={setEditTags}
                  label="Tags"
                />
              </div>
              <div className="space-y-2">
                <label className="text-sm font-medium text-foreground">Tagged Users</label>
                <div className="flex flex-wrap gap-1.5 mb-2">
                  {editTaggedUsers.map((username) => (
                    <span
                      key={`etu-${username}`}
                      className="px-2.5 py-1 rounded-full text-xs font-medium bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 flex items-center gap-1"
                    >
                      @{username}
                      <button
                        onClick={() => setEditTaggedUsers(editTaggedUsers.filter(u => u !== username))}
                        className="ml-0.5 hover:text-red-400 transition-colors"
                      >
                        &times;
                      </button>
                    </span>
                  ))}
                </div>
                <div className="flex gap-2">
                  <div className="relative flex-1">
                    <input
                      type="text"
                      value={newTaggedUser}
                      onChange={(e) => {
                        setNewTaggedUser(e.target.value.replace(/^@/, '').toLowerCase())
                        setShowSuggestions(true)
                        setSuggestionIndex(-1)
                      }}
                      onFocus={() => setShowSuggestions(true)}
                      onBlur={() => {
                        blurTimeoutRef.current = setTimeout(() => setShowSuggestions(false), 150)
                      }}
                      onKeyDown={(e) => {
                        if (e.key === 'ArrowDown') {
                          e.preventDefault()
                          if (showSuggestions && taggedUserSuggestions.length > 0) {
                            setSuggestionIndex(i => Math.min(i + 1, taggedUserSuggestions.length - 1))
                          }
                        } else if (e.key === 'ArrowUp') {
                          e.preventDefault()
                          if (showSuggestions && taggedUserSuggestions.length > 0) {
                            setSuggestionIndex(i => Math.max(i - 1, -1))
                          }
                        } else if (e.key === 'Escape') {
                          setShowSuggestions(false)
                          setSuggestionIndex(-1)
                        } else if (e.key === 'Enter') {
                          e.preventDefault()
                          const username = suggestionIndex >= 0 && suggestionIndex < taggedUserSuggestions.length
                            ? taggedUserSuggestions[suggestionIndex]
                            : newTaggedUser.trim()
                          if (username && !editTaggedUsers.includes(username)) {
                            setEditTaggedUsers([...editTaggedUsers, username])
                          }
                          setNewTaggedUser('')
                          setShowSuggestions(false)
                          setSuggestionIndex(-1)
                        }
                      }}
                      className="w-full px-3 py-2 bg-secondary border border-border rounded-lg text-foreground text-sm focus:outline-none focus:ring-2 focus:ring-primary"
                      placeholder="Add username..."
                      autoComplete="off"
                    />
                    {showSuggestions && taggedUserSuggestions.length > 0 && (
                      <div
                        ref={suggestionsRef}
                        className="absolute z-50 left-0 right-0 top-full mt-1 bg-secondary border border-border rounded-lg shadow-lg max-h-48 overflow-y-auto"
                      >
                        {taggedUserSuggestions.map((username, idx) => (
                          <button
                            key={username}
                            type="button"
                            onMouseDown={(e) => {
                              e.preventDefault()
                              clearTimeout(blurTimeoutRef.current)
                              if (!editTaggedUsers.includes(username)) {
                                setEditTaggedUsers([...editTaggedUsers, username])
                              }
                              setNewTaggedUser('')
                              setShowSuggestions(false)
                              setSuggestionIndex(-1)
                            }}
                            className={`w-full text-left px-3 py-1.5 text-sm transition-colors ${
                              idx === suggestionIndex
                                ? 'bg-primary/20 text-foreground'
                                : 'text-muted-foreground hover:bg-primary/10 hover:text-foreground'
                            }`}
                          >
                            @{username}
                          </button>
                        ))}
                      </div>
                    )}
                  </div>
                  <button
                    onClick={() => {
                      const username = newTaggedUser.trim()
                      if (username && !editTaggedUsers.includes(username)) {
                        setEditTaggedUsers([...editTaggedUsers, username])
                      }
                      setNewTaggedUser('')
                      setShowSuggestions(false)
                      setSuggestionIndex(-1)
                    }}
                    disabled={!newTaggedUser.trim()}
                    className="px-3 py-2 bg-cyan-600 text-white rounded-lg text-sm font-medium hover:bg-cyan-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
                  >
                    Add
                  </button>
                </div>
              </div>
            </div>
          ) : (
            <>
              {/* Post description - truncated on mobile, full on desktop */}
              {/* For YouTube/Twitch, show title AND description separately */}
              {(() => {
                const isVideoService = ['youtube', 'twitch', 'pornhub'].includes(post.platform?.toLowerCase() || '')
                if (isVideoService && post.title) {
                  return (
                    <div className="space-y-2">
                      <div className="text-foreground font-medium text-sm">
                        {decodeHtmlEntities(post.title)}
                      </div>
                      {post.content && post.content !== post.title && (
                        <div className={`text-muted-foreground whitespace-pre-wrap text-sm leading-relaxed ${compactMode ? 'line-clamp-3' : ''}`}>
                          {cleanCaption(decodeHtmlEntities(post.content))}
                        </div>
                      )}
                    </div>
                  )
                }
                const displayText = post.content || post.title
                return displayText ? (
                  <div className={`text-foreground whitespace-pre-wrap text-sm leading-relaxed ${compactMode ? 'line-clamp-3' : ''}`}>
                    {cleanCaption(decodeHtmlEntities(displayText))}
                  </div>
                ) : null
              })()}

              {/* Service origin note */}
              {post.tags?.some(t => t.name === 'Fansly' || t.name === 'OnlyFans') && (() => {
                const serviceTag = post.tags!.find(t => t.name === 'Fansly' || t.name === 'OnlyFans')
                return serviceTag ? (
                  <div className={`flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-lg ${getPlatformBadgeClasses(serviceTag.name.toLowerCase())}`}>
                    <ExternalLink className="w-3 h-3" />
                    This post is on {serviceTag.name}
                  </div>
                ) : null
              })()}

              {/* Inline Video Player */}
              {videoAttachments.length > 0 && (
                <div className={
                  useNativeAspect && videoAttachments.length > 1
                    ? `grid gap-1 grid-cols-2`
                    : 'space-y-3'
                }>
                  {videoAttachments.map((video, vidIdx) => {
                    const videoUrl = getVideoUrl(video)
                    const thumbUrl = getThumbnailUrl(video)
                    const posterUrl = getVideoPosterUrl(video)
                    const allIdx = completedAttachments.findIndex(a => a.id === video.id)
                    const isVideoConfirming = confirmDeleteId === video.id
                    const isVideoDeleting = deletingAttachmentId === video.id
                    const isVideoSelected = selectedIds.has(video.id)

                    return (
                      <div
                        key={video.id}
                        className={`relative rounded-xl overflow-hidden min-w-0 ${
                          useNativeAspect
                            ? `bg-secondary ${video.width && video.height && video.height >= video.width ? 'w-fit mx-auto' : ''}`
                            : 'bg-black'
                        } ${isVideoDeleting ? 'opacity-50' : ''}`}
                      >
                        {/* Selection checkbox for video */}
                        {selectionMode && (
                          <button
                            onClick={(e) => {
                              e.stopPropagation()
                              if (e.shiftKey && lastSelectedAttIdx.current !== null) {
                                const allVids = videoAttachments
                                const start = Math.min(lastSelectedAttIdx.current, vidIdx)
                                const end = Math.max(lastSelectedAttIdx.current, vidIdx)
                                const newIds = new Set(selectedIds)
                                for (let i = start; i <= end; i++) {
                                  newIds.add(allVids[i].id)
                                }
                                setSelectedIds(newIds)
                              } else {
                                const newIds = new Set(selectedIds)
                                if (isVideoSelected) {
                                  newIds.delete(video.id)
                                } else {
                                  newIds.add(video.id)
                                }
                                setSelectedIds(newIds)
                              }
                              lastSelectedAttIdx.current = vidIdx
                            }}
                            className={`absolute top-2 left-2 w-6 h-6 rounded-md border-2 flex items-center justify-center transition-colors z-20 ${
                              isVideoSelected
                                ? 'bg-primary border-primary text-primary-foreground'
                                : 'bg-black/50 border-white/70 text-transparent hover:border-white'
                            }`}
                          >
                            {isVideoSelected && <Check className="w-4 h-4" />}
                          </button>
                        )}

                        {/* Delete icon overlay for video (hover) */}
                        {!selectionMode && !hideControls && !compactMode && (
                          <button
                            onClick={(e) => {
                              e.stopPropagation()
                              setConfirmDeleteId(video.id)
                            }}
                            className="absolute top-2 right-2 w-7 h-7 rounded-full bg-red-500/80 flex items-center justify-center opacity-0 hover:!opacity-100 transition-opacity z-20 hover:bg-red-600"
                            title="Delete attachment"
                          >
                            <Trash2 className="w-4 h-4 text-white" />
                          </button>
                        )}

                        {/* Delete confirmation overlay for video */}
                        {isVideoConfirming && (
                          <div className="absolute inset-0 bg-black/80 flex flex-col items-center justify-center gap-2 p-2 z-20">
                            <AlertTriangle className="w-5 h-5 text-yellow-500" />
                            <span className="text-xs text-white text-center">Delete?</span>
                            <div className="flex gap-1">
                              <button
                                onClick={(e) => { e.stopPropagation(); handleDeleteAttachment(video.id) }}
                                className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
                              >
                                Yes
                              </button>
                              <button
                                onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(null) }}
                                className="px-2 py-1 text-xs bg-secondary text-foreground rounded hover:bg-secondary/80"
                              >
                                No
                              </button>
                            </div>
                          </div>
                        )}
                        {videoUrl ? (
                          <>
                            <div className="relative">
                              {(compactMode || thumbnailsOnly) ? (
                                /* Thumbnail with play button - opens lightbox */
                                video.width && video.height && video.height >= video.width ? (
                                  useNativeAspect ? (
                                  /* Portrait video: natural aspect ratio thumbnail */
                                  <button
                                    onClick={(e) => { e.stopPropagation(); onOpenLightbox(allIdx, true) }}
                                    className="w-full relative group"
                                  >
                                    <img
                                      src={thumbUrl}
                                      alt={video.name || 'Video thumbnail'}
                                      className="w-full h-auto max-h-[600px] object-contain"
                                    />
                                    {/* Play icon overlay */}
                                    <div className="absolute inset-0 flex items-center justify-center">
                                      <div className="w-16 h-16 rounded-full bg-white/90 flex items-center justify-center">
                                        <Play className="w-8 h-8 text-black ml-1" fill="currentColor" />
                                      </div>
                                    </div>
                                    {/* Duration badge */}
                                    {video.duration && (
                                      <div className="absolute bottom-2 right-2 px-2 py-0.5 bg-black/70 rounded text-white text-xs">
                                        {formatDuration(video.duration)}
                                      </div>
                                    )}
                                  </button>
                                  ) : (
                                  /* Portrait video: 16:9 container with blur fill */
                                  <button
                                    onClick={(e) => { e.stopPropagation(); onOpenLightbox(allIdx, true) }}
                                    className="w-full aspect-video relative group overflow-hidden"
                                  >
                                    {/* Blurred background */}
                                    <div
                                      className="absolute inset-0 scale-150"
                                      style={{
                                        backgroundImage: `url(${thumbUrl})`,
                                        backgroundSize: 'cover',
                                        backgroundPosition: 'center',
                                        filter: 'blur(20px) brightness(0.5)',
                                      }}
                                    />
                                    {/* Centered thumbnail */}
                                    <div className="absolute inset-0 flex items-center justify-center">
                                      <img
                                        src={thumbUrl}
                                        alt={video.name || 'Video thumbnail'}
                                        className="h-full object-contain"
                                        style={{ aspectRatio: `${video.width}/${video.height}` }}
                                      />
                                    </div>
                                    {/* Play icon overlay */}
                                    <div className="absolute inset-0 flex items-center justify-center">
                                      <div className="w-16 h-16 rounded-full bg-white/90 flex items-center justify-center">
                                        <Play className="w-8 h-8 text-black ml-1" fill="currentColor" />
                                      </div>
                                    </div>
                                    {/* Duration badge */}
                                    {video.duration && (
                                      <div className="absolute bottom-2 right-2 px-2 py-0.5 bg-black/70 rounded text-white text-xs">
                                        {formatDuration(video.duration)}
                                      </div>
                                    )}
                                  </button>
                                  )
                                ) : (
                                  /* Landscape video: normal 16:9 thumbnail */
                                  <button
                                    onClick={(e) => { e.stopPropagation(); onOpenLightbox(allIdx, true) }}
                                    className="w-full aspect-video relative group"
                                  >
                                    <img
                                      src={thumbUrl}
                                      alt={video.name || 'Video thumbnail'}
                                      className="w-full h-full object-cover"
                                    />
                                    {/* Play icon overlay */}
                                    <div className="absolute inset-0 flex items-center justify-center bg-black/30 group-hover:bg-black/40 transition-colors">
                                      <div className="w-16 h-16 rounded-full bg-white/90 flex items-center justify-center">
                                        <Play className="w-8 h-8 text-black ml-1" fill="currentColor" />
                                      </div>
                                    </div>
                                    {/* Duration badge */}
                                    {video.duration && (
                                      <div className="absolute bottom-2 right-2 px-2 py-0.5 bg-black/70 rounded text-white text-xs">
                                        {formatDuration(video.duration)}
                                      </div>
                                    )}
                                  </button>
                                )
                              ) : (
                                /* Desktop: Native video player */
                                <>
                                  {video.width && video.height && video.height >= video.width ? (
                                    useNativeAspect ? (
                                    /* Portrait video: natural aspect ratio like images */
                                    <div className="w-full flex justify-center">
                                      <video
                                        ref={(el) => {
                                          if (el) {
                                            videoRefs.current.set(video.id, el)
                                          } else {
                                            videoRefs.current.delete(video.id)
                                          }
                                        }}
                                        src={videoUrl || undefined}
                                        poster={posterUrl}
                                        className="max-h-[600px] max-w-full h-auto w-auto"
                                        style={{ aspectRatio: `${video.width}/${video.height}` }}
                                        controls
                                        playsInline
                                        preload="none"
                                        // @ts-ignore - AirPlay attributes
                                        x-webkit-airplay="allow"
                                        airplay="allow"
                                      />
                                    </div>
                                    ) : (
                                    /* Portrait video: same height as 16:9, blur fill on sides */
                                    <div className="w-full aspect-video relative overflow-hidden">
                                      {/* Blurred background */}
                                      <div
                                        className="absolute inset-0 scale-150"
                                        style={{
                                          backgroundImage: `url(${thumbUrl})`,
                                          backgroundSize: 'cover',
                                          backgroundPosition: 'center',
                                          filter: 'blur(20px) brightness(0.75)',
                                        }}
                                      />
                                      {/* Centered video */}
                                      <div className="absolute inset-0 flex items-center justify-center">
                                        <video
                                          ref={(el) => {
                                            if (el) {
                                              videoRefs.current.set(video.id, el)
                                            } else {
                                              videoRefs.current.delete(video.id)
                                            }
                                          }}
                                          src={videoUrl || undefined}
                                          poster={posterUrl}
                                          className="h-full"
                                          style={{ aspectRatio: `${video.width}/${video.height}` }}
                                          controls
                                          playsInline
                                          preload="none"
                                          // @ts-ignore - AirPlay attributes
                                          x-webkit-airplay="allow"
                                          airplay="allow"
                                        />
                                      </div>
                                    </div>
                                    )
                                  ) : (
                                    /* Landscape video: natural aspect ratio */
                                    <div className="w-full flex justify-center">
                                        <video
                                          ref={(el) => {
                                            if (el) {
                                              videoRefs.current.set(video.id, el)
                                            } else {
                                              videoRefs.current.delete(video.id)
                                            }
                                          }}
                                          src={videoUrl || undefined}
                                          poster={posterUrl}
                                          className="max-w-full h-auto"
                                          style={video.width && video.height ? { aspectRatio: `${video.width}/${video.height}` } : undefined}
                                          controls
                                          playsInline
                                          preload="none"
                                          // @ts-ignore - AirPlay attributes
                                          x-webkit-airplay="allow"
                                          airplay="allow"
                                        />
                                    </div>
                                  )}
                                  {/* Expand button - top left (for opening lightbox) */}
                                  <button
                                    onClick={(e) => {
                                      e.stopPropagation()
                                      const videoEl = videoRefs.current.get(video.id)
                                      if (videoEl) {
                                        const wasPlaying = !videoEl.paused
                                        videoEl.pause()
                                        onOpenLightbox(allIdx, true, videoEl.currentTime, wasPlaying)
                                      } else {
                                        onOpenLightbox(allIdx, true)
                                      }
                                    }}
                                    className="absolute left-3 top-3 z-10 p-2 bg-black/50 hover:bg-black/70 rounded-lg text-white transition-colors"
                                    title="Open in lightbox"
                                  >
                                    <Maximize2 className="w-5 h-5" />
                                  </button>
                                  {/* Favorite heart - middle right */}
                                  {!hideControls && (
                                    <button
                                      onClick={(e) => {
                                        e.stopPropagation()
                                        favoriteMutation.mutate()
                                      }}
                                      disabled={favoriteMutation.isPending}
                                      className="absolute right-3 top-1/2 -translate-y-1/2 z-10 p-2 text-white hover:text-red-400 transition-colors drop-shadow-[0_2px_4px_rgba(0,0,0,0.8)]"
                                    >
                                      <Heart className={`w-6 h-6 drop-shadow-[0_1px_2px_rgba(0,0,0,0.9)] ${post.is_favorited ? 'fill-red-500 text-red-500' : ''}`} />
                                    </button>
                                  )}
                                </>
                              )}
                            </div>
                            {/* Info bar below video */}
                            {/* Mobile: stacked layout */}
                            <div className="lg:hidden bg-secondary/80 px-3 py-1.5 text-xs text-muted-foreground">
                              <div className="flex items-center space-x-2">
                                {video.file_size && <span>{formatFileSize(video.file_size)}</span>}
                                {video.width && video.height && <span>{video.width}×{video.height}</span>}
                                {video.duration && <span>{formatDuration(video.duration)}</span>}
                              </div>
                              <div className="truncate mt-0.5">{truncateFilename(video.name || '')}</div>
                            </div>
                            {/* Desktop: single row - size+resolution left, duration center, filename right */}
                            <div className="hidden lg:grid bg-secondary/80 px-3 py-1.5 text-xs text-muted-foreground items-center" style={{ gridTemplateColumns: '1fr auto 1fr' }}>
                              <div className="flex items-center space-x-2">
                                {video.file_size && <span>{formatFileSize(video.file_size)}</span>}
                                {video.width && video.height && <span>{video.width}×{video.height}</span>}
                              </div>
                              <span>{video.duration ? formatDuration(video.duration) : ''}</span>
                              <span className="truncate text-right">{truncateFilename(video.name || '')}</span>
                            </div>
                          </>
                        ) : (
                          <div className="aspect-video flex items-center justify-center">
                            <div className="text-center text-white/60">
                              <Video className="w-12 h-12 mx-auto mb-2" />
                              <p>Video unavailable</p>
                            </div>
                          </div>
                        )}
                      </div>
                    )
                  })}
                </div>
              )}

              {/* Batch delete bar - top (shown when items are selected) */}
              {selectionMode && selectedIds.size > 0 && (
                <div className="p-3 bg-secondary/50 border border-border rounded-lg flex items-center justify-between gap-2">
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-medium">
                      {selectedIds.size} selected
                    </span>
                    <button
                      onClick={() => {
                        if (selectedIds.size === completedAttachments.length) {
                          setSelectedIds(new Set())
                        } else {
                          setSelectedIds(new Set(completedAttachments.map(a => a.id)))
                        }
                      }}
                      className="text-xs text-primary hover:underline"
                    >
                      {selectedIds.size === completedAttachments.length ? 'Deselect all' : 'Select all'}
                    </button>
                  </div>
                  <button
                    onClick={handleBatchDelete}
                    disabled={isBatchDeleting}
                    className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500 text-white text-sm font-medium rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50"
                  >
                    {isBatchDeleting ? (
                      <Loader2 className="w-4 h-4 animate-spin" />
                    ) : (
                      <Trash2 className="w-4 h-4" />
                    )}
                    Delete
                  </button>
                </div>
              )}

              {/* Inline Audio Player */}
              {audioAttachments.length > 0 && (
                <div className="space-y-2">
                  {audioAttachments.map((audio) => {
                    const audioUrl = getVideoUrl(audio)
                    const isAudioConfirming = confirmDeleteId === audio.id
                    const isAudioDeleting = deletingAttachmentId === audio.id
                    const isAudioSelected = selectedIds.has(audio.id)
                    const fileSizeMB = audio.file_size ? (audio.file_size / 1024 / 1024).toFixed(1) : null
                    return (
                      <div key={audio.id} className="relative rounded-lg border border-border bg-card/50 p-3">
                        <div className="flex items-center gap-3">
                          <div className="flex-shrink-0 w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center">
                            <Music className="w-5 h-5 text-primary" />
                          </div>
                          <div className="flex-1 min-w-0">
                            <div className="text-sm font-medium text-foreground truncate">
                              {audio.name || 'Audio'}
                            </div>
                            {fileSizeMB && (
                              <div className="text-xs text-muted-foreground">{fileSizeMB} MB</div>
                            )}
                          </div>
                          {selectionMode && (
                            <button
                              onClick={(e) => {
                                e.stopPropagation()
                                const newIds = new Set(selectedIds)
                                if (isAudioSelected) newIds.delete(audio.id)
                                else newIds.add(audio.id)
                                setSelectedIds(newIds)
                              }}
                              className={`p-1.5 rounded-md border ${isAudioSelected ? 'bg-primary border-primary text-primary-foreground' : 'border-border text-muted-foreground hover:text-foreground'}`}
                            >
                              {isAudioSelected ? <Check className="w-4 h-4" /> : <CheckSquare className="w-4 h-4" />}
                            </button>
                          )}
                          {!selectionMode && !isAudioConfirming && (
                            <button
                              onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(audio.id) }}
                              className="p-1.5 rounded-md text-muted-foreground hover:text-red-400 hover:bg-red-500/10 transition-colors"
                              title="Delete"
                            >
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                          {isAudioConfirming && (
                            <div className="flex items-center gap-1">
                              <button
                                onClick={(e) => { e.stopPropagation(); handleDeleteAttachment(audio.id) }}
                                disabled={isAudioDeleting}
                                className="px-2 py-1 text-xs rounded bg-red-600 text-white hover:bg-red-700"
                              >
                                {isAudioDeleting ? <Loader2 className="w-3 h-3 animate-spin" /> : 'Delete'}
                              </button>
                              <button
                                onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(null) }}
                                className="px-2 py-1 text-xs rounded bg-secondary text-foreground hover:bg-secondary/80"
                              >
                                Cancel
                              </button>
                            </div>
                          )}
                        </div>
                        <audio
                          src={audioUrl || undefined}
                          controls
                          preload="metadata"
                          className="w-full mt-2 h-10"
                          style={{ colorScheme: 'dark' }}
                        />
                      </div>
                    )
                  })}
                </div>
              )}

              {/* Image Grid - Fansly style with natural aspect ratios */}
              {imageAttachments.length > 0 && (
                <div className={`grid gap-1 ${
                  imageAttachments.length === 1 ? 'grid-cols-1' :
                  'grid-cols-2'
                }`}>
                  {imageAttachments.map((img, imgIdx) => {
                    const allIdx = completedAttachments.findIndex(a => a.id === img.id)
                    const imgThumbUrl = getThumbnailUrl(img)
                    const isConfirming = confirmDeleteId === img.id
                    const isDeleting = deletingAttachmentId === img.id
                    const isSelected = selectedIds.has(img.id)

                    const handleAttSelection = (e: React.MouseEvent) => {
                      if (e.shiftKey && lastSelectedAttIdx.current !== null) {
                        // Shift-click range select
                        const start = Math.min(lastSelectedAttIdx.current, imgIdx)
                        const end = Math.max(lastSelectedAttIdx.current, imgIdx)
                        const newIds = new Set(selectedIds)
                        for (let i = start; i <= end; i++) {
                          newIds.add(imageAttachments[i].id)
                        }
                        setSelectedIds(newIds)
                      } else {
                        const newIds = new Set(selectedIds)
                        if (isSelected) {
                          newIds.delete(img.id)
                        } else {
                          newIds.add(img.id)
                        }
                        setSelectedIds(newIds)
                      }
                      lastSelectedAttIdx.current = imgIdx
                    }

                    return (
                      <div
                        key={img.id}
                        className={`rounded-lg overflow-hidden bg-secondary relative ${useNativeAspect && img.width && img.height && img.height >= img.width ? 'w-fit mx-auto' : ''} ${isDeleting ? 'opacity-50' : ''}`}
                      >
                        <button
                          type="button"
                          className="relative cursor-pointer hover:ring-2 hover:ring-primary transition-all block w-full"
                          onClick={(e) => {
                            e.stopPropagation()
                            if (selectionMode) {
                              handleAttSelection(e)
                            } else {
                              onOpenLightbox(allIdx, false)
                            }
                          }}
                        >
                          <img
                            src={imgThumbUrl}
                            alt=""
                            className="w-full h-auto object-contain max-h-[600px]"
                            loading="lazy"
                          />

                          {/* Selection checkbox */}
                          {selectionMode && (
                            <button
                              onClick={(e) => {
                                e.stopPropagation()
                                handleAttSelection(e)
                              }}
                              className={`absolute top-1 left-1 w-6 h-6 rounded-md border-2 flex items-center justify-center transition-colors z-10 ${
                                isSelected
                                  ? 'bg-primary border-primary text-primary-foreground'
                                  : 'bg-black/50 border-white/70 text-transparent hover:border-white'
                              }`}
                            >
                              {isSelected && <Check className="w-4 h-4" />}
                            </button>
                          )}

                          {/* Delete icon overlay (hover) - shown when not in selection mode */}
                          {!selectionMode && !hideControls && !compactMode && (
                            <button
                              onClick={(e) => {
                                e.stopPropagation()
                                setConfirmDeleteId(img.id)
                              }}
                              className="absolute top-1 right-1 w-7 h-7 rounded-full bg-red-500/80 flex items-center justify-center opacity-0 group-hover:opacity-100 hover:!opacity-100 transition-opacity z-10 hover:bg-red-600"
                              title="Delete attachment"
                            >
                              <Trash2 className="w-4 h-4 text-white" />
                            </button>
                          )}

                          {/* Confirmation overlay */}
                          {isConfirming && (
                            <div className="absolute inset-0 bg-black/80 rounded-lg flex flex-col items-center justify-center gap-2 p-2 z-10">
                              <AlertTriangle className="w-5 h-5 text-yellow-500" />
                              <span className="text-xs text-white text-center">Delete?</span>
                              <div className="flex gap-1">
                                <button
                                  onClick={(e) => { e.stopPropagation(); handleDeleteAttachment(img.id) }}
                                  className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
                                >
                                  Yes
                                </button>
                                <button
                                  onClick={(e) => { e.stopPropagation(); setConfirmDeleteId(null) }}
                                  className="px-2 py-1 text-xs bg-secondary text-foreground rounded hover:bg-secondary/80"
                                >
                                  No
                                </button>
                              </div>
                            </div>
                          )}

                          {/* Lock overlay for video preview frames (PPV/DRM content) */}
                          {previewFrameIds.has(img.id) && !isConfirming && (
                            <div className="absolute inset-0 bg-black/30 flex flex-col items-center justify-center gap-1 group/drm">
                              <Lock className="w-8 h-8 text-white/80 group-hover/drm:hidden" />
                              <Upload className="w-8 h-8 text-white hidden group-hover/drm:block" />
                              <span className="text-xs font-medium text-white/80 group-hover/drm:hidden">DRM Protected</span>
                              <button
                                onClick={(e) => { e.stopPropagation(); setImportAttachment(img) }}
                                className="text-xs font-medium text-white/90 hover:text-white underline hidden group-hover/drm:inline-flex items-center gap-1"
                              >
                                <Upload className="w-3 h-3" />
                                Import File
                              </button>
                              {platformPostUrl && (
                                <a
                                  href={platformPostUrl}
                                  target="_blank"
                                  rel="noopener noreferrer"
                                  onClick={(e) => e.stopPropagation()}
                                  className="inline-flex items-center gap-1 text-xs font-medium text-white/90 hover:text-white underline mt-1"
                                >
                                  View on {formatPlatformName(post.platform)}
                                  <ExternalLink className="w-3 h-3" />
                                </a>
                              )}
                            </div>
                          )}
                        </button>
                        {/* Info bar below image - 2 lines on mobile, 1 line on desktop */}
                        {/* Mobile: stacked layout */}
                        <div className="lg:hidden bg-secondary/80 px-3 py-1.5 text-xs text-muted-foreground">
                          <div className="truncate">{truncateFilename(img.name || '')}</div>
                          <div className="flex items-center space-x-2 mt-0.5">
                            {img.file_size && <span>{formatFileSize(img.file_size)}</span>}
                            {img.width && img.height && <span>{img.width}×{img.height}</span>}
                          </div>
                        </div>
                        {/* Desktop: single row */}
                        <div className="hidden lg:flex bg-secondary/80 px-3 py-1.5 text-xs text-muted-foreground items-center justify-between">
                          <div className="flex items-center space-x-2">
                            {img.file_size && <span>{formatFileSize(img.file_size)}</span>}
                            {img.width && img.height && <span>{img.width}×{img.height}</span>}
                          </div>
                          <span className="truncate ml-2">{truncateFilename(img.name || '')}</span>
                        </div>
                      </div>
                    )
                  })}
                </div>
              )}

              {/* Batch delete bar - bottom (shown when items are selected) */}
              {selectionMode && selectedIds.size > 0 && (
                <div className="p-3 bg-secondary/50 border border-border rounded-lg flex items-center justify-between gap-2">
                  <div className="flex items-center gap-2">
                    <span className="text-sm font-medium">
                      {selectedIds.size} selected
                    </span>
                    <button
                      onClick={() => {
                        if (selectedIds.size === completedAttachments.length) {
                          setSelectedIds(new Set())
                        } else {
                          setSelectedIds(new Set(completedAttachments.map(a => a.id)))
                        }
                      }}
                      className="text-xs text-primary hover:underline"
                    >
                      {selectedIds.size === completedAttachments.length ? 'Deselect all' : 'Select all'}
                    </button>
                  </div>
                  <button
                    onClick={handleBatchDelete}
                    disabled={isBatchDeleting}
                    className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500 text-white text-sm font-medium rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50"
                  >
                    {isBatchDeleting ? (
                      <Loader2 className="w-4 h-4 animate-spin" />
                    ) : (
                      <Trash2 className="w-4 h-4" />
                    )}
                    Delete
                  </button>
                </div>
              )}
            </>
          )}

          {/* PPV Locked Attachments - placeholder grid (only for items without preview frames) */}
          {unavailableAttachments.length > 0 && previewFrameIds.size === 0 && (
            <div className="mt-3">
              <div className="flex items-center gap-1.5 mb-2">
                <Lock className="w-3.5 h-3.5 text-amber-500" />
                <span className="text-xs font-medium text-amber-500">
                  {unavailableAttachments.length} locked {unavailableAttachments.length === 1 ? 'file' : 'files'} (PPV)
                </span>
              </div>
              <div className={`grid gap-1.5 ${
                unavailableAttachments.length === 1 ? 'grid-cols-1' :
                unavailableAttachments.length === 2 ? 'grid-cols-2' :
                'grid-cols-3'
              }`}>
                {unavailableAttachments.map((att) => (
                  <button
                    key={att.id}
                    onClick={() => setImportAttachment(att)}
                    className="relative bg-secondary/30 border border-dashed border-muted-foreground/20 rounded-lg overflow-hidden aspect-video flex flex-col items-center justify-center gap-1.5 group hover:border-blue-500/50 hover:bg-blue-500/5 transition-colors cursor-pointer"
                  >
                    <Lock className="w-5 h-5 text-muted-foreground/30 group-hover:hidden" />
                    <Upload className="w-5 h-5 text-blue-500 hidden group-hover:block" />
                    <div className="flex items-center gap-1 text-muted-foreground/40 group-hover:text-blue-500/70">
                      {att.file_type === 'video' ? (
                        <Video className="w-3 h-3" />
                      ) : (
                        <ImageIcon className="w-3 h-3" />
                      )}
                      <span className="text-[10px] group-hover:hidden">
                        {att.file_type === 'video' ? 'Video' : att.file_type === 'image' ? 'Image' : 'Media'}
                      </span>
                      <span className="text-[10px] hidden group-hover:inline">
                        Import {att.file_type === 'video' ? 'Video' : att.file_type === 'image' ? 'Image' : 'Media'}
                      </span>
                    </div>
                  </button>
                ))}
              </div>
            </div>
          )}

          {/* Tagged Users */}
          {(post.tagged_users?.length ?? 0) > 0 && (
            <div className="mt-4 pt-4 border-t border-border">
              <div className="flex flex-wrap gap-1.5">
                {post.tagged_users!.map((username) => (
                  <span
                    key={`tu-${username}`}
                    className="px-2.5 py-1 rounded-full text-xs font-medium bg-cyan-500/15 text-cyan-600 dark:text-cyan-400"
                  >
                    @{username}
                  </span>
                ))}
              </div>
            </div>
          )}

          {/* Footer - Actions (inside scrollable area) */}
          <div className="mt-4 pt-4 border-t border-border">
            {/* Action buttons */}
            <div className="flex flex-col gap-2">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2 text-sm text-muted-foreground">
                  <span className="capitalize">{post.platform}</span>
                  <span>·</span>
                  <span>{completedAttachments.length} files{unavailableAttachments.length > 0 && previewFrameIds.size === 0 ? ` · ${unavailableAttachments.length} locked` : ''}</span>
                  {hasDrmContent && (
                    <>
                      <span className="hidden lg:inline">·</span>
                      <span className="hidden lg:inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-600 dark:text-amber-400 text-xs font-medium">
                        <Lock className="w-3 h-3" />
                        DRM
                      </span>
                    </>
                  )}
                  {platformPostUrl && (
                    <>
                      <span className="hidden lg:inline">·</span>
                      <a
                        href={platformPostUrl}
                        target="_blank"
                        rel="noopener noreferrer"
                        onClick={(e) => e.stopPropagation()}
                        className="hidden lg:inline-flex items-center gap-1 text-xs text-primary hover:underline"
                      >
                        View on {formatPlatformName(post.platform)}
                        <ExternalLink className="w-3 h-3" />
                      </a>
                    </>
                  )}
                </div>
                {!hideControls && (
                  <div className="flex items-center gap-1.5 sm:gap-2 flex-wrap justify-end" onClick={(e) => e.stopPropagation()} onTouchEnd={(e) => e.stopPropagation()}>
                    {recheckableAttachments.length > 0 && (
                      <button
                        onClick={() => {
                          recheckQualityMutation.mutate(recheckableAttachments.map(a => a.id))
                        }}
                        disabled={recheckQualityMutation.isPending || recheckStatus === 'checking'}
                        className="flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 transition-colors"
                        title="Re-check Fansly for higher quality video"
                      >
                        {(recheckQualityMutation.isPending || recheckStatus === 'checking')
                          ? <Loader2 className="w-4 h-4 animate-spin" />
                          : <RefreshCw className="w-4 h-4" />}
                        <span className="text-sm hidden sm:inline">
                          {recheckStatus === 'checking' ? 'Checking...' : 'Recheck Quality'}
                        </span>
                      </button>
                    )}
                    {onCopyToGallery && (
                      <button
                        onClick={onCopyToGallery}
                        className="flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg bg-secondary text-muted-foreground hover:text-violet-500 hover:bg-violet-500/10 transition-colors"
                        title="Copy to Private Gallery"
                      >
                        <ImagePlus className="w-4 h-4" />
                        <span className="text-sm hidden sm:inline">Gallery</span>
                      </button>
                    )}
                    {post.tags?.some(t => t.slug === 'ppv' || t.name === 'PPV') && (
                      <button
                        onClick={() => {
                          const target = post.attachments?.find(a => a.status !== 'completed') || post.attachments?.[0]
                          if (target) setImportAttachment(target)
                        }}
                        className="flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg bg-blue-500/10 text-blue-500 hover:bg-blue-500/20 transition-colors"
                      >
                        <Upload className="w-4 h-4" />
                        <span className="text-sm hidden sm:inline">Import</span>
                      </button>
                    )}
                    {firstCompletedAttachment && (
                      <button
                        onClick={() => toggleWatchLater()}
                        className={`flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg transition-colors ${
                          hasWatchLaterItems
                            ? 'bg-violet-500/10 text-violet-500 hover:bg-violet-500/20'
                            : 'bg-secondary text-muted-foreground hover:text-violet-500 hover:bg-violet-500/10'
                        }`}
                        title={hasWatchLaterItems ? 'Remove from Watch Later' : 'Add to Watch Later'}
                      >
                        <Clock className={`w-4 h-4 ${hasWatchLaterItems ? 'fill-current' : ''}`} />
                        <span className="text-sm hidden sm:inline">{hasWatchLaterItems ? 'Queued' : 'Queue'}</span>
                      </button>
                    )}
                    <button
                      onClick={() => favoriteMutation.mutate()}
                      disabled={favoriteMutation.isPending}
                      className={`flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg transition-colors ${
                        post.is_favorited
                          ? 'bg-red-500/10 text-red-500 hover:bg-red-500/20'
                          : 'bg-secondary text-muted-foreground hover:text-foreground hover:bg-secondary/80'
                      }`}
                    >
                      <Heart className={`w-4 h-4 ${post.is_favorited ? 'fill-current' : ''}`} />
                      <span className="text-sm hidden sm:inline">{post.is_favorited ? 'Favorited' : 'Favorite'}</span>
                    </button>
                    {!compactMode && (
                      <button
                        onClick={() => setIsEditing(true)}
                        className="flex items-center gap-1.5 px-2 sm:px-3 py-1.5 rounded-lg bg-secondary text-muted-foreground hover:text-foreground hover:bg-secondary/80 transition-colors"
                      >
                        <Edit className="w-4 h-4" />
                        <span className="text-sm hidden sm:inline">Edit</span>
                      </button>
                    )}
                  </div>
                )}
              </div>
              {/* Mobile: platform link row */}
              {platformPostUrl && (
                <div className="lg:hidden flex items-center gap-2 text-sm text-muted-foreground">
                  <a
                    href={platformPostUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    onClick={(e) => e.stopPropagation()}
                    className="inline-flex items-center gap-1 text-xs text-primary hover:underline"
                  >
                    View on {formatPlatformName(post.platform)}
                    <ExternalLink className="w-3 h-3" />
                  </a>
                </div>
              )}
              {recheckResult && (
                <div className={`text-xs ${recheckResult.startsWith('Upgraded') ? 'text-green-500' : 'text-muted-foreground'}`}>
                  {recheckResult}
                </div>
              )}
            </div>
          </div>
        </div>

      {/* Import modal for PPV/locked attachments */}
      {importAttachment && (
        <ImportAttachmentModal
          attachment={importAttachment}
          onClose={() => setImportAttachment(null)}
          onSuccess={async () => {
            const updatedPost = await api.paidContent.getPost(post.id)
            queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
            onPostUpdated?.({ attachments: updatedPost.attachments })
          }}
        />
      )}
    </div>
  )
}

// Modal for importing/uploading files to unavailable (PPV/locked) attachments
function ImportAttachmentModal({
  attachment,
  onClose,
  onSuccess,
}: {
  attachment: PaidContentAttachment
  onClose: () => void
  onSuccess: () => void | Promise<void>
}) {
  const [mode, setMode] = useState<'url' | 'file'>('file')
  const [url, setUrl] = useState('')
  const [selectedFile, setSelectedFile] = useState<File | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [isDownloading, setIsDownloading] = useState(false)
  const [progress, setProgress] = useState<string | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [isDragging, setIsDragging] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  // Real-time WebSocket progress updates for URL downloads
  useEffect(() => {
    if (!isDownloading) return

    const handleProgress = (data: any) => {
      if (data.attachment_id !== attachment.id) return
      if (data.status === 'completed') {
        setIsDownloading(false)
        setProgress(null)
        onSuccess()
        onClose()
      } else if (data.status === 'failed') {
        setIsDownloading(false)
        setIsLoading(false)
        setError(data.message || 'Download failed')
      } else if (data.status === 'downloading') {
        setProgress(data.message || `Downloading: ${data.progress}%`)
      }
    }

    const unsubscribe = wsClient.on('attachment_download_progress', handleProgress)

    const pollInterval = setInterval(async () => {
      try {
        const att = await api.paidContent.getAttachment(attachment.id)
        if (att.status === 'completed') {
          setIsDownloading(false)
          setProgress('Complete! Refreshing...')
          await onSuccess()
          onClose()
        } else if (att.status === 'failed') {
          setIsDownloading(false)
          setIsLoading(false)
          setError(att.error_message || 'Download failed')
        }
      } catch {
        // Ignore polling errors
      }
    }, 2000)

    return () => {
      unsubscribe()
      clearInterval(pollInterval)
    }
  }, [isDownloading, attachment.id, onSuccess, onClose])

  const handleImportUrl = async () => {
    if (!url.trim()) { setError('Please enter a URL'); return }
    setIsLoading(true)
    setError(null)
    setProgress(null)
    try {
      const result = await api.paidContent.importUrlToAttachment(attachment.id, url.trim()) as {
        status: string; error?: string
      }
      if (result.status === 'success') {
        await onSuccess()
        onClose()
      } else if (result.status === 'downloading') {
        setIsDownloading(true)
        setProgress('Starting download...')
      } else {
        setError(result.error || 'Import failed')
        setIsLoading(false)
      }
    } catch (err: any) {
      setError(err.message || 'Failed to import file')
      setIsLoading(false)
    }
  }

  const handleUploadFile = async () => {
    if (!selectedFile) { setError('Please select a file'); return }
    setIsLoading(true)
    setError(null)
    setProgress('Uploading: 0%')
    try {
      await api.paidContent.uploadFileToAttachment(
        attachment.id,
        selectedFile,
        (loaded, total) => {
          const pct = Math.round((loaded / total) * 100)
          const loadedMB = (loaded / (1024 * 1024)).toFixed(1)
          const totalMB = (total / (1024 * 1024)).toFixed(1)
          setProgress(`Uploading: ${pct}% (${loadedMB}MB / ${totalMB}MB)`)
        }
      )
      setProgress('Complete! Refreshing...')
      await onSuccess()
      onClose()
    } catch (err: any) {
      setError(err.message || 'Failed to upload file')
      setIsLoading(false)
      setProgress(null)
    }
  }

  const fmtSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
    if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
    return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60" onClick={isDownloading || isLoading ? undefined : onClose}>
      <div className="bg-card border border-border rounded-xl shadow-xl w-full max-w-md mx-4 p-6" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <h3 className="text-lg font-semibold text-foreground">Import Attachment</h3>
          {!isDownloading && !isLoading && (
            <button onClick={onClose} className="p-1 rounded-lg hover:bg-secondary transition-colors">
              <X className="w-5 h-5 text-muted-foreground" />
            </button>
          )}
        </div>

        <div className="space-y-4">
          <p className="text-sm text-muted-foreground">
            Import file for: <span className="font-medium text-foreground">{attachment.name || `Attachment ${attachment.attachment_index + 1}`}</span>
          </p>

          {/* Mode tabs */}
          <div className="flex border border-border rounded-lg overflow-hidden">
            <button
              onClick={() => { setMode('url'); setError(null) }}
              disabled={isLoading || isDownloading}
              className={`flex-1 px-4 py-2 text-sm font-medium transition-colors ${
                mode === 'url' ? 'bg-blue-500 text-white' : 'bg-secondary text-muted-foreground hover:text-foreground'
              }`}
            >
              <Link className="w-4 h-4 inline mr-2" />
              From URL
            </button>
            <button
              onClick={() => { setMode('file'); setError(null) }}
              disabled={isLoading || isDownloading}
              className={`flex-1 px-4 py-2 text-sm font-medium transition-colors ${
                mode === 'file' ? 'bg-blue-500 text-white' : 'bg-secondary text-muted-foreground hover:text-foreground'
              }`}
            >
              <Upload className="w-4 h-4 inline mr-2" />
              Upload File
            </button>
          </div>

          {/* URL input */}
          {mode === 'url' && (
            <div className="space-y-2">
              <p className="text-xs text-muted-foreground">
                Supported: Bunkr, Pixeldrain, Gofile, Cyberdrop, FileDitch, or direct file URLs
              </p>
              <input
                type="url"
                value={url}
                onChange={(e) => setUrl(e.target.value)}
                placeholder="https://..."
                className="w-full px-4 py-2 rounded-lg border border-border bg-secondary text-foreground placeholder-muted-foreground focus:outline-none focus:ring-2 focus:ring-blue-500"
                autoFocus
                disabled={isDownloading || isLoading}
                onKeyDown={(e) => { if (e.key === 'Enter' && !isLoading && !isDownloading) handleImportUrl() }}
              />
            </div>
          )}

          {/* File upload */}
          {mode === 'file' && (
            <div className="space-y-2">
              <div
                onDrop={(e) => { e.preventDefault(); setIsDragging(false); const f = e.dataTransfer.files[0]; if (f) { setSelectedFile(f); setError(null) } }}
                onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}
                onDragLeave={() => setIsDragging(false)}
                onClick={() => !isLoading && fileInputRef.current?.click()}
                className={`border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors ${
                  isDragging ? 'border-blue-500 bg-blue-500/10'
                  : selectedFile ? 'border-green-500 bg-green-500/10'
                  : 'border-border hover:border-blue-500 hover:bg-secondary'
                }`}
              >
                {selectedFile ? (
                  <div className="space-y-1">
                    <p className="text-sm font-medium text-foreground">{selectedFile.name}</p>
                    <p className="text-xs text-muted-foreground">{fmtSize(selectedFile.size)}</p>
                    <p className="text-xs text-green-500">Click to change file</p>
                  </div>
                ) : (
                  <div className="space-y-1">
                    <Plus className="w-8 h-8 mx-auto text-muted-foreground" />
                    <p className="text-sm text-muted-foreground">Drop file here or click to browse</p>
                  </div>
                )}
              </div>
              <input
                ref={fileInputRef}
                type="file"
                className="hidden"
                onChange={(e) => { const f = e.target.files?.[0]; if (f) { setSelectedFile(f); setError(null) } }}
              />
            </div>
          )}

          {/* Progress */}
          {(isDownloading || (isLoading && mode === 'file')) && progress && (
            <div className="space-y-2">
              <div className="flex items-center gap-2 text-sm text-blue-500">
                <Loader2 className="w-4 h-4 animate-spin" />
                {progress}
              </div>
              {progress.includes('%') && (
                <div className="w-full bg-secondary rounded-full h-2">
                  <div
                    className="bg-blue-500 h-2 rounded-full transition-all duration-300"
                    style={{ width: progress.match(/(\d+)%/)?.[1] + '%' || '0%' }}
                  />
                </div>
              )}
            </div>
          )}

          {error && (
            <div className="flex items-center gap-2 text-sm text-red-500">
              <AlertTriangle className="w-4 h-4" />
              {error}
            </div>
          )}

          <div className="flex justify-end gap-2">
            <button
              onClick={onClose}
              className="px-4 py-2 rounded-lg border border-border text-foreground hover:bg-secondary transition-colors"
              disabled={isLoading || isDownloading}
            >
              {isDownloading ? 'Downloading...' : 'Cancel'}
            </button>
            <button
              onClick={mode === 'url' ? handleImportUrl : handleUploadFile}
              disabled={isLoading || isDownloading || (mode === 'url' ? !url.trim() : !selectedFile)}
              className="px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
            >
              {isLoading ? (
                <>
                  <Loader2 className="w-4 h-4 animate-spin" />
                  {mode === 'url' ? 'Starting...' : 'Uploading...'}
                </>
              ) : (
                <>
                  <Download className="w-4 h-4" />
                  {mode === 'url' ? 'Import' : 'Upload'}
                </>
              )}
            </button>
          </div>
        </div>
      </div>
    </div>
  )
}

export default memo(PostDetailView)
