import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useState, useCallback, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { useSearchParams } from 'react-router-dom'
import {
  Trash2,
  CheckSquare,
  Square,
  X,
  ChevronDown,
  ChevronRight,
  Image as ImageIcon,
  Video,
  File,
  Paperclip,
  ArrowUpDown,
  ScanFace,
  Plus,
  Filter,
} from 'lucide-react'
import { api, getErrorMessage, PaidContentPost, PaidContentAttachment, PaidContentCreator } from '../../lib/api'
import { formatRelativeTime } from '../../lib/utils'
import { notificationManager } from '../../lib/notificationManager'

const PAGE_SIZE = 50
const STORAGE_KEY = 'bulk-delete-selected'

function loadSavedSelections(creatorId: number): Set<number> {
  try {
    const data = localStorage.getItem(`${STORAGE_KEY}-${creatorId}`)
    if (data) return new Set(JSON.parse(data) as number[])
  } catch { /* ignore */ }
  return new Set()
}

function saveSelections(creatorId: number | null, ids: Set<number>) {
  if (!creatorId) return
  try {
    if (ids.size === 0) {
      localStorage.removeItem(`${STORAGE_KEY}-${creatorId}`)
    } else {
      localStorage.setItem(`${STORAGE_KEY}-${creatorId}`, JSON.stringify([...ids]))
    }
  } catch { /* ignore */ }
}

function AttachmentThumbnail({
  attachment,
  addRefMode,
  onAddReference,
}: {
  attachment: PaidContentAttachment
  addRefMode?: boolean
  onAddReference?: (att: PaidContentAttachment) => void
}) {
  const [error, setError] = useState(false)
  const [hovered, setHovered] = useState(false)
  const [popupPos, setPopupPos] = useState({ top: 0, left: 0 })
  const thumbRef = useRef<HTMLDivElement>(null)
  const videoRef = useRef<HTMLVideoElement>(null)

  const isVideo = attachment.file_type === 'video'
  const videoUrl = isVideo && attachment.local_path
    ? attachment.file_token ? `/api/paid-content/files/serve?t=${encodeURIComponent(attachment.file_token)}` : `/api/paid-content/files/serve?path=${encodeURIComponent(attachment.local_path)}`
    : null

  const handleMouseEnter = useCallback(() => {
    if (thumbRef.current) {
      const rect = thumbRef.current.getBoundingClientRect()
      const previewSize = 280
      let top = rect.top - previewSize - 8
      let left = rect.left
      if (top < 8) {
        top = rect.bottom + 8
      }
      if (left + previewSize > window.innerWidth - 8) {
        left = window.innerWidth - previewSize - 8
      }
      if (left < 8) left = 8
      setPopupPos({ top, left })
    }
    setHovered(true)
  }, [])

  const handleMouseLeave = useCallback(() => {
    setHovered(false)
    if (videoRef.current) {
      videoRef.current.pause()
      videoRef.current.currentTime = 0
    }
  }, [])

  const handleClick = useCallback((e: React.MouseEvent) => {
    if (addRefMode && onAddReference && attachment.local_path && attachment.file_type === 'image') {
      e.stopPropagation()
      onAddReference(attachment)
    }
  }, [addRefMode, onAddReference, attachment])

  if (error) {
    return (
      <div className="w-16 h-16 rounded bg-secondary flex items-center justify-center">
        <ImageIcon className="w-4 h-4 text-muted-foreground" />
      </div>
    )
  }

  return (
    <div ref={thumbRef} className="relative">
      <img
        src={`/api/paid-content/files/thumbnail/${attachment.id}?size=small`}
        alt=""
        className={`w-16 h-16 rounded object-cover bg-secondary cursor-pointer ${
          addRefMode && attachment.file_type === 'image' && attachment.local_path
            ? 'ring-2 ring-green-500 ring-offset-1'
            : ''
        }`}
        onMouseEnter={handleMouseEnter}
        onMouseLeave={handleMouseLeave}
        onClick={handleClick}
        onError={() => setError(true)}
        loading="lazy"
      />
      {addRefMode && attachment.file_type === 'image' && attachment.local_path && (
        <div className="absolute -top-1 -right-1 bg-green-500 rounded-full w-4 h-4 flex items-center justify-center pointer-events-none">
          <Plus className="w-3 h-3 text-white" />
        </div>
      )}
      {isVideo && (
        <div className="absolute bottom-0.5 right-0.5 bg-black/70 rounded px-1 py-0.5 pointer-events-none">
          <Video className="w-2.5 h-2.5 text-white" />
        </div>
      )}
      {hovered && createPortal(
        <div
          className="fixed z-[9999] pointer-events-none"
          style={{ top: popupPos.top, left: popupPos.left }}
        >
          {videoUrl ? (
            <video
              ref={videoRef}
              src={videoUrl}
              className="w-[280px] h-[280px] rounded-lg object-contain bg-black/90 shadow-2xl border border-border"
              autoPlay
              muted
              loop
              playsInline
            />
          ) : (
            <img
              src={`/api/paid-content/files/thumbnail/${attachment.id}?size=large`}
              alt=""
              className="w-[280px] h-[280px] rounded-lg object-contain bg-black/90 shadow-2xl border border-border"
            />
          )}
        </div>,
        document.body
      )}
    </div>
  )
}

function getPostDisplayTitle(post: PaidContentPost): string {
  if (post.title && post.title.trim()) {
    return post.title.trim()
  }
  if (post.content && post.content.trim()) {
    const text = post.content.trim().replace(/\s+/g, ' ')
    return text.length > 120 ? text.slice(0, 120) + '...' : text
  }
  // Build from metadata
  const parts: string[] = []
  if (post.published_at) {
    const date = new Date(post.published_at)
    parts.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }))
  }
  if (post.attachment_count > 0) {
    const imageCount = post.attachments?.filter(a => a.file_type === 'image').length || 0
    const videoCount = post.attachments?.filter(a => a.file_type === 'video').length || 0
    if (videoCount > 0 && imageCount > 0) {
      parts.push(`${imageCount} images, ${videoCount} videos`)
    } else if (videoCount > 0) {
      parts.push(`${videoCount} ${videoCount === 1 ? 'video' : 'videos'}`)
    } else if (imageCount > 0) {
      parts.push(`${imageCount} ${imageCount === 1 ? 'image' : 'images'}`)
    } else {
      parts.push(`${post.attachment_count} ${post.attachment_count === 1 ? 'file' : 'files'}`)
    }
  }
  if (parts.length > 0) return parts.join(' — ')
  return `Post ${post.post_id?.slice(-8) || post.id}`
}

function PostCard({
  post,
  isSelected,
  onSelect,
  addRefMode,
  onAddReference,
}: {
  post: PaidContentPost
  isSelected: boolean
  onSelect: () => void
  addRefMode?: boolean
  onAddReference?: (att: PaidContentAttachment) => void
}) {
  const thumbnailAttachments = post.attachments?.slice(0, 4) || []

  return (
    <div
      className={`p-4 border-b border-border last:border-b-0 ${
        isSelected ? 'bg-primary/10' : 'hover:bg-secondary/50'
      } transition-colors cursor-pointer`}
      onClick={onSelect}
    >
      {/* Top row: checkbox + title + metadata */}
      <div className="flex items-start gap-3">
        <button onClick={(e) => { e.stopPropagation(); onSelect() }} className="flex-shrink-0 mt-0.5">
          {isSelected ? (
            <CheckSquare className="w-5 h-5 text-primary" />
          ) : (
            <Square className="w-5 h-5 text-muted-foreground" />
          )}
        </button>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <p className="font-medium text-foreground">
              {getPostDisplayTitle(post)}
            </p>
            {(post.tags?.length || (post.tagged_users?.length ?? 0) > 0) ? (
              <div className="flex gap-1 flex-shrink-0 flex-wrap">
                {(post.tags || []).map(tag => (
                  <span
                    key={tag.id}
                    className="text-[10px] px-1.5 py-0.5 rounded-full font-medium"
                    style={{ backgroundColor: tag.color + '20', color: tag.color }}
                  >
                    {tag.name}
                  </span>
                ))}
                {(post.tagged_users || []).map(username => (
                  <span
                    key={`tu-${username}`}
                    className="text-[10px] px-1.5 py-0.5 rounded-full font-medium bg-cyan-500/15 text-cyan-600 dark:text-cyan-400"
                  >
                    @{username}
                  </span>
                ))}
              </div>
            ) : null}
          </div>
          <div className="flex items-center gap-3 text-xs text-muted-foreground mt-1">
            {post.published_at && (
              <span>{formatRelativeTime(post.published_at)}</span>
            )}
            <span className="flex items-center gap-1">
              <Paperclip className="w-3 h-3" />
              {post.attachment_count} attachment{post.attachment_count !== 1 ? 's' : ''}
            </span>
            {post.image_count !== undefined && post.image_count > 0 && (
              <span className="flex items-center gap-1">
                <ImageIcon className="w-3 h-3" />
                {post.image_count}
              </span>
            )}
            {post.video_count !== undefined && post.video_count > 0 && (
              <span className="flex items-center gap-1">
                <Video className="w-3 h-3" />
                {post.video_count}
              </span>
            )}
          </div>
        </div>
      </div>

      {/* Thumbnails underneath */}
      {thumbnailAttachments.length > 0 && (
        <div className="flex gap-1.5 mt-3 ml-8" onClick={(e) => e.stopPropagation()}>
          {thumbnailAttachments.map((att) => (
            <AttachmentThumbnail
              key={att.id}
              attachment={att}
              addRefMode={addRefMode}
              onAddReference={onAddReference}
            />
          ))}
          {post.attachment_count > 4 && (
            <div className="w-16 h-16 rounded bg-secondary flex items-center justify-center text-xs text-muted-foreground font-medium">
              +{post.attachment_count - 4}
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export default function PaidContentBulkDelete() {
  const queryClient = useQueryClient()
  const [searchParams, setSearchParams] = useSearchParams()

  const initialCreatorId = searchParams.get('creator_id')
  const parsedCreatorId = initialCreatorId ? parseInt(initialCreatorId, 10) : null
  const [creatorId, setCreatorId] = useState<number | null>(parsedCreatorId)
  const [sortOrder, setSortOrder] = useState<'desc' | 'asc'>('desc')
  const [selectedIds, setSelectedIds] = useState<Set<number>>(
    () => parsedCreatorId ? loadSavedSelections(parsedCreatorId) : new Set()
  )
  const [offset, setOffset] = useState(0)
  const [allPosts, setAllPosts] = useState<PaidContentPost[]>([])
  const [showConfirm, setShowConfirm] = useState(false)

  // Face recognition state
  const [faceExpanded, setFaceExpanded] = useState(false)
  const [addRefMode, setAddRefMode] = useState(false)
  const [personName, setPersonName] = useState('India Reynolds')
  const [faceFilter, setFaceFilter] = useState<'all' | 'not-match'>('all')
  const [scanComplete, setScanComplete] = useState(false)
  const [isPolling, setIsPolling] = useState(false)

  // Persist selections to localStorage
  useEffect(() => {
    saveSelections(creatorId, selectedIds)
  }, [creatorId, selectedIds])

  // Fetch creators for dropdown
  const { data: creators = [] } = useQuery<PaidContentCreator[]>({
    queryKey: ['paid-content-creators-all'],
    queryFn: () => api.paidContent.getCreators({}),
    staleTime: 30000,
  })

  // Fetch posts for selected creator
  const { data: feedData, isLoading, isFetching } = useQuery({
    queryKey: ['paid-content-bulk-delete-feed', creatorId, sortOrder, offset],
    queryFn: async () => {
      const result = await api.paidContent.getFeed({
        creator_id: creatorId!,
        sort_by: 'published_at',
        sort_order: sortOrder,
        pinned_first: false,
        skip_pinned: true,
        limit: PAGE_SIZE,
        offset,
      })
      // Append or replace posts based on offset
      if (offset === 0) {
        setAllPosts(result.posts)
      } else {
        setAllPosts((prev) => {
          const existingIds = new Set(prev.map((p) => p.id))
          const newPosts = result.posts.filter((p) => !existingIds.has(p.id))
          return [...prev, ...newPosts]
        })
      }
      return result
    },
    enabled: !!creatorId,
  })

  // Face references
  const { data: faceRefs = [], refetch: refetchRefs } = useQuery({
    queryKey: ['face-references'],
    queryFn: () => api.paidContent.faceGetReferences(),
    staleTime: 10000,
  })

  // Face scan status polling - uses refetchInterval for reliable polling
  const { data: scanStatus } = useQuery({
    queryKey: ['face-scan-status'],
    queryFn: () => api.paidContent.faceScanStatus(),
    enabled: faceExpanded || isPolling,
    refetchInterval: isPolling ? 2000 : false,
    staleTime: 0,
  })

  const isScanning = scanStatus?.status === 'initializing' || scanStatus?.status === 'scanning'

  // Auto-start polling when we detect a running scan, stop when done
  useEffect(() => {
    if (isScanning && !isPolling) {
      setIsPolling(true)
    }
    if (scanStatus && !isScanning && isPolling) {
      setIsPolling(false)
    }
  }, [isScanning, isPolling, scanStatus])

  // When scan completes, reload posts to reflect updated tagged users
  useEffect(() => {
    if (scanStatus?.status === 'completed' && !scanComplete) {
      setScanComplete(true)
      // Reload posts to get updated tagged users
      setOffset(0)
      setAllPosts([])
      queryClient.invalidateQueries({ queryKey: ['paid-content-bulk-delete-feed'] })
    }
  }, [scanStatus?.status, scanComplete, queryClient])

  const totalPosts = feedData?.total || 0
  const hasMore = allPosts.length < totalPosts

  // Apply face filter: show posts WITHOUT lovefromreyn tagged user (i.e. not matched)
  const displayPosts = faceFilter === 'not-match'
    ? allPosts.filter(p => !(p.tagged_users || []).includes('lovefromreyn'))
    : allPosts

  const handleCreatorChange = useCallback((newCreatorId: number | null) => {
    setCreatorId(newCreatorId)
    setSelectedIds(newCreatorId ? loadSavedSelections(newCreatorId) : new Set())
    setOffset(0)
    setAllPosts([])
    setFaceFilter('all')
    setScanComplete(false)
    if (newCreatorId) {
      setSearchParams({ creator_id: newCreatorId.toString() })
    } else {
      setSearchParams({})
    }
  }, [setSearchParams])

  const handleSortChange = useCallback((newSort: 'desc' | 'asc') => {
    setSortOrder(newSort)
    setOffset(0)
    setAllPosts([])
  }, [])

  const handleSelect = useCallback((id: number) => {
    setSelectedIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) {
        next.delete(id)
      } else {
        next.add(id)
      }
      return next
    })
  }, [])

  const handleSelectAllOnPage = useCallback(() => {
    const postsToSelect = displayPosts
    const allIds = postsToSelect.map((p) => p.id)
    const allSelected = allIds.every((id) => selectedIds.has(id))
    if (allSelected) {
      setSelectedIds(new Set())
    } else {
      setSelectedIds(new Set(allIds))
    }
  }, [displayPosts, selectedIds])

  const handleLoadMore = useCallback(() => {
    setOffset((prev) => prev + PAGE_SIZE)
  }, [])

  // Face reference add mutation
  const addRefMutation = useMutation({
    mutationFn: (att: PaidContentAttachment) =>
      api.paidContent.faceAddReference(personName, att.local_path!),
    onSuccess: () => {
      notificationManager.success('Reference Added', 'Face reference added successfully')
      refetchRefs()
    },
    onError: (error: unknown) => {
      notificationManager.error('Failed', getErrorMessage(error))
    },
  })

  const deleteRefMutation = useMutation({
    mutationFn: (id: number) => api.paidContent.faceDeleteReference(id),
    onSuccess: () => {
      refetchRefs()
    },
  })

  const startScanMutation = useMutation({
    mutationFn: () => api.paidContent.faceScanCreator(creatorId!, personName),
    onSuccess: () => {
      notificationManager.success('Scan Started', `Scanning for ${personName}...`)
      setIsPolling(true)
    },
    onError: (error: unknown) => {
      notificationManager.error('Scan Failed', getErrorMessage(error))
    },
  })

  const handleAddReference = useCallback((att: PaidContentAttachment) => {
    if (!att.local_path) return
    addRefMutation.mutate(att)
  }, [addRefMutation])

  const handleSelectAllNotMatch = useCallback(() => {
    const notMatchIds = allPosts
      .filter(p => !(p.tagged_users || []).includes('lovefromreyn'))
      .map(p => p.id)
    setSelectedIds(new Set(notMatchIds))
  }, [allPosts])

  // Bulk delete mutation
  const deleteMutation = useMutation({
    mutationFn: (postIds: number[]) => api.paidContent.bulkDeletePosts(postIds),
    onSuccess: (result, postIds) => {
      notificationManager.success(
        'Deleted',
        `${result.deleted_count} post(s) deleted successfully`
      )
      // Remove deleted posts from local state
      const deletedSet = new Set(postIds)
      setAllPosts((prev) => prev.filter((p) => !deletedSet.has(p.id)))
      setSelectedIds(new Set())
      // Invalidate feed queries so other pages reflect changes
      queryClient.invalidateQueries({ queryKey: ['paid-content-feed'] })
      queryClient.invalidateQueries({ queryKey: ['paid-content-bulk-delete-feed'] })
      setShowConfirm(false)
    },
    onError: (error: unknown) => {
      notificationManager.error('Delete Failed', getErrorMessage(error))
      setShowConfirm(false)
    },
  })

  const handleDeleteSelected = useCallback(() => {
    if (selectedIds.size === 0) return
    setShowConfirm(true)
  }, [selectedIds])

  const confirmDelete = useCallback(() => {
    deleteMutation.mutate(Array.from(selectedIds))
  }, [deleteMutation, selectedIds])

  const allOnPageSelected =
    displayPosts.length > 0 && displayPosts.every((p) => selectedIds.has(p.id))

  return (
    <div className="space-y-6">
      {/* Header */}
      <div>
        <h1 className="text-2xl sm:text-3xl font-bold flex items-center gap-2 sm:gap-3">
          <Trash2 className="w-8 h-8 text-red-500" />
          Bulk Delete
        </h1>
        <p className="text-slate-600 dark:text-slate-400 mt-1">
          Select and delete multiple posts at once
        </p>
      </div>

      {/* Controls */}
      <div className="card-glass-hover rounded-xl p-4 flex flex-wrap items-center gap-4">
        {/* Creator dropdown */}
        <div className="flex items-center gap-2">
          <label className="text-sm font-medium text-foreground whitespace-nowrap">Creator:</label>
          <div className="relative">
            <select
              value={creatorId ?? ''}
              onChange={(e) => handleCreatorChange(e.target.value ? parseInt(e.target.value, 10) : null)}
              className="input pr-8 min-w-[200px]"
            >
              <option value="">Select a creator...</option>
              {creators.map((c) => (
                <option key={c.id} value={c.id}>
                  {c.username} ({c.platform})
                </option>
              ))}
            </select>
            <ChevronDown className="w-4 h-4 absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground" />
          </div>
        </div>

        {/* Sort dropdown */}
        <div className="flex items-center gap-2">
          <label className="text-sm font-medium text-foreground whitespace-nowrap">Sort:</label>
          <div className="relative">
            <select
              value={sortOrder}
              onChange={(e) => handleSortChange(e.target.value as 'desc' | 'asc')}
              className="input pr-8"
            >
              <option value="desc">Newest first</option>
              <option value="asc">Oldest first</option>
            </select>
            <ArrowUpDown className="w-4 h-4 absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none text-muted-foreground" />
          </div>
        </div>

        {/* Post count */}
        {creatorId && feedData && (
          <span className="text-sm text-muted-foreground ml-auto">
            {allPosts.length} of {totalPosts} posts loaded
          </span>
        )}
      </div>

      {/* Face Recognition Panel */}
      {creatorId && (
        <div className="card-glass-hover rounded-xl border border-border overflow-hidden">
          <button
            onClick={() => setFaceExpanded(!faceExpanded)}
            className="w-full p-4 flex items-center gap-3 text-left hover:bg-secondary/30 transition-colors"
          >
            {faceExpanded ? (
              <ChevronDown className="w-4 h-4 text-muted-foreground" />
            ) : (
              <ChevronRight className="w-4 h-4 text-muted-foreground" />
            )}
            <ScanFace className="w-5 h-5 text-blue-500" />
            <span className="font-medium text-foreground">Face Recognition</span>
            {faceRefs.length > 0 && (
              <span className="text-xs text-muted-foreground">
                {faceRefs.length} reference{faceRefs.length !== 1 ? 's' : ''}
              </span>
            )}
          </button>

          {faceExpanded && (
            <div className="p-4 pt-0 space-y-4">
              {/* Person name input */}
              <div className="flex items-center gap-3">
                <label className="text-sm font-medium text-foreground whitespace-nowrap">Person:</label>
                <input
                  type="text"
                  value={personName}
                  onChange={(e) => setPersonName(e.target.value)}
                  className="input max-w-[200px]"
                  placeholder="Person name..."
                />
                <button
                  onClick={() => setAddRefMode(!addRefMode)}
                  className={`btn btn-sm ${addRefMode ? 'btn-primary' : 'btn-secondary'}`}
                >
                  <Plus className="w-4 h-4 mr-1" />
                  {addRefMode ? 'Done Adding' : 'Add from Posts'}
                </button>
              </div>

              {addRefMode && (
                <div className="text-xs text-blue-500 bg-blue-500/10 rounded-lg px-3 py-2">
                  Click any image thumbnail below to add it as a face reference for "{personName}".
                  Only images with faces will be accepted.
                </div>
              )}

              {/* Existing references */}
              {faceRefs.length > 0 && (
                <div className="flex flex-wrap gap-2">
                  {faceRefs.map((ref) => (
                    <div key={ref.id} className="relative group">
                      {ref.thumbnail ? (
                        <img
                          src={`data:image/jpeg;base64,${ref.thumbnail}`}
                          alt={ref.person_name}
                          className="w-14 h-14 rounded-lg object-cover border border-border"
                        />
                      ) : (
                        <div className="w-14 h-14 rounded-lg bg-secondary flex items-center justify-center border border-border">
                          <ScanFace className="w-5 h-5 text-muted-foreground" />
                        </div>
                      )}
                      <button
                        onClick={() => deleteRefMutation.mutate(ref.id)}
                        className="absolute -top-1.5 -right-1.5 bg-red-500 rounded-full w-4 h-4 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
                      >
                        <X className="w-3 h-3 text-white" />
                      </button>
                      <div className="absolute bottom-0 left-0 right-0 bg-black/60 rounded-b-lg text-[9px] text-white text-center truncate px-1">
                        {ref.person_name}
                      </div>
                    </div>
                  ))}
                </div>
              )}

              {/* Scan controls */}
              <div className="flex items-center gap-3 flex-wrap">
                <button
                  onClick={() => startScanMutation.mutate()}
                  disabled={!creatorId || faceRefs.length === 0 || isScanning || !personName.trim()}
                  className="btn btn-sm btn-primary"
                >
                  <ScanFace className="w-4 h-4 mr-1" />
                  {isScanning ? 'Scanning...' : `Scan for ${personName}`}
                </button>

                {/* Scan progress */}
                {scanStatus && scanStatus.status !== 'idle' && (
                  <div className="text-sm text-muted-foreground">
                    {scanStatus.status === 'initializing' && 'Initializing model...'}
                    {scanStatus.status === 'scanning' && (
                      <>
                        {scanStatus.processed}/{scanStatus.total} posts
                        {' '} ({scanStatus.matched} match, {scanStatus.unmatched} no match)
                        {scanStatus.matched > 0 && scanStatus.avg_confidence != null && (
                          <span className="text-blue-400 ml-1">
                            avg {scanStatus.avg_confidence}% [{scanStatus.min_confidence}-{scanStatus.max_confidence}%]
                          </span>
                        )}
                      </>
                    )}
                    {scanStatus.status === 'completed' && (
                      <span className="text-green-500">
                        Done: {scanStatus.matched} matched, {scanStatus.unmatched} not matched
                        {scanStatus.errors > 0 && `, ${scanStatus.errors} errors`}
                        {scanStatus.matched > 0 && scanStatus.avg_confidence != null && (
                          <span className="text-blue-400 ml-1">
                            (avg {scanStatus.avg_confidence}%, range {scanStatus.min_confidence}-{scanStatus.max_confidence}%)
                          </span>
                        )}
                      </span>
                    )}
                    {scanStatus.status === 'error' && (
                      <span className="text-red-500">
                        Error: {scanStatus.error_message}
                      </span>
                    )}
                  </div>
                )}

                {/* Scan progress bar */}
                {isScanning && scanStatus && scanStatus.total > 0 && (
                  <div className="flex-1 min-w-[100px]">
                    <div className="h-2 bg-secondary rounded-full overflow-hidden">
                      <div
                        className="h-full bg-blue-500 transition-all duration-300"
                        style={{ width: `${(scanStatus.processed / scanStatus.total) * 100}%` }}
                      />
                    </div>
                  </div>
                )}
              </div>

              {/* Filter by face result */}
              {scanComplete && (
                <div className="flex items-center gap-3 pt-2 border-t border-border">
                  <button
                    onClick={() => setFaceFilter(faceFilter === 'not-match' ? 'all' : 'not-match')}
                    className={`btn btn-sm ${faceFilter === 'not-match' ? 'btn-primary' : 'btn-secondary'}`}
                  >
                    <Filter className="w-4 h-4 mr-1" />
                    {faceFilter === 'not-match' ? `Showing "Not ${personName}" only` : `Filter: Not ${personName}`}
                  </button>
                  {faceFilter === 'not-match' && (
                    <>
                      <span className="text-sm text-muted-foreground">
                        {displayPosts.length} posts
                      </span>
                      <button
                        onClick={handleSelectAllNotMatch}
                        className="btn btn-sm btn-secondary"
                      >
                        <CheckSquare className="w-4 h-4 mr-1" />
                        Select All Not {personName}
                      </button>
                    </>
                  )}
                </div>
              )}
            </div>
          )}
        </div>
      )}

      {/* Selection bar */}
      {selectedIds.size > 0 && (
        <div className="sticky top-0 z-20 bg-primary/10 rounded-xl border border-primary/20 p-4 flex items-center justify-between">
          <span className="text-sm font-medium text-foreground">
            {selectedIds.size} post(s) selected
          </span>
          <div className="flex items-center gap-2">
            <button onClick={handleSelectAllOnPage} className="btn btn-sm btn-secondary">
              {allOnPageSelected ? 'Deselect All' : 'Select All on Page'}
            </button>
            <button
              onClick={handleDeleteSelected}
              disabled={deleteMutation.isPending}
              className="btn btn-sm btn-danger"
            >
              <Trash2 className="w-4 h-4 mr-1" />
              Delete Selected
            </button>
            <button
              onClick={() => setSelectedIds(new Set())}
              className="p-2 rounded-lg hover:bg-secondary"
            >
              <X className="w-4 h-4 text-muted-foreground" />
            </button>
          </div>
        </div>
      )}

      {/* Confirm dialog */}
      {showConfirm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
          <div className="bg-card rounded-xl border border-border p-6 max-w-md w-full mx-4 shadow-xl">
            <h3 className="text-lg font-semibold text-foreground mb-2">Confirm Deletion</h3>
            <p className="text-muted-foreground mb-4">
              Are you sure you want to delete {selectedIds.size} post(s)? Files will be removed from disk and posts will be soft-deleted.
            </p>
            <div className="flex justify-end gap-3">
              <button
                onClick={() => setShowConfirm(false)}
                disabled={deleteMutation.isPending}
                className="btn btn-secondary"
              >
                Cancel
              </button>
              <button
                onClick={confirmDelete}
                disabled={deleteMutation.isPending}
                className="btn btn-danger"
              >
                {deleteMutation.isPending ? 'Deleting...' : 'Delete'}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Posts list */}
      {!creatorId ? (
        <div className="bg-card rounded-xl border border-border p-12 text-center">
          <Trash2 className="w-12 h-12 mx-auto mb-4 text-muted-foreground opacity-50" />
          <h3 className="text-lg font-semibold text-foreground">Select a creator</h3>
          <p className="text-muted-foreground mt-1">Choose a creator from the dropdown to load their posts</p>
        </div>
      ) : isLoading && allPosts.length === 0 ? (
        <div className="bg-card rounded-xl border border-border flex items-center justify-center h-64">
          <div className="animate-spin rounded-full h-8 w-8 border-2 border-primary border-t-transparent"></div>
        </div>
      ) : displayPosts.length === 0 ? (
        <div className="bg-card rounded-xl border border-border p-12 text-center">
          <File className="w-12 h-12 mx-auto mb-4 text-muted-foreground opacity-50" />
          <h3 className="text-lg font-semibold text-foreground">No posts found</h3>
          <p className="text-muted-foreground mt-1">
            {faceFilter === 'not-match' ? 'No unmatched posts found' : 'This creator has no posts'}
          </p>
        </div>
      ) : (
        <div className="bg-card rounded-xl border border-border overflow-hidden">
          {/* Select All Header */}
          <div className="p-4 border-b border-border bg-secondary/30 flex items-center gap-4">
            <button onClick={handleSelectAllOnPage}>
              {allOnPageSelected ? (
                <CheckSquare className="w-5 h-5 text-primary" />
              ) : (
                <Square className="w-5 h-5 text-muted-foreground" />
              )}
            </button>
            <span className="text-sm font-medium text-foreground">
              {allOnPageSelected ? 'Deselect all' : 'Select all'}
            </span>
            {faceFilter === 'not-match' && (
              <span className="text-xs text-muted-foreground ml-auto">
                Showing {displayPosts.length} of {allPosts.length} posts
              </span>
            )}
          </div>

          {/* Post rows */}
          <div className="max-h-[calc(100vh-400px)] overflow-y-auto">
            {displayPosts.map((post) => (
              <PostCard
                key={post.id}
                post={post}
                isSelected={selectedIds.has(post.id)}
                onSelect={() => handleSelect(post.id)}
                addRefMode={addRefMode}
                onAddReference={handleAddReference}
              />
            ))}
          </div>

          {/* Load More */}
          {hasMore && faceFilter === 'all' && (
            <div className="p-4 border-t border-border text-center">
              <button
                onClick={handleLoadMore}
                disabled={isFetching}
                className="btn btn-secondary"
              >
                {isFetching ? 'Loading...' : `Load More (${totalPosts - allPosts.length} remaining)`}
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  )
}
