/**
 * Private Gallery Configuration Page
 *
 * Sections:
 * - Storage Settings
 * - Relationship Types Management
 * - Persons Management
 * - Statistics Dashboard
 * - Security (Change Password)
 */

import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  Settings,
  FolderCog,
  FolderOpen,
  Users,
  Tag,
  Lock,
  BarChart3,
  Plus,
  Edit,
  Trash2,
  Save,
  Loader2,
  Check,
  X,
  Image as ImageIcon,
  Video,
  HardDrive,
  Calendar,
  KeyRound,
  Pencil,
  Search,
  ChevronDown,
  ChevronUp,
  Globe,
  Download,
  RefreshCw,
  Power,
  PowerOff,
  Camera,
  Music,
  Ghost,
  Eye,
  EyeOff,
} from 'lucide-react'
import { api } from '../../lib/api'
import TagSearchSelector from '../../components/private-gallery/TagSearchSelector'
import { usePrivateGalleryContext } from '../../components/private-gallery/PrivateGalleryProvider'
import { useBreadcrumb } from '../../hooks/useBreadcrumb'
import { breadcrumbConfig } from '../../config/breadcrumbConfig'

const TAG_COLORS = [
  '#f59e0b', '#ef4444', '#10b981', '#3b82f6', '#8b5cf6',
  '#ec4899', '#f97316', '#06b6d4', '#84cc16', '#6b7280',
]

interface Relationship {
  id: number
  name: string
  color: string
}

interface TagItem {
  id: number
  name: string
  color: string
}

interface Person {
  id: number
  name: string
  sort_name?: string | null
  relationship_id: number
  relationship: Relationship
  default_tag_ids: number[]
}

function formatFileSize(bytes: number): string {
  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`
}

type Tab = 'storage' | 'import' | 'relationships' | 'tags' | 'persons' | 'groups' | 'reddit' | 'instagram' | 'tiktok' | 'snapchat' | 'stats' | 'security'

interface RedditCommunity {
  id: number
  subreddit_name: string
  person_id: number
  person_name: string
  relationship_name: string
  relationship_color: string
  enabled: boolean
  last_checked: string | null
  total_media_found: number
  created_at: string
  updated_at: string
}

interface RedditSettings {
  enabled: boolean
  check_interval_hours: number
  lookback_days: number
  has_cookies: boolean
  last_checked: string | null
}

interface RedditCheckProgress {
  isRunning: boolean
  currentCommunity: string | null
  communitiesChecked: number
  totalCommunities: number
  mediaFound: number
  phase: string | null
  detailedStatus: string | null
  filesDownloaded: number
  postsImported: number
  postsTotal: number
  currentFile: number
  totalFiles: number
}

interface ScraperAccount {
  id: number
  platform: string
  username: string
  person_id: number
  person_name: string
  relationship_name: string | null
  relationship_color: string | null
  enabled: boolean
  last_imported_at: string | null
  total_media_imported: number
  created_at: string
  updated_at: string
}

interface AvailableAccount {
  username: string
  sources: string[]
  is_mapped: boolean
}

function ScraperAccountTab({ platform, platformLabel, persons }: { platform: string; platformLabel: string; persons: Person[] }) {
  const queryClient = useQueryClient()
  const [saveMsg, setSaveMsg] = useState('')
  const [mappingUsername, setMappingUsername] = useState<string | null>(null)
  const [mappingPersonId, setMappingPersonId] = useState<number | undefined>()

  const { data: accounts = [], isLoading: loadingAccounts } = useQuery<ScraperAccount[]>({
    queryKey: ['scraper-accounts', platform],
    queryFn: () => api.privateGallery.getScraperAccounts(platform),
  })

  const { data: availableAccounts = [], isLoading: loadingAvailable } = useQuery<AvailableAccount[]>({
    queryKey: ['scraper-accounts-available', platform],
    queryFn: () => api.privateGallery.getAvailableAccounts(platform),
  })

  const addAccountMutation = useMutation({
    mutationFn: (data: { username: string; person_id: number }) =>
      api.privateGallery.addScraperAccount(platform, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['scraper-accounts', platform] })
      queryClient.invalidateQueries({ queryKey: ['scraper-accounts-available', platform] })
      setMappingUsername(null)
      setMappingPersonId(undefined)
      setSaveMsg('Account mapped')
      setTimeout(() => setSaveMsg(''), 3000)
    },
  })

  const deleteAccountMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deleteScraperAccount(platform, id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['scraper-accounts', platform] })
      queryClient.invalidateQueries({ queryKey: ['scraper-accounts-available', platform] })
    },
  })

  const toggleAccountMutation = useMutation({
    mutationFn: ({ id, enabled }: { id: number; enabled: boolean }) =>
      api.privateGallery.updateScraperAccount(platform, id, { enabled }),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['scraper-accounts', platform] }),
  })

  if (loadingAccounts || loadingAvailable) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="w-6 h-6 animate-spin text-primary" />
      </div>
    )
  }

  const unmappedAvailable = availableAccounts.filter(a => !a.is_mapped)

  return (
    <div className="space-y-6">
      {saveMsg && (
        <div className="p-3 rounded-lg bg-emerald-500/10 text-emerald-600 flex items-center gap-2 text-sm">
          <Check className="w-4 h-4" />
          {saveMsg}
        </div>
      )}

      {/* Available Accounts — primary mapping UI */}
      <div className="space-y-4">
        <div className="flex items-center justify-between">
          <div>
            <h3 className="text-base font-semibold">Available Accounts</h3>
            <p className="text-sm text-muted-foreground mt-0.5">
              {platformLabel} accounts detected from your scrapers. Map them to a person to auto-import media.
            </p>
          </div>
          <span className="text-xs text-muted-foreground bg-secondary/50 px-2 py-1 rounded-full">
            {unmappedAvailable.length} unmapped
          </span>
        </div>

        {availableAccounts.length === 0 ? (
          <div className="text-center py-8 text-muted-foreground">
            <Camera className="w-8 h-8 mx-auto mb-2 opacity-40" />
            <p className="text-sm">No {platformLabel} accounts found in scraper configs</p>
          </div>
        ) : unmappedAvailable.length === 0 ? (
          <div className="p-4 rounded-lg bg-emerald-500/5 border border-emerald-500/20 text-center">
            <p className="text-sm text-emerald-600">All {availableAccounts.length} accounts are mapped</p>
          </div>
        ) : (
          <div className="space-y-2">
            {unmappedAvailable.map((acc) => (
              <div
                key={acc.username}
                className="p-3 rounded-lg border border-border bg-secondary/20 flex flex-col sm:flex-row sm:items-center gap-2"
              >
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="text-sm font-medium">@{acc.username}</span>
                    <span className="text-[10px] text-muted-foreground bg-secondary px-1.5 py-0.5 rounded">
                      {acc.sources.join(', ')}
                    </span>
                  </div>
                </div>

                {mappingUsername === acc.username ? (
                  <div className="flex items-center gap-2">
                    <select
                      value={mappingPersonId ?? ''}
                      onChange={(e) => setMappingPersonId(e.target.value ? parseInt(e.target.value) : undefined)}
                      className="px-2 py-1.5 rounded-lg border border-border bg-background text-sm"
                      autoFocus
                    >
                      <option value="">Select person...</option>
                      {[...persons].sort((a, b) => a.name.localeCompare(b.name)).map((p) => (
                        <option key={p.id} value={p.id}>{p.name}</option>
                      ))}
                    </select>
                    <button
                      onClick={() => {
                        if (mappingPersonId) {
                          addAccountMutation.mutate({ username: acc.username, person_id: mappingPersonId })
                        }
                      }}
                      disabled={!mappingPersonId || addAccountMutation.isPending}
                      className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 text-sm flex items-center gap-1"
                    >
                      {addAccountMutation.isPending ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Check className="w-3.5 h-3.5" />}
                      Map
                    </button>
                    <button
                      onClick={() => { setMappingUsername(null); setMappingPersonId(undefined) }}
                      className="p-1.5 rounded hover:bg-secondary text-muted-foreground"
                    >
                      <X className="w-3.5 h-3.5" />
                    </button>
                  </div>
                ) : (
                  <button
                    onClick={() => { setMappingUsername(acc.username); setMappingPersonId(undefined) }}
                    className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm flex items-center gap-1.5 transition-colors"
                  >
                    <Plus className="w-3.5 h-3.5" />
                    Map to Person
                  </button>
                )}
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Mapped accounts list - grouped by person */}
      {accounts.length === 0 ? (
        <div />
      ) : (() => {
        const grouped: Record<string, { person_name: string; relationship_name: string | null; relationship_color: string | null; person_id: number; accounts: ScraperAccount[] }> = {}
        for (const a of accounts) {
          const key = String(a.person_id)
          if (!grouped[key]) {
            grouped[key] = {
              person_name: a.person_name,
              relationship_name: a.relationship_name,
              relationship_color: a.relationship_color,
              person_id: a.person_id,
              accounts: [],
            }
          }
          grouped[key].accounts.push(a)
        }
        return (
          <div className="space-y-3">
            {Object.values(grouped).sort((a, b) => a.person_name.localeCompare(b.person_name)).map((group) => (
              <div key={group.person_id} className="rounded-lg border border-border overflow-hidden">
                {/* Person header */}
                <div className="px-3 sm:px-4 py-2.5 bg-secondary/30 flex items-center gap-2">
                  <div
                    className="w-2.5 h-2.5 rounded-full flex-shrink-0"
                    style={{ backgroundColor: group.relationship_color || '#6b7280' }}
                  />
                  <span className="text-sm font-semibold">{group.person_name}</span>
                  {group.relationship_name && (
                    <span className="text-xs text-muted-foreground">({group.relationship_name})</span>
                  )}
                  <span className="text-xs text-muted-foreground ml-auto">
                    {group.accounts.length} {group.accounts.length === 1 ? 'account' : 'accounts'}
                  </span>
                </div>

                {/* Account rows */}
                <div className="divide-y divide-border">
                  {group.accounts.map((a) => (
                    <div
                      key={a.id}
                      className={`px-3 sm:px-4 py-2.5 flex items-center gap-3 transition-colors ${
                        a.enabled ? 'hover:bg-secondary/20' : 'opacity-50 bg-secondary/10'
                      }`}
                    >
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2 flex-wrap">
                          <span className="text-sm font-medium">@{a.username}</span>
                          {!a.enabled && (
                            <span className="px-1.5 py-0.5 text-[10px] font-medium rounded bg-gray-500/10 text-gray-500">
                              Paused
                            </span>
                          )}
                        </div>
                        <div className="flex flex-wrap gap-x-3 text-[11px] text-muted-foreground mt-0.5">
                          <span>{a.total_media_imported || 0} media imported</span>
                          <span>Last import: {a.last_imported_at ? new Date(a.last_imported_at).toLocaleDateString() : 'Never'}</span>
                        </div>
                      </div>

                      <div className="flex gap-1 flex-shrink-0">
                        <button
                          onClick={() => toggleAccountMutation.mutate({ id: a.id, enabled: !a.enabled })}
                          title={a.enabled ? 'Pause' : 'Resume'}
                          className={`p-1.5 rounded hover:bg-secondary transition-colors ${
                            a.enabled ? 'text-emerald-500' : 'text-muted-foreground'
                          }`}
                        >
                          {a.enabled ? <Eye className="w-3.5 h-3.5" /> : <EyeOff className="w-3.5 h-3.5" />}
                        </button>
                        <button
                          onClick={() => {
                            if (confirm(`Remove @${a.username}?`)) {
                              deleteAccountMutation.mutate(a.id)
                            }
                          }}
                          title="Remove"
                          className="p-1.5 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-colors"
                        >
                          <Trash2 className="w-3.5 h-3.5" />
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
        )
      })()}
    </div>
  )
}

function RedditTab({ persons }: { persons: Person[] }) {
  const queryClient = useQueryClient()
  const [newSubreddits, setNewSubreddits] = useState('')
  const [newPersonId, setNewPersonId] = useState<number | undefined>()
  const [saveMsg, setSaveMsg] = useState('')
  // Cookie state removed - managed on Scrapers page
  const [redditProgress, setRedditProgress] = useState<RedditCheckProgress>({
    isRunning: false,
    currentCommunity: null,
    communitiesChecked: 0,
    totalCommunities: 0,
    mediaFound: 0,
    phase: null,
    detailedStatus: null,
    filesDownloaded: 0,
    postsImported: 0,
    postsTotal: 0,
    currentFile: 0,
    totalFiles: 0,
  })

  const { data: settings, isLoading: loadingSettings } = useQuery<RedditSettings>({
    queryKey: ['reddit-settings'],
    queryFn: () => api.privateGallery.getRedditSettings(),
  })

  const { data: communities = [], isLoading: loadingCommunities } = useQuery<RedditCommunity[]>({
    queryKey: ['reddit-communities'],
    queryFn: () => api.privateGallery.getRedditCommunities(),
  })

  // Check for running task on mount
  useEffect(() => {
    const checkRunningTask = async () => {
      try {
        const task = await api.getBackgroundTask('reddit_monitor')
        if (task.active) {
          const ed = task.extra_data || {}
          setRedditProgress({
            isRunning: true,
            currentCommunity: ed.current_community || null,
            communitiesChecked: task.progress?.current || 0,
            totalCommunities: ed.total_communities || task.progress?.total || 0,
            mediaFound: ed.media_found || 0,
            phase: ed.phase || null,
            detailedStatus: task.detailed_status || null,
            filesDownloaded: ed.files_downloaded || 0,
            postsImported: ed.posts_imported || 0,
            postsTotal: ed.posts_total || 0,
            currentFile: ed.current_file || 0,
            totalFiles: ed.total_files || 0,
          })
        }
      } catch {}
    }
    checkRunningTask()
  }, [])

  // Poll for Reddit monitor background task status
  useEffect(() => {
    if (!redditProgress.isRunning) return

    const pollInterval = setInterval(async () => {
      try {
        const task = await api.getBackgroundTask('reddit_monitor')
        if (task.active) {
          const ed = task.extra_data || {}
          setRedditProgress({
            isRunning: true,
            currentCommunity: ed.current_community || null,
            communitiesChecked: task.progress?.current || 0,
            totalCommunities: ed.total_communities || task.progress?.total || 0,
            mediaFound: ed.media_found || 0,
            phase: ed.phase || null,
            detailedStatus: task.detailed_status || null,
            filesDownloaded: ed.files_downloaded || 0,
            postsImported: ed.posts_imported || 0,
            postsTotal: ed.posts_total || 0,
            currentFile: ed.current_file || 0,
            totalFiles: ed.total_files || 0,
          })
        } else if (!task.active && redditProgress.isRunning) {
          setRedditProgress(prev => ({
            ...prev,
            isRunning: false,
            currentCommunity: null,
          }))
          queryClient.invalidateQueries({ queryKey: ['reddit-communities'] })
          queryClient.invalidateQueries({ queryKey: ['reddit-settings'] })
          queryClient.invalidateQueries({ queryKey: ['private-gallery-posts'] })
        }
      } catch {}
    }, 1000)

    return () => clearInterval(pollInterval)
  }, [redditProgress.isRunning, queryClient])

  const [localSettings, setLocalSettings] = useState<Partial<RedditSettings>>({})

  useEffect(() => {
    if (settings) {
      setLocalSettings({
        enabled: settings.enabled,
        check_interval_hours: settings.check_interval_hours,
        lookback_days: settings.lookback_days,
      })
    }
  }, [settings])

  const updateSettingsMutation = useMutation({
    mutationFn: (data: Partial<RedditSettings>) => api.privateGallery.updateRedditSettings(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['reddit-settings'] })
      setSaveMsg('Settings saved')
      setTimeout(() => setSaveMsg(''), 3000)
    },
  })

  // Cookie mutations removed - managed on Scrapers page

  const addCommunityMutation = useMutation({
    mutationFn: async (items: { subreddit_name: string; person_id: number }[]) => {
      for (const item of items) {
        await api.privateGallery.addRedditCommunity(item)
      }
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['reddit-communities'] })
      setNewSubreddits('')
    },
  })

  const deleteCommunityMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deleteRedditCommunity(id),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['reddit-communities'] }),
  })

  const toggleCommunityMutation = useMutation({
    mutationFn: ({ id, enabled }: { id: number; enabled: boolean }) =>
      api.privateGallery.updateRedditCommunity(id, { enabled }),
    onSuccess: () => queryClient.invalidateQueries({ queryKey: ['reddit-communities'] }),
  })

  const triggerCheckMutation = useMutation({
    mutationFn: () => api.privateGallery.triggerRedditCheck(),
    onMutate: () => {
      setRedditProgress({
        isRunning: true,
        currentCommunity: null,
        communitiesChecked: 0,
        totalCommunities: communities.length || 0,
        mediaFound: 0,
        phase: 'starting',
        detailedStatus: 'Starting...',
        filesDownloaded: 0, postsImported: 0, postsTotal: 0,
        currentFile: 0, totalFiles: 0,
      })
    },
  })

  const downloadAllMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.downloadFullCommunity(id),
    onMutate: () => {
      setRedditProgress({
        isRunning: true,
        currentCommunity: null,
        communitiesChecked: 0,
        totalCommunities: 1,
        mediaFound: 0,
        phase: 'starting',
        detailedStatus: 'Starting full download...',
        filesDownloaded: 0, postsImported: 0, postsTotal: 0,
        currentFile: 0, totalFiles: 0,
      })
    },
  })

  const checkSingleCommunityMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.checkSingleCommunity(id),
    onMutate: () => {
      setRedditProgress({
        isRunning: true,
        currentCommunity: null,
        communitiesChecked: 0,
        totalCommunities: 1,
        mediaFound: 0,
        phase: 'starting',
        detailedStatus: 'Checking for new posts...',
        filesDownloaded: 0, postsImported: 0, postsTotal: 0,
        currentFile: 0, totalFiles: 0,
      })
    },
  })

  const checkByPersonMutation = useMutation({
    mutationFn: (personId: number) => api.privateGallery.checkCommunitiesByPerson(personId),
    onMutate: () => {
      setRedditProgress({
        isRunning: true,
        currentCommunity: null,
        communitiesChecked: 0,
        totalCommunities: 0,
        mediaFound: 0,
        phase: 'starting',
        detailedStatus: 'Checking all subreddits for person...',
        filesDownloaded: 0, postsImported: 0, postsTotal: 0,
        currentFile: 0, totalFiles: 0,
      })
    },
  })

  const handleSaveSettings = () => {
    updateSettingsMutation.mutate(localSettings)
  }

  if (loadingSettings || loadingCommunities) {
    return (
      <div className="flex justify-center py-8">
        <Loader2 className="w-6 h-6 animate-spin text-primary" />
      </div>
    )
  }

  return (
    <div className="space-y-6">
      {/* Running Status Banner */}
      {redditProgress.isRunning && (
        <div className="card-glass rounded-xl bg-gradient-to-r from-orange-500/10 to-amber-500/10 border border-orange-500/30 p-4 glow-border">
          <div className="flex items-center justify-between mb-3">
            <div className="flex items-center gap-2">
              <div className="relative">
                <Globe className="w-5 h-5 text-orange-600 dark:text-orange-400" />
                <span className="absolute -top-1 -right-1 w-2 h-2 bg-orange-500 rounded-full animate-pulse"></span>
              </div>
              <h3 className="text-sm font-semibold text-orange-900 dark:text-orange-100">
                Reddit Community Monitor
              </h3>
            </div>
            <span className="text-xs text-orange-600 dark:text-orange-400">
              {redditProgress.totalCommunities > 1
                ? `Community ${(redditProgress.communitiesChecked || 0) + 1}/${redditProgress.totalCommunities}`
                : '1 community'}
            </span>
          </div>

          {/* Current community */}
          {redditProgress.currentCommunity && (
            <div className="mb-3 px-3 py-1.5 bg-orange-100 dark:bg-orange-900/30 rounded-lg">
              <div className="flex items-center gap-2 text-sm font-medium text-orange-800 dark:text-orange-200">
                <span>{redditProgress.currentCommunity}</span>
              </div>
            </div>
          )}

          {/* Phase-specific detail */}
          <div className="mb-3 px-3 py-2 bg-black/5 dark:bg-white/5 rounded-lg">
            <div className="flex items-center gap-2 text-sm text-orange-800 dark:text-orange-200">
              <span className="w-2 h-2 bg-orange-500 rounded-full animate-pulse flex-shrink-0"></span>
              <span className="truncate">
                {redditProgress.phase === 'starting' && 'Starting...'}
                {redditProgress.phase === 'downloading' && (
                  <>Downloading media from {redditProgress.currentCommunity || 'subreddit'}...</>
                )}
                {redditProgress.phase === 'processing' && (
                  <>Downloaded {redditProgress.filesDownloaded} files, grouping by post...</>
                )}
                {redditProgress.phase === 'importing' && (
                  <>Importing post {redditProgress.postsImported}/{redditProgress.postsTotal} ({redditProgress.filesDownloaded} files)</>
                )}
                {redditProgress.phase === 'encrypting' && (
                  <>Encrypting file {redditProgress.currentFile}/{redditProgress.totalFiles}</>
                )}
                {redditProgress.phase === 'found' && (
                  <>Finished {redditProgress.currentCommunity}</>
                )}
                {redditProgress.phase === 'done' && (
                  <>No new posts in {redditProgress.currentCommunity}</>
                )}
                {!redditProgress.phase && (redditProgress.detailedStatus || 'Working...')}
              </span>
            </div>
          </div>

          {/* Community progress bar (only for multi-community checks) */}
          {redditProgress.totalCommunities > 1 && (
            <div className="mb-2">
              <div className="flex justify-between text-xs text-orange-700 dark:text-orange-300 mb-1">
                <span>Communities</span>
                <span>{redditProgress.communitiesChecked || 0}/{redditProgress.totalCommunities}</span>
              </div>
              <div className="w-full bg-orange-200 dark:bg-orange-800 rounded-full h-1.5 sm:h-2">
                <div
                  className="bg-orange-600 dark:bg-orange-400 h-1.5 sm:h-2 rounded-full transition-all duration-300 progress-animated"
                  style={{ width: `${redditProgress.totalCommunities > 0 ? (redditProgress.communitiesChecked / redditProgress.totalCommunities * 100) : 0}%` }}
                ></div>
              </div>
            </div>
          )}

          {/* File encryption progress bar (during encrypting phase) */}
          {(redditProgress.phase === 'encrypting' || redditProgress.phase === 'importing') && redditProgress.totalFiles > 0 && (
            <div className="mb-2">
              <div className="flex justify-between text-xs text-orange-700 dark:text-orange-300 mb-1">
                <span>Files</span>
                <span>{redditProgress.currentFile}/{redditProgress.totalFiles}</span>
              </div>
              <div className="w-full bg-orange-200 dark:bg-orange-800 rounded-full h-1.5 sm:h-2">
                <div
                  className="bg-amber-500 dark:bg-amber-400 h-1.5 sm:h-2 rounded-full transition-all duration-300 progress-animated"
                  style={{ width: `${(redditProgress.currentFile / redditProgress.totalFiles * 100)}%` }}
                ></div>
              </div>
            </div>
          )}

          {/* Media found counter */}
          <div className="flex items-center gap-1.5 text-xs font-medium mt-1">
            {(redditProgress.mediaFound ?? 0) > 0 ? (
              <span className="text-green-700 dark:text-green-300 flex items-center gap-1.5">
                <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                </svg>
                {redditProgress.mediaFound} media file{redditProgress.mediaFound !== 1 ? 's' : ''} imported
              </span>
            ) : (
              <span className="text-orange-600 dark:text-orange-400">
                No media imported yet
              </span>
            )}
          </div>
        </div>
      )}

      {/* Settings Section */}
      <div className="space-y-4">
        <h3 className="text-base font-semibold">Monitor Settings</h3>

        {saveMsg && (
          <div className="p-3 rounded-lg bg-emerald-500/10 text-emerald-600 flex items-center gap-2 text-sm">
            <Check className="w-4 h-4" />
            {saveMsg}
          </div>
        )}

        <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
          <div className="flex items-center justify-between p-3 rounded-lg bg-secondary/50">
            <div>
              <p className="text-sm font-medium">Enable Monitor</p>
              <p className="text-xs text-muted-foreground">Periodically check for new posts</p>
            </div>
            <button
              onClick={() => {
                const newEnabled = !localSettings.enabled
                setLocalSettings(s => ({ ...s, enabled: newEnabled }))
                updateSettingsMutation.mutate({ enabled: newEnabled })
              }}
              className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${
                localSettings.enabled ? 'bg-primary' : 'bg-gray-300 dark:bg-gray-600'
              }`}
            >
              <span
                className={`inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${
                  localSettings.enabled ? 'translate-x-6' : 'translate-x-1'
                }`}
              />
            </button>
          </div>

          <div>
            <label className="block text-sm font-medium mb-1">Check Interval (hours)</label>
            <input
              type="number"
              min={1}
              max={168}
              value={localSettings.check_interval_hours ?? 4}
              onChange={(e) => setLocalSettings(s => ({ ...s, check_interval_hours: parseInt(e.target.value) || 4 }))}
              className="w-full px-3 py-2 rounded-lg border border-border bg-background text-sm"
            />
          </div>

          <div>
            <label className="block text-sm font-medium mb-1">Lookback Days</label>
            <input
              type="number"
              min={1}
              max={30}
              value={localSettings.lookback_days ?? 3}
              onChange={(e) => setLocalSettings(s => ({ ...s, lookback_days: parseInt(e.target.value) || 3 }))}
              className="w-full px-3 py-2 rounded-lg border border-border bg-background text-sm"
            />
            <p className="text-xs text-muted-foreground mt-1">Only download posts from the last N days</p>
          </div>
        </div>

        {/* Cookie Authentication - managed on Scrapers page */}
        <div className="rounded-lg border border-border p-3">
          <div className="flex items-center gap-2">
            <KeyRound className="w-4 h-4 text-muted-foreground" />
            <span className="text-sm font-medium">Cookie Authentication</span>
            <span className={`px-2 py-0.5 text-xs font-medium rounded-full ${
              settings?.has_cookies
                ? 'bg-emerald-500/10 text-emerald-600'
                : 'bg-gray-500/10 text-gray-500'
            }`}>
              {settings?.has_cookies ? 'Active' : 'None'}
            </span>
          </div>
          <p className="text-xs text-muted-foreground mt-2">
            Reddit cookies are now managed in one place.{' '}
            <a href="/scrapers" className="text-primary hover:underline font-medium">
              Go to Scrapers page →
            </a>
          </p>
        </div>

        {/* Action buttons */}
        <div className="flex items-center gap-3 flex-wrap">
          <button
            onClick={handleSaveSettings}
            disabled={updateSettingsMutation.isPending}
            className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-2 text-sm"
          >
            {updateSettingsMutation.isPending ? (
              <Loader2 className="w-4 h-4 animate-spin" />
            ) : (
              <Save className="w-4 h-4" />
            )}
            Save Settings
          </button>

          <button
            onClick={() => triggerCheckMutation.mutate()}
            disabled={triggerCheckMutation.isPending || redditProgress.isRunning}
            className="px-4 py-2 rounded-lg border border-border hover:bg-secondary disabled:opacity-50 flex items-center gap-2 text-sm"
          >
            {triggerCheckMutation.isPending || redditProgress.isRunning ? (
              <Loader2 className="w-4 h-4 animate-spin" />
            ) : (
              <RefreshCw className="w-4 h-4" />
            )}
            Check Now
          </button>

          {settings?.last_checked && (
            <span className="text-xs text-muted-foreground">
              Last checked: {new Date(settings.last_checked).toLocaleString()}
            </span>
          )}
        </div>
      </div>

      {/* Communities Section */}
      <div className="space-y-4">
        <div className="flex items-center justify-between">
          <div>
            <h3 className="text-base font-semibold">Subreddit Mappings</h3>
            <p className="text-sm text-muted-foreground mt-0.5">
              Map subreddits to persons. New posts are automatically imported and tagged.
            </p>
          </div>
          <span className="text-xs text-muted-foreground bg-secondary/50 px-2 py-1 rounded-full">
            {communities.length} {communities.length === 1 ? 'community' : 'communities'}
          </span>
        </div>

        {/* Add new community */}
        <div className="p-4 rounded-lg border border-dashed border-border bg-secondary/20">
          <div className="flex flex-col sm:flex-row gap-3">
            <div className="sm:w-48">
              <label className="block text-xs font-medium text-muted-foreground mb-1.5">Person</label>
              <select
                value={newPersonId ?? ''}
                onChange={(e) => setNewPersonId(e.target.value ? parseInt(e.target.value) : undefined)}
                className="w-full px-3 py-2 rounded-lg border border-border bg-background text-sm"
              >
                <option value="">Select person...</option>
                {[...persons].sort((a, b) => a.name.localeCompare(b.name)).map((p) => (
                  <option key={p.id} value={p.id}>{p.name}</option>
                ))}
              </select>
            </div>

            <div className="flex-1">
              <label className="block text-xs font-medium text-muted-foreground mb-1.5">
                Subreddits <span className="text-muted-foreground/60 font-normal">(comma or newline separated)</span>
              </label>
              <div className="flex gap-2">
                <input
                  type="text"
                  value={newSubreddits}
                  onChange={(e) => setNewSubreddits(e.target.value)}
                  placeholder="subreddit1, subreddit2, subreddit3"
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' && newSubreddits.trim() && newPersonId) {
                      const subs = newSubreddits.split(/[,\n]+/).map(s => s.replace(/^r\//, '').trim()).filter(Boolean)
                      if (subs.length > 0) {
                        addCommunityMutation.mutate(subs.map(s => ({ subreddit_name: s, person_id: newPersonId! })))
                      }
                    }
                  }}
                  className="flex-1 px-3 py-2 rounded-lg border border-border bg-background text-sm"
                />
                <button
                  onClick={() => {
                    if (newSubreddits.trim() && newPersonId) {
                      const subs = newSubreddits.split(/[,\n]+/).map(s => s.replace(/^r\//, '').trim()).filter(Boolean)
                      if (subs.length > 0) {
                        addCommunityMutation.mutate(subs.map(s => ({ subreddit_name: s, person_id: newPersonId! })))
                      }
                    }
                  }}
                  disabled={!newSubreddits.trim() || !newPersonId || addCommunityMutation.isPending}
                  className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-2 text-sm whitespace-nowrap"
                >
                  {addCommunityMutation.isPending ? (
                    <Loader2 className="w-4 h-4 animate-spin" />
                  ) : (
                    <Plus className="w-4 h-4" />
                  )}
                  Add
                </button>
              </div>
            </div>
          </div>
        </div>

        {/* Community list - grouped by person */}
        {communities.length === 0 ? (
          <div className="text-center py-8 text-muted-foreground">
            <Globe className="w-8 h-8 mx-auto mb-2 opacity-40" />
            <p className="text-sm">No subreddit mappings configured yet</p>
            <p className="text-xs mt-1">Select a person and add subreddits above to start monitoring</p>
          </div>
        ) : (() => {
          // Group communities by person
          const grouped: Record<string, { person_name: string; relationship_name: string; relationship_color: string; person_id: number; communities: RedditCommunity[] }> = {}
          for (const c of communities) {
            const key = String(c.person_id)
            if (!grouped[key]) {
              grouped[key] = {
                person_name: c.person_name,
                relationship_name: c.relationship_name,
                relationship_color: c.relationship_color,
                person_id: c.person_id,
                communities: [],
              }
            }
            grouped[key].communities.push(c)
          }
          return (
            <div className="space-y-3">
              {Object.values(grouped).sort((a, b) => a.person_name.localeCompare(b.person_name)).map((group) => (
                <div key={group.person_id} className="rounded-lg border border-border overflow-hidden">
                  {/* Person header */}
                  <div className="px-3 sm:px-4 py-2.5 bg-secondary/30 flex items-center gap-2">
                    <div
                      className="w-2.5 h-2.5 rounded-full flex-shrink-0"
                      style={{ backgroundColor: group.relationship_color || '#6b7280' }}
                    />
                    <span className="text-sm font-semibold">{group.person_name}</span>
                    {group.relationship_name && (
                      <span className="text-xs text-muted-foreground">({group.relationship_name})</span>
                    )}
                    <span className="text-xs text-muted-foreground ml-auto">
                      {group.communities.length} {group.communities.length === 1 ? 'subreddit' : 'subreddits'}
                    </span>
                    <button
                      onClick={() => checkByPersonMutation.mutate(group.person_id)}
                      disabled={redditProgress.isRunning}
                      title="Check all subreddits for this person"
                      className="p-1 rounded hover:bg-secondary text-muted-foreground hover:text-foreground transition-colors"
                    >
                      <RefreshCw className="w-3.5 h-3.5" />
                    </button>
                  </div>

                  {/* Subreddit rows */}
                  <div className="divide-y divide-border">
                    {group.communities.map((c) => (
                      <div
                        key={c.id}
                        className={`px-3 sm:px-4 py-2.5 flex items-center gap-3 transition-colors ${
                          c.enabled ? 'hover:bg-secondary/20' : 'opacity-50 bg-secondary/10'
                        }`}
                      >
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 flex-wrap">
                            <span className="text-sm font-medium">r/{c.subreddit_name}</span>
                            {!c.enabled && (
                              <span className="px-1.5 py-0.5 text-[10px] font-medium rounded bg-gray-500/10 text-gray-500">
                                Paused
                              </span>
                            )}
                          </div>
                          <div className="flex flex-wrap gap-x-3 text-[11px] text-muted-foreground mt-0.5">
                            <span>{c.total_media_found || 0} media</span>
                            <span>Checked: {c.last_checked ? new Date(c.last_checked).toLocaleDateString() : 'Never'}</span>
                          </div>
                        </div>

                        <div className="flex gap-1 flex-shrink-0">
                          <button
                            onClick={() => checkSingleCommunityMutation.mutate(c.id)}
                            disabled={redditProgress.isRunning}
                            title="Check for new posts"
                            className="p-1.5 rounded hover:bg-secondary text-muted-foreground hover:text-foreground transition-colors"
                          >
                            <RefreshCw className="w-3.5 h-3.5" />
                          </button>
                          <button
                            onClick={() => downloadAllMutation.mutate(c.id)}
                            disabled={downloadAllMutation.isPending || redditProgress.isRunning}
                            title="Download all posts"
                            className="p-1.5 rounded hover:bg-secondary text-muted-foreground hover:text-foreground transition-colors"
                          >
                            <Download className="w-3.5 h-3.5" />
                          </button>
                          <button
                            onClick={() => toggleCommunityMutation.mutate({ id: c.id, enabled: !c.enabled })}
                            title={c.enabled ? 'Pause' : 'Resume'}
                            className={`p-1.5 rounded hover:bg-secondary transition-colors ${
                              c.enabled ? 'text-emerald-500' : 'text-muted-foreground'
                            }`}
                          >
                            {c.enabled ? <Power className="w-3.5 h-3.5" /> : <PowerOff className="w-3.5 h-3.5" />}
                          </button>
                          <button
                            onClick={() => {
                              if (confirm(`Remove r/${c.subreddit_name}?`)) {
                                deleteCommunityMutation.mutate(c.id)
                              }
                            }}
                            title="Remove"
                            className="p-1.5 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-colors"
                          >
                            <Trash2 className="w-3.5 h-3.5" />
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )
        })()}
      </div>
    </div>
  )
}

function PersonGroupsTab({ persons, tags, relationships }: { persons: Person[]; tags: TagItem[]; relationships: Relationship[] }) {
  const queryClient = useQueryClient()
  const [showCreateForm, setShowCreateForm] = useState(false)
  const [newGroupName, setNewGroupName] = useState('')
  const [newGroupDesc, setNewGroupDesc] = useState('')
  const [expandedGroupId, setExpandedGroupId] = useState<number | null>(null)
  const [editingGroupId, setEditingGroupId] = useState<number | null>(null)
  const [editName, setEditName] = useState('')
  const [editDesc, setEditDesc] = useState('')
  const [newGroupMinRes, setNewGroupMinRes] = useState(0)
  const [addPersonSearch, setAddPersonSearch] = useState('')
  const [showAddPersonFor, setShowAddPersonFor] = useState<number | null>(null)
  const [showAddTagFor, setShowAddTagFor] = useState<number | null>(null)
  const [addTagSearch, setAddTagSearch] = useState('')
  const [showAddRelFor, setShowAddRelFor] = useState<number | null>(null)
  const [showAddExcludedTagFor, setShowAddExcludedTagFor] = useState<number | null>(null)
  const [addExcludedTagSearch, setAddExcludedTagSearch] = useState('')

  const { data: groups = [], isLoading } = useQuery({
    queryKey: ['private-gallery-person-groups'],
    queryFn: () => api.privateGallery.getPersonGroups(),
  })

  const { data: expandedGroup } = useQuery({
    queryKey: ['private-gallery-person-group', expandedGroupId],
    queryFn: () => api.privateGallery.getPersonGroup(expandedGroupId!),
    enabled: !!expandedGroupId,
  })

  const createMutation = useMutation({
    mutationFn: () => api.privateGallery.createPersonGroup(newGroupName, newGroupDesc || undefined, newGroupMinRes || undefined),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-person-groups'] })
      setNewGroupName('')
      setNewGroupDesc('')
      setNewGroupMinRes(0)
      setShowCreateForm(false)
    },
  })

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: number; data: { name?: string; description?: string; min_resolution?: number } }) =>
      api.privateGallery.updatePersonGroup(id, data),
    onSuccess: () => {
      invalidateGroupAndGallery()
      setEditingGroupId(null)
    },
  })

  const deleteMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deletePersonGroup(id),
    onSuccess: () => {
      invalidateGroupAndGallery()
      if (expandedGroupId) setExpandedGroupId(null)
    },
  })

  const invalidateGroupAndGallery = () => {
    queryClient.invalidateQueries({ queryKey: ['private-gallery-person-groups'] })
    queryClient.invalidateQueries({ queryKey: ['private-gallery-person-group'] })
    queryClient.invalidateQueries({ queryKey: ['private-gallery-posts'] })
    queryClient.invalidateQueries({ queryKey: ['private-gallery-media'] })
  }

  const addMemberMutation = useMutation({
    mutationFn: ({ groupId, personId }: { groupId: number; personId: number }) =>
      api.privateGallery.addPersonToGroup(groupId, personId),
    onSuccess: invalidateGroupAndGallery,
  })

  const removeMemberMutation = useMutation({
    mutationFn: ({ groupId, personId }: { groupId: number; personId: number }) =>
      api.privateGallery.removePersonFromGroup(groupId, personId),
    onSuccess: invalidateGroupAndGallery,
  })

  const addTagMemberMutation = useMutation({
    mutationFn: ({ groupId, tagId }: { groupId: number; tagId: number }) =>
      api.privateGallery.addTagToGroup(groupId, tagId),
    onSuccess: invalidateGroupAndGallery,
  })

  const removeTagMemberMutation = useMutation({
    mutationFn: ({ groupId, tagId }: { groupId: number; tagId: number }) =>
      api.privateGallery.removeTagFromGroup(groupId, tagId),
    onSuccess: invalidateGroupAndGallery,
  })

  const addRelMemberMutation = useMutation({
    mutationFn: ({ groupId, relationshipId }: { groupId: number; relationshipId: number }) =>
      api.privateGallery.addRelationshipToGroup(groupId, relationshipId),
    onSuccess: invalidateGroupAndGallery,
  })

  const removeRelMemberMutation = useMutation({
    mutationFn: ({ groupId, relationshipId }: { groupId: number; relationshipId: number }) =>
      api.privateGallery.removeRelationshipFromGroup(groupId, relationshipId),
    onSuccess: invalidateGroupAndGallery,
  })

  const addExcludedTagMutation = useMutation({
    mutationFn: ({ groupId, tagId }: { groupId: number; tagId: number }) =>
      api.privateGallery.addExcludedTagToGroup(groupId, tagId),
    onSuccess: invalidateGroupAndGallery,
  })

  const removeExcludedTagMutation = useMutation({
    mutationFn: ({ groupId, tagId }: { groupId: number; tagId: number }) =>
      api.privateGallery.removeExcludedTagFromGroup(groupId, tagId),
    onSuccess: invalidateGroupAndGallery,
  })

  const memberIds = new Set(expandedGroup?.members?.map((m: { id: number }) => m.id) || [])
  const tagMemberIds = new Set(expandedGroup?.tag_members?.map((t: { id: number }) => t.id) || [])
  const relMemberIds = new Set(expandedGroup?.relationship_members?.map((r: { id: number }) => r.id) || [])
  const excludedTagIds = new Set(expandedGroup?.excluded_tags?.map((t: { id: number }) => t.id) || [])
  const filteredAddPersons = persons.filter(p => {
    if (memberIds.has(p.id)) return false
    if (!addPersonSearch) return true
    const q = addPersonSearch.toLowerCase()
    return p.name.toLowerCase().includes(q)
  })

  const filteredAddTags = tags.filter(t => {
    if (tagMemberIds.has(t.id)) return false
    if (!addTagSearch) return true
    return t.name.toLowerCase().includes(addTagSearch.toLowerCase())
  })

  const filteredAddRels = relationships.filter(r => !relMemberIds.has(r.id))

  const filteredAddExcludedTags = tags.filter(t => {
    if (excludedTagIds.has(t.id) || tagMemberIds.has(t.id)) return false
    if (!addExcludedTagSearch) return true
    return t.name.toLowerCase().includes(addExcludedTagSearch.toLowerCase())
  })

  return (
    <div className="space-y-4">
      {/* Create Group */}
      {!showCreateForm ? (
        <button
          onClick={() => setShowCreateForm(true)}
          className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2"
        >
          <Plus className="w-4 h-4" />
          Create Group
        </button>
      ) : (
        <div className="p-4 rounded-lg bg-secondary/50 space-y-3">
          <h3 className="font-semibold">New Group</h3>
          <input
            type="text"
            value={newGroupName}
            onChange={e => setNewGroupName(e.target.value)}
            placeholder="Group name"
            className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
            autoFocus
          />
          <input
            type="text"
            value={newGroupDesc}
            onChange={e => setNewGroupDesc(e.target.value)}
            placeholder="Description (optional)"
            className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
          />
          <div className="flex items-center gap-2">
            <button
              onClick={() => createMutation.mutate()}
              disabled={!newGroupName.trim() || createMutation.isPending}
              className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-2"
            >
              {createMutation.isPending ? <Loader2 className="w-4 h-4 animate-spin" /> : 'Create'}
            </button>
            <button onClick={() => setShowCreateForm(false)} className="px-4 py-2 rounded-lg border border-border hover:bg-secondary">
              Cancel
            </button>
          </div>
        </div>
      )}

      {/* Groups List */}
      {isLoading ? (
        <div className="flex items-center justify-center h-32">
          <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
        </div>
      ) : groups.length === 0 ? (
        <div className="p-8 text-center rounded-lg bg-secondary/50">
          <FolderOpen className="w-12 h-12 mx-auto mb-4 text-muted-foreground opacity-50" />
          <h3 className="text-lg font-semibold">No groups yet</h3>
          <p className="text-muted-foreground mt-1">Create a group to organize your persons</p>
        </div>
      ) : (
        <div className="space-y-3">
          {groups.map((group) => {
            const isExpanded = expandedGroupId === group.id
            const isEditing = editingGroupId === group.id

            return (
              <div key={group.id} className="rounded-xl border border-border overflow-hidden bg-secondary/50">
                {/* Group Header */}
                <div
                  className="flex items-center justify-between p-4 cursor-pointer hover:bg-accent/50 transition-colors"
                  onClick={() => {
                    if (isExpanded) {
                      setExpandedGroupId(null)
                      setShowAddPersonFor(null)
                    } else {
                      setExpandedGroupId(group.id)
                    }
                  }}
                >
                  <div className="flex items-center gap-3 min-w-0">
                    <FolderOpen className="w-5 h-5 text-violet-500 shrink-0" />
                    <div className="min-w-0">
                      {isEditing ? (
                        <div className="flex items-center gap-2" onClick={e => e.stopPropagation()}>
                          <input
                            type="text"
                            value={editName}
                            onChange={e => setEditName(e.target.value)}
                            className="px-3 py-1.5 rounded-lg border border-border bg-background text-sm"
                            autoFocus
                          />
                          <input
                            type="text"
                            value={editDesc}
                            onChange={e => setEditDesc(e.target.value)}
                            placeholder="Description"
                            className="px-3 py-1.5 rounded-lg border border-border bg-background text-sm"
                          />
                          <button
                            onClick={() => updateMutation.mutate({ id: group.id, data: { name: editName, description: editDesc || undefined } })}
                            className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground text-sm"
                            disabled={!editName.trim()}
                          >
                            Save
                          </button>
                          <button onClick={() => setEditingGroupId(null)} className="px-3 py-1.5 rounded-lg border border-border text-sm">
                            Cancel
                          </button>
                        </div>
                      ) : (
                        <>
                          <h3 className="font-semibold truncate">{group.name}</h3>
                          {group.description && (
                            <p className="text-sm text-muted-foreground truncate">{group.description}</p>
                          )}
                        </>
                      )}
                    </div>
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <span className="text-sm text-muted-foreground">
                      {group.member_count} {group.member_count === 1 ? 'person' : 'persons'}
                      {group.tag_member_count > 0 && `, ${group.tag_member_count} ${group.tag_member_count === 1 ? 'tag' : 'tags'}`}
                      {group.relationship_member_count > 0 && `, ${group.relationship_member_count} ${group.relationship_member_count === 1 ? 'relationship' : 'relationships'}`}
                      {(group.min_resolution ?? 0) > 0 && `, ${group.min_resolution}px+`}
                    </span>
                    {!isEditing && (
                      <>
                        <button
                          onClick={e => {
                            e.stopPropagation()
                            setEditingGroupId(group.id)
                            setEditName(group.name)
                            setEditDesc(group.description || '')
                          }}
                          className="p-1.5 rounded-lg hover:bg-accent text-muted-foreground hover:text-foreground"
                          title="Edit group"
                        >
                          <Pencil className="w-4 h-4" />
                        </button>
                        <button
                          onClick={e => {
                            e.stopPropagation()
                            if (window.confirm(`Delete group "${group.name}"? This won't delete the persons themselves.`)) {
                              deleteMutation.mutate(group.id)
                            }
                          }}
                          className="p-1.5 rounded-lg hover:bg-destructive/20 text-muted-foreground hover:text-destructive"
                          title="Delete group"
                        >
                          <Trash2 className="w-4 h-4" />
                        </button>
                      </>
                    )}
                    {isExpanded ? <ChevronUp className="w-4 h-4 text-muted-foreground" /> : <ChevronDown className="w-4 h-4 text-muted-foreground" />}
                  </div>
                </div>

                {/* Expanded Members */}
                {isExpanded && expandedGroup && (
                  <div className="border-t border-border p-4 space-y-3">
                    {/* Members */}
                    {expandedGroup.members && expandedGroup.members.length > 0 ? (
                      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2">
                        {expandedGroup.members.map((member) => (
                          <div key={member.id} className="flex items-center gap-2 p-2 rounded-lg bg-accent/30">
                            <div
                              className="w-8 h-8 rounded-full flex items-center justify-center shrink-0"
                              style={{ backgroundColor: member.relationship.color + '30' }}
                            >
                              <Users className="w-4 h-4" style={{ color: member.relationship.color }} />
                            </div>
                            <div className="min-w-0 flex-1">
                              <div className="text-sm font-medium truncate">{member.name}</div>
                              <div className="text-xs text-muted-foreground">{member.relationship.name}</div>
                            </div>
                            <button
                              onClick={() => removeMemberMutation.mutate({ groupId: group.id, personId: member.id })}
                              className="p-1 rounded hover:bg-destructive/20 text-muted-foreground hover:text-destructive shrink-0"
                              title="Remove from group"
                            >
                              <X className="w-3.5 h-3.5" />
                            </button>
                          </div>
                        ))}
                      </div>
                    ) : (
                      <p className="text-sm text-muted-foreground">No members yet. Add persons to this group.</p>
                    )}

                    {/* Add Person */}
                    {showAddPersonFor === group.id ? (
                      <div className="space-y-2">
                        <div className="relative">
                          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                          <input
                            type="text"
                            value={addPersonSearch}
                            onChange={e => setAddPersonSearch(e.target.value)}
                            placeholder="Search persons to add..."
                            className="w-full pl-9 px-4 py-2.5 rounded-lg border border-border bg-background"
                            autoFocus
                          />
                        </div>
                        <div className="max-h-48 overflow-y-auto space-y-1 border border-border rounded-lg p-1">
                          {filteredAddPersons.length === 0 ? (
                            <p className="text-sm text-muted-foreground p-2">No persons found</p>
                          ) : (
                            filteredAddPersons.slice(0, 50).map(person => (
                              <button
                                key={person.id}
                                onClick={() => addMemberMutation.mutate({ groupId: group.id, personId: person.id })}
                                className="w-full flex items-center gap-2 p-2 rounded-lg hover:bg-accent text-left"
                              >
                                <div
                                  className="w-7 h-7 rounded-full flex items-center justify-center shrink-0"
                                  style={{ backgroundColor: person.relationship.color + '30' }}
                                >
                                  <Users className="w-3.5 h-3.5" style={{ color: person.relationship.color }} />
                                </div>
                                <span className="text-sm truncate">{person.name}</span>
                                <span className="text-xs text-muted-foreground ml-auto shrink-0">{person.relationship.name}</span>
                              </button>
                            ))
                          )}
                        </div>
                        <button
                          onClick={() => { setShowAddPersonFor(null); setAddPersonSearch('') }}
                          className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm"
                        >
                          Done
                        </button>
                      </div>
                    ) : (
                      <button
                        onClick={() => setShowAddPersonFor(group.id)}
                        className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm flex items-center gap-1"
                      >
                        <Plus className="w-3.5 h-3.5" />
                        Add Person
                      </button>
                    )}

                    {/* Tag Members */}
                    <div className="border-t border-border pt-3 mt-3">
                      <h4 className="text-sm font-medium text-muted-foreground mb-2">Tags</h4>
                      {expandedGroup.tag_members && expandedGroup.tag_members.length > 0 ? (
                        <div className="flex flex-wrap gap-2 mb-2">
                          {expandedGroup.tag_members.map((tag: { id: number; name: string; color: string }) => (
                            <span
                              key={tag.id}
                              className="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs text-white"
                              style={{ backgroundColor: tag.color }}
                            >
                              {tag.name}
                              <button
                                onClick={() => removeTagMemberMutation.mutate({ groupId: group.id, tagId: tag.id })}
                                className="hover:bg-white/20 rounded-full p-0.5"
                                title="Remove tag from group"
                              >
                                <X className="w-3 h-3" />
                              </button>
                            </span>
                          ))}
                        </div>
                      ) : (
                        <p className="text-sm text-muted-foreground mb-2">No tags yet.</p>
                      )}

                      {showAddTagFor === group.id ? (
                        <div className="space-y-2">
                          <div className="relative">
                            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                            <input
                              type="text"
                              value={addTagSearch}
                              onChange={e => setAddTagSearch(e.target.value)}
                              placeholder="Search tags to add..."
                              className="w-full pl-9 px-4 py-2.5 rounded-lg border border-border bg-background"
                              autoFocus
                            />
                          </div>
                          <div className="max-h-48 overflow-y-auto space-y-1 border border-border rounded-lg p-1">
                            {filteredAddTags.length === 0 ? (
                              <p className="text-sm text-muted-foreground p-2">No tags found</p>
                            ) : (
                              filteredAddTags.slice(0, 50).map(tag => (
                                <button
                                  key={tag.id}
                                  onClick={() => addTagMemberMutation.mutate({ groupId: group.id, tagId: tag.id })}
                                  className="w-full flex items-center gap-2 p-2 rounded-lg hover:bg-accent text-left"
                                >
                                  <span
                                    className="w-3 h-3 rounded-full shrink-0"
                                    style={{ backgroundColor: tag.color }}
                                  />
                                  <span className="text-sm truncate">{tag.name}</span>
                                </button>
                              ))
                            )}
                          </div>
                          <button
                            onClick={() => { setShowAddTagFor(null); setAddTagSearch('') }}
                            className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm"
                          >
                            Done
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => setShowAddTagFor(group.id)}
                          className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm flex items-center gap-1"
                        >
                          <Plus className="w-3.5 h-3.5" />
                          Add Tag
                        </button>
                      )}
                    </div>

                    {/* Relationship Members */}
                    <div className="border-t border-border pt-3 mt-3">
                      <h4 className="text-sm font-medium text-muted-foreground mb-2">Relationships</h4>
                      {expandedGroup.relationship_members && expandedGroup.relationship_members.length > 0 ? (
                        <div className="flex flex-wrap gap-2 mb-2">
                          {expandedGroup.relationship_members.map((rel: { id: number; name: string; color: string }) => (
                            <span
                              key={rel.id}
                              className="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs text-white"
                              style={{ backgroundColor: rel.color }}
                            >
                              {rel.name}
                              <button
                                onClick={() => removeRelMemberMutation.mutate({ groupId: group.id, relationshipId: rel.id })}
                                className="hover:bg-white/20 rounded-full p-0.5"
                                title="Remove relationship from group"
                              >
                                <X className="w-3 h-3" />
                              </button>
                            </span>
                          ))}
                        </div>
                      ) : (
                        <p className="text-sm text-muted-foreground mb-2">No relationships yet.</p>
                      )}

                      {showAddRelFor === group.id ? (
                        <div className="space-y-2">
                          <div className="max-h-48 overflow-y-auto space-y-1 border border-border rounded-lg p-1">
                            {filteredAddRels.length === 0 ? (
                              <p className="text-sm text-muted-foreground p-2">No relationships available</p>
                            ) : (
                              filteredAddRels.map(rel => (
                                <button
                                  key={rel.id}
                                  onClick={() => addRelMemberMutation.mutate({ groupId: group.id, relationshipId: rel.id })}
                                  className="w-full flex items-center gap-2 p-2 rounded-lg hover:bg-accent text-left"
                                >
                                  <span
                                    className="w-3 h-3 rounded-full shrink-0"
                                    style={{ backgroundColor: rel.color }}
                                  />
                                  <span className="text-sm truncate">{rel.name}</span>
                                </button>
                              ))
                            )}
                          </div>
                          <button
                            onClick={() => setShowAddRelFor(null)}
                            className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm"
                          >
                            Done
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => setShowAddRelFor(group.id)}
                          className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm flex items-center gap-1"
                        >
                          <Plus className="w-3.5 h-3.5" />
                          Add Relationship
                        </button>
                      )}
                    </div>

                    {/* Excluded Tags */}
                    <div className="border-t border-border pt-3 mt-3">
                      <h4 className="text-sm font-medium text-muted-foreground mb-2">Excluded Tags</h4>
                      {expandedGroup.excluded_tags && expandedGroup.excluded_tags.length > 0 ? (
                        <div className="flex flex-wrap gap-2 mb-2">
                          {expandedGroup.excluded_tags.map((tag: { id: number; name: string; color: string }) => (
                            <span
                              key={tag.id}
                              className="inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-xs text-white border-2 border-red-400"
                              style={{ backgroundColor: tag.color }}
                            >
                              {tag.name}
                              <button
                                onClick={() => removeExcludedTagMutation.mutate({ groupId: group.id, tagId: tag.id })}
                                className="hover:bg-white/20 rounded-full p-0.5"
                                title="Remove excluded tag from group"
                              >
                                <X className="w-3 h-3" />
                              </button>
                            </span>
                          ))}
                        </div>
                      ) : (
                        <p className="text-sm text-muted-foreground mb-2">No excluded tags.</p>
                      )}

                      {showAddExcludedTagFor === group.id ? (
                        <div className="space-y-2">
                          <div className="relative">
                            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                            <input
                              type="text"
                              value={addExcludedTagSearch}
                              onChange={e => setAddExcludedTagSearch(e.target.value)}
                              placeholder="Search tags to exclude..."
                              className="w-full pl-9 px-4 py-2.5 rounded-lg border border-border bg-background"
                              autoFocus
                            />
                          </div>
                          <div className="max-h-48 overflow-y-auto space-y-1 border border-border rounded-lg p-1">
                            {filteredAddExcludedTags.length === 0 ? (
                              <p className="text-sm text-muted-foreground p-2">No tags found</p>
                            ) : (
                              filteredAddExcludedTags.slice(0, 50).map(tag => (
                                <button
                                  key={tag.id}
                                  onClick={() => addExcludedTagMutation.mutate({ groupId: group.id, tagId: tag.id })}
                                  className="w-full flex items-center gap-2 p-2 rounded-lg hover:bg-accent text-left"
                                >
                                  <span
                                    className="w-3 h-3 rounded-full shrink-0"
                                    style={{ backgroundColor: tag.color }}
                                  />
                                  <span className="text-sm truncate">{tag.name}</span>
                                </button>
                              ))
                            )}
                          </div>
                          <button
                            onClick={() => { setShowAddExcludedTagFor(null); setAddExcludedTagSearch('') }}
                            className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm"
                          >
                            Done
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => setShowAddExcludedTagFor(group.id)}
                          className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm flex items-center gap-1"
                        >
                          <Plus className="w-3.5 h-3.5" />
                          Add Excluded Tag
                        </button>
                      )}
                    </div>

                    {/* Min Resolution */}
                    <div className="flex items-center gap-3 pt-2 border-t border-border">
                      <span className="text-sm font-medium text-muted-foreground">Min Resolution</span>
                      <select
                        value={expandedGroup.min_resolution || 0}
                        onChange={e => updateMutation.mutate({ id: group.id, data: { min_resolution: parseInt(e.target.value) } })}
                        className="px-3 py-1.5 rounded-lg border border-border bg-background text-sm"
                      >
                        <option value={0}>Off</option>
                        <option value={300}>300px+</option>
                        <option value={500}>500px+</option>
                        <option value={720}>720px+</option>
                        <option value={1080}>1080px+</option>
                      </select>
                      <span className="text-xs text-muted-foreground">Hide images below this size</span>
                    </div>
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}

export default function PrivateGalleryConfig() {
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const { isUnlocked, isLoading, changePassword } = usePrivateGalleryContext()

  // Redirect if not authenticated
  useEffect(() => {
    if (!isLoading && !isUnlocked) {
      navigate('/private-gallery/unlock', { replace: true })
    }
  }, [isLoading, isUnlocked, navigate])

  useBreadcrumb(breadcrumbConfig['/private-gallery/config'])

  const [activeTab, setActiveTab] = useState<Tab>('storage')

  // Storage form state
  const [storagePath, setStoragePath] = useState('')
  const [autoLockMinutes, setAutoLockMinutes] = useState(30)
  const [duplicateAutoSelectDistance, setDuplicateAutoSelectDistance] = useState(2)
  const [minImportResolution, setMinImportResolution] = useState(0)

  // Relationship form state
  const [editingRelationship, setEditingRelationship] = useState<Relationship | null>(null)
  const [newRelationshipName, setNewRelationshipName] = useState('')
  const [newRelationshipColor, setNewRelationshipColor] = useState(TAG_COLORS[4])

  // Tag form state
  const [isAddingTag, setIsAddingTag] = useState(false)
  const [editingTag, setEditingTag] = useState<TagItem | null>(null)
  const [newTagName, setNewTagName] = useState('')
  const [newTagColor, setNewTagColor] = useState('#f59e0b')

  // Person form state
  const [editingPerson, setEditingPerson] = useState<Person | null>(null)
  const [newPersonName, setNewPersonName] = useState('')
  const [newPersonSortName, setNewPersonSortName] = useState('')
  const [newPersonRelationshipId, setNewPersonRelationshipId] = useState<number | undefined>()
  const [newPersonDefaultTagIds, setNewPersonDefaultTagIds] = useState<number[]>([])

  // Password form state
  const [currentPassword, setCurrentPassword] = useState('')
  const [newPassword, setNewPassword] = useState('')
  const [confirmPassword, setConfirmPassword] = useState('')
  const [passwordError, setPasswordError] = useState('')
  const [passwordSuccess, setPasswordSuccess] = useState(false)
  const [isChangingPassword, setIsChangingPassword] = useState(false)

  // Import Auth form state
  const [newAuthDomain, setNewAuthDomain] = useState('')
  const [newAuthType, setNewAuthType] = useState<'basic' | 'cookies' | 'both'>('basic')
  const [newAuthUsername, setNewAuthUsername] = useState('')
  const [newAuthPassword, setNewAuthPassword] = useState('')
  const [newAuthCookiesText, setNewAuthCookiesText] = useState('')
  const [newAuthUserAgent, setNewAuthUserAgent] = useState('')
  const [newAuthNotes, setNewAuthNotes] = useState('')
  const [deletingAuthId, setDeletingAuthId] = useState<number | null>(null)

  // Config save state
  const [configSaveSuccess, setConfigSaveSuccess] = useState(false)
  const [configSaveError, setConfigSaveError] = useState('')

  // Fetch config
  const { data: config } = useQuery({
    queryKey: ['private-gallery-config'],
    queryFn: () => api.privateGallery.getConfig(),
    enabled: isUnlocked,
  })

  // Update local state when config is loaded
  useEffect(() => {
    if (config) {
      setStoragePath((config as Record<string, unknown>).storage_path as string || '')
      setAutoLockMinutes((config as Record<string, unknown>).auto_lock_minutes as number || 30)
      setDuplicateAutoSelectDistance(Number((config as Record<string, unknown>).duplicate_auto_select_distance) || 2)
      setMinImportResolution(Number((config as Record<string, unknown>).min_import_resolution) || 0)
    }
  }, [config])

  // Fetch relationships
  const { data: relationships = [] } = useQuery({
    queryKey: ['private-gallery-relationships'],
    queryFn: () => api.privateGallery.getRelationships(),
    enabled: isUnlocked,
  })

  // Fetch persons
  const { data: persons = [] } = useQuery({
    queryKey: ['private-gallery-persons'],
    queryFn: () => api.privateGallery.getPersons(),
    enabled: isUnlocked,
  })

  // Fetch tags
  const { data: tags = [] } = useQuery<TagItem[]>({
    queryKey: ['private-gallery-tags'],
    queryFn: () => api.privateGallery.getTags(),
    enabled: isUnlocked,
  })

  // Fetch stats
  const { data: stats, isLoading: isLoadingStats } = useQuery({
    queryKey: ['private-gallery-stats'],
    queryFn: () => api.privateGallery.getStats(),
    enabled: isUnlocked && activeTab === 'stats',
  })

  // Fetch import auth entries
  const { data: importAuthEntries, isLoading: isLoadingImportAuth } = useQuery({
    queryKey: ['private-gallery-import-auth'],
    queryFn: () => api.privateGallery.getImportAuth(),
    enabled: isUnlocked && activeTab === 'import',
  })

  // Mutations
  const updateConfigMutation = useMutation({
    mutationFn: (data: { storage_path?: string; auto_lock_minutes?: number; duplicate_auto_select_distance?: number; min_import_resolution?: number }) =>
      api.privateGallery.updateConfig(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-config'] })
      setConfigSaveSuccess(true)
      setConfigSaveError('')
      setTimeout(() => setConfigSaveSuccess(false), 3000)
    },
    onError: (error: Error) => {
      setConfigSaveError(error.message || 'Failed to save settings')
      setConfigSaveSuccess(false)
    },
  })

  const createRelationshipMutation = useMutation({
    mutationFn: (data: { name: string; color: string }) =>
      api.privateGallery.createRelationship(data.name, data.color),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-relationships'] })
      setNewRelationshipName('')
      setNewRelationshipColor('#6366f1')
    },
  })

  const updateRelationshipMutation = useMutation({
    mutationFn: (data: { id: number; name: string; color: string }) =>
      api.privateGallery.updateRelationship(data.id, data.name, data.color),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-relationships'] })
      setEditingRelationship(null)
    },
  })

  const deleteRelationshipMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deleteRelationship(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-relationships'] })
    },
  })

  const createTagMutation = useMutation({
    mutationFn: (data: { name: string; color: string }) =>
      api.privateGallery.createTag(data.name, data.color),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-tags'] })
      setIsAddingTag(false)
      setNewTagName('')
      setNewTagColor('#f59e0b')
    },
  })

  const updateTagMutation = useMutation({
    mutationFn: (data: { id: number; name: string; color: string }) =>
      api.privateGallery.updateTag(data.id, { name: data.name, color: data.color }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-tags'] })
      setEditingTag(null)
    },
  })

  const deleteTagMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deleteTag(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-tags'] })
    },
  })

  const createPersonMutation = useMutation({
    mutationFn: (data: { name: string; sort_name?: string; relationship_id: number; default_tag_ids?: number[] }) =>
      api.privateGallery.createPerson(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-persons'] })
      setNewPersonName('')
      setNewPersonSortName('')
      setNewPersonRelationshipId(undefined)
      setNewPersonDefaultTagIds([])
    },
  })

  const updatePersonMutation = useMutation({
    mutationFn: (data: { id: number; name?: string; sort_name?: string; relationship_id?: number; default_tag_ids?: number[] }) => {
      const { id, ...body } = data
      return api.privateGallery.updatePerson(id, body)
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-persons'] })
      setEditingPerson(null)
    },
    onError: (error) => {
      console.error('Failed to update person:', error)
      alert('Failed to save person changes')
    },
  })

  const deletePersonMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deletePerson(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-persons'] })
    },
  })

  const createImportAuthMutation = useMutation({
    mutationFn: (data: {
      domain: string; auth_type: string; username?: string; password?: string;
      cookies?: Array<Record<string, string>>; user_agent?: string; notes?: string
    }) => api.privateGallery.createImportAuth(data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-import-auth'] })
      setNewAuthDomain('')
      setNewAuthType('basic')
      setNewAuthUsername('')
      setNewAuthPassword('')
      setNewAuthCookiesText('')
      setNewAuthUserAgent('')
      setNewAuthNotes('')
    },
  })

  const deleteImportAuthMutation = useMutation({
    mutationFn: (id: number) => api.privateGallery.deleteImportAuth(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['private-gallery-import-auth'] })
      setDeletingAuthId(null)
    },
  })

  const handleSaveConfig = () => {
    updateConfigMutation.mutate({
      storage_path: storagePath,
      auto_lock_minutes: autoLockMinutes,
      duplicate_auto_select_distance: duplicateAutoSelectDistance,
      min_import_resolution: minImportResolution,
    })
  }

  const handleChangePassword = async () => {
    setPasswordError('')
    setPasswordSuccess(false)

    if (newPassword.length < 8) {
      setPasswordError('New password must be at least 8 characters')
      return
    }

    if (newPassword !== confirmPassword) {
      setPasswordError('Passwords do not match')
      return
    }

    setIsChangingPassword(true)
    const success = await changePassword(currentPassword, newPassword)
    setIsChangingPassword(false)

    if (success) {
      setPasswordSuccess(true)
      setCurrentPassword('')
      setNewPassword('')
      setConfirmPassword('')
    } else {
      setPasswordError('Failed to change password. Check your current password.')
    }
  }

  const tabs = [
    { id: 'storage', label: 'Storage', icon: FolderCog },
    { id: 'import', label: 'Import Auth', icon: KeyRound },
    { id: 'relationships', label: 'Relationships', icon: Tag },
    { id: 'tags', label: 'Tags', icon: Tag },
    { id: 'persons', label: 'Persons', icon: Users },
    { id: 'groups', label: 'Groups', icon: FolderOpen },
    { id: 'reddit', label: 'Reddit', icon: Globe },
    { id: 'instagram', label: 'Instagram', icon: Camera },
    { id: 'tiktok', label: 'TikTok', icon: Music },
    { id: 'snapchat', label: 'Snapchat', icon: Ghost },
    { id: 'stats', label: 'Statistics', icon: BarChart3 },
    { id: 'security', label: 'Security', icon: Lock },
  ] as const

  // Auth is handled by RequirePrivateGalleryAuth wrapper in App.tsx

  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">
            <Settings className="w-8 h-8 text-slate-500" />
            Gallery Settings
          </h1>
          <p className="text-slate-600 dark:text-slate-400 mt-1">
            Manage storage, persons, tags, and security settings
          </p>
        </div>

        {/* Horizontal Tabs */}
        <div className="border-b border-border">
          <nav className="flex space-x-1 overflow-x-auto" aria-label="Tabs">
            {tabs.map((tab) => {
              const Icon = tab.icon
              return (
                <button
                  key={tab.id}
                  onClick={() => setActiveTab(tab.id)}
                  className={`flex items-center gap-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
                    activeTab === tab.id
                      ? 'border-primary text-primary'
                      : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'
                  }`}
                >
                  <Icon className="w-4 h-4" />
                  <span>{tab.label}</span>
                </button>
              )
            })}
          </nav>
        </div>

        {/* Content */}
        <div>
            {/* Storage Settings */}
            {activeTab === 'storage' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Storage Settings</h2>

                {configSaveSuccess && (
                  <div className="p-4 rounded-lg bg-emerald-500/10 text-emerald-600 flex items-center gap-2">
                    <Check className="w-5 h-5" />
                    Settings saved successfully
                  </div>
                )}

                {configSaveError && (
                  <div className="p-4 rounded-lg bg-destructive/10 text-destructive">
                    {configSaveError}
                  </div>
                )}

                <div className="space-y-4">
                  <div>
                    <label className="block text-sm font-medium mb-2">Storage Path</label>
                    <input
                      type="text"
                      value={storagePath}
                      onChange={(e) => setStoragePath(e.target.value)}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                      placeholder="/opt/private_gallery"
                    />
                    <p className="text-xs text-muted-foreground mt-1">
                      Directory where encrypted files are stored
                    </p>
                  </div>

                  <div>
                    <label className="block text-sm font-medium mb-2">Auto-Lock Timeout (minutes)</label>
                    <input
                      type="number"
                      value={autoLockMinutes}
                      onChange={(e) => setAutoLockMinutes(parseInt(e.target.value) || 30)}
                      min={5}
                      max={480}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                    <p className="text-xs text-muted-foreground mt-1">
                      Gallery will auto-lock after this period of inactivity
                    </p>
                  </div>

                  <div>
                    <label className="block text-sm font-medium mb-2">Duplicate Auto-Select Distance</label>
                    <input
                      type="number"
                      value={duplicateAutoSelectDistance}
                      onChange={(e) => setDuplicateAutoSelectDistance(Math.max(0, Math.min(12, parseInt(e.target.value) || 0)))}
                      min={0}
                      max={12}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                    <p className="text-xs text-muted-foreground mt-1">
                      Hamming distance threshold for auto-selecting duplicates (0 = exact only, higher = more aggressive)
                    </p>
                  </div>

                  <div>
                    <label className="block text-sm font-medium mb-2">Min Import Resolution (px)</label>
                    <input
                      type="number"
                      value={minImportResolution}
                      onChange={(e) => setMinImportResolution(Math.max(0, parseInt(e.target.value) || 0))}
                      min={0}
                      max={10000}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                    <p className="text-xs text-muted-foreground mt-1">
                      Images smaller than this (in either dimension) will be skipped during import. Set to 0 to disable.
                    </p>
                  </div>
                </div>

                <button
                  onClick={handleSaveConfig}
                  disabled={updateConfigMutation.isPending}
                  className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2 transition-colors"
                >
                  {updateConfigMutation.isPending ? (
                    <Loader2 className="w-4 h-4 animate-spin" />
                  ) : (
                    <Save className="w-4 h-4" />
                  )}
                  Save Settings
                </button>

                {/* Maintenance */}
                <div className="border-t border-border pt-6">
                  <h3 className="font-medium mb-2">Maintenance</h3>
                  <div className="flex flex-wrap gap-3">
                    <div>
                      <button
                        onClick={async () => {
                          try {
                            const result = await api.privateGallery.reparseDates()
                            setConfigSaveSuccess(true)
                            setConfigSaveError('')
                            alert(`Re-parsed dates: ${(result as { updated: number }).updated} items updated`)
                            setTimeout(() => setConfigSaveSuccess(false), 3000)
                          } catch (err) {
                            setConfigSaveError('Failed to reparse dates')
                          }
                        }}
                        className="px-4 py-2.5 rounded-lg bg-secondary hover:bg-secondary/80 text-foreground text-sm font-medium transition-colors"
                      >
                        Re-extract Dates from Filenames
                      </button>
                      <p className="text-xs text-muted-foreground mt-1">
                        Re-parse dates and times from original filenames for all media items
                      </p>
                    </div>
                    <div>
                      <button
                        onClick={async () => {
                          try {
                            const result = await api.privateGallery.regenerateThumbnails(true) as { total: number; regenerated: number; skipped: number; errors: Array<{ id: number; error: string }> }
                            setConfigSaveSuccess(true)
                            setConfigSaveError('')
                            alert(`Regenerated ${result.regenerated} missing thumbnails` + (result.errors.length > 0 ? ` (${result.errors.length} errors)` : ''))
                            setTimeout(() => setConfigSaveSuccess(false), 3000)
                          } catch (err) {
                            setConfigSaveError('Failed to regenerate thumbnails')
                          }
                        }}
                        className="px-4 py-2.5 rounded-lg bg-secondary hover:bg-secondary/80 text-foreground text-sm font-medium transition-colors"
                      >
                        Regenerate Missing Thumbnails
                      </button>
                      <p className="text-xs text-muted-foreground mt-1">
                        Generate thumbnails for any media items that are missing them
                      </p>
                    </div>
                  </div>
                </div>
              </div>
            )}

            {/* Import Auth */}
            {activeTab === 'import' && (
              <div className="space-y-6">
                {/* Add New Entry */}
                <div className="bg-card rounded-xl border border-border p-6 space-y-4">
                  <h2 className="text-lg font-semibold">Add Domain Authentication</h2>
                  <p className="text-sm text-muted-foreground">
                    Configure credentials for domains that require authentication when importing URLs.
                  </p>

                  <div className="space-y-4 max-w-lg">
                    <div>
                      <label className="block text-sm font-medium mb-1">Domain</label>
                      <input
                        type="text"
                        value={newAuthDomain}
                        onChange={(e) => setNewAuthDomain(e.target.value)}
                        placeholder="example.com"
                        className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                      />
                      <p className="text-xs text-muted-foreground mt-1">Matches subdomains too (e.g. &quot;example.com&quot; matches &quot;cdn.example.com&quot;)</p>
                    </div>

                    <div>
                      <label className="block text-sm font-medium mb-2">Auth Type</label>
                      <div className="flex gap-4">
                        {(['basic', 'cookies', 'both'] as const).map((type) => (
                          <label key={type} className="flex items-center gap-2 cursor-pointer">
                            <input
                              type="radio"
                              name="authType"
                              value={type}
                              checked={newAuthType === type}
                              onChange={() => setNewAuthType(type)}
                              className="text-primary"
                            />
                            <span className="text-sm capitalize">{type === 'both' ? 'Both' : type === 'basic' ? 'Basic Auth' : 'Cookies'}</span>
                          </label>
                        ))}
                      </div>
                    </div>

                    {(newAuthType === 'basic' || newAuthType === 'both') && (
                      <div className="space-y-3">
                        <div>
                          <label className="block text-sm font-medium mb-1">Username</label>
                          <input
                            type="text"
                            value={newAuthUsername}
                            onChange={(e) => setNewAuthUsername(e.target.value)}
                            className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                          />
                        </div>
                        <div>
                          <label className="block text-sm font-medium mb-1">Password</label>
                          <input
                            type="password"
                            value={newAuthPassword}
                            onChange={(e) => setNewAuthPassword(e.target.value)}
                            className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                          />
                        </div>
                      </div>
                    )}

                    {(newAuthType === 'cookies' || newAuthType === 'both') && (
                      <div>
                        <label className="block text-sm font-medium mb-1">Cookies (JSON)</label>
                        <textarea
                          value={newAuthCookiesText}
                          onChange={(e) => setNewAuthCookiesText(e.target.value)}
                          rows={4}
                          placeholder={'[{"name": "session", "value": "abc123"}, ...]'}
                          className="w-full px-4 py-2.5 rounded-lg border border-border bg-background font-mono text-sm"
                        />
                      </div>
                    )}

                    <div>
                      <label className="block text-sm font-medium mb-1">User-Agent (optional)</label>
                      <input
                        type="text"
                        value={newAuthUserAgent}
                        onChange={(e) => setNewAuthUserAgent(e.target.value)}
                        placeholder="Custom User-Agent string"
                        className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                      />
                    </div>

                    <div>
                      <label className="block text-sm font-medium mb-1">Notes (optional)</label>
                      <input
                        type="text"
                        value={newAuthNotes}
                        onChange={(e) => setNewAuthNotes(e.target.value)}
                        placeholder="e.g. credentials from ..."
                        className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                      />
                    </div>

                    <button
                      onClick={() => {
                        let cookies: Array<Record<string, string>> | undefined
                        if ((newAuthType === 'cookies' || newAuthType === 'both') && newAuthCookiesText.trim()) {
                          try {
                            cookies = JSON.parse(newAuthCookiesText)
                            if (!Array.isArray(cookies)) {
                              alert('Cookies must be a JSON array')
                              return
                            }
                          } catch {
                            alert('Invalid JSON for cookies')
                            return
                          }
                        }
                        createImportAuthMutation.mutate({
                          domain: newAuthDomain,
                          auth_type: newAuthType,
                          username: (newAuthType === 'basic' || newAuthType === 'both') ? newAuthUsername : undefined,
                          password: (newAuthType === 'basic' || newAuthType === 'both') ? newAuthPassword : undefined,
                          cookies,
                          user_agent: newAuthUserAgent || undefined,
                          notes: newAuthNotes || undefined,
                        })
                      }}
                      disabled={!newAuthDomain.trim() || createImportAuthMutation.isPending}
                      className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-2 transition-colors"
                    >
                      {createImportAuthMutation.isPending ? (
                        <Loader2 className="w-4 h-4 animate-spin" />
                      ) : (
                        <Plus className="w-4 h-4" />
                      )}
                      Add Domain
                    </button>
                  </div>
                </div>

                {/* Existing Entries */}
                <div className="bg-card rounded-xl border border-border p-6 space-y-4">
                  <h2 className="text-lg font-semibold">Configured Domains</h2>
                  {isLoadingImportAuth ? (
                    <div className="flex justify-center py-8">
                      <Loader2 className="w-6 h-6 animate-spin text-primary" />
                    </div>
                  ) : importAuthEntries && importAuthEntries.length > 0 ? (
                    <div className="space-y-3">
                      {importAuthEntries.map((entry) => (
                        <div key={entry.id} className="flex items-center justify-between p-4 rounded-lg border border-border bg-background">
                          <div className="flex-1 min-w-0">
                            <div className="flex items-center gap-2 flex-wrap">
                              <span className="font-medium font-mono text-sm">{entry.domain}</span>
                              <span className={`px-2 py-0.5 rounded-full text-xs font-medium ${
                                entry.auth_type === 'basic' ? 'bg-blue-500/10 text-blue-600 dark:text-blue-400' :
                                entry.auth_type === 'cookies' ? 'bg-amber-500/10 text-amber-600 dark:text-amber-400' :
                                'bg-purple-500/10 text-purple-600 dark:text-purple-400'
                              }`}>
                                {entry.auth_type}
                              </span>
                              {entry.has_username && (
                                <span className="px-2 py-0.5 rounded-full text-xs bg-muted text-muted-foreground">user/pass</span>
                              )}
                              {entry.cookies_count > 0 && (
                                <span className="px-2 py-0.5 rounded-full text-xs bg-muted text-muted-foreground">
                                  {entry.cookies_count} cookie{entry.cookies_count !== 1 ? 's' : ''}
                                </span>
                              )}
                            </div>
                            {entry.notes && (
                              <p className="text-xs text-muted-foreground mt-1 truncate">{entry.notes}</p>
                            )}
                          </div>
                          <div className="flex items-center gap-2 ml-4">
                            {deletingAuthId === entry.id ? (
                              <>
                                <button
                                  onClick={() => deleteImportAuthMutation.mutate(entry.id)}
                                  className="px-3 py-1.5 rounded-lg text-xs bg-destructive text-destructive-foreground hover:bg-destructive/90"
                                >
                                  Confirm
                                </button>
                                <button
                                  onClick={() => setDeletingAuthId(null)}
                                  className="px-3 py-1.5 rounded-lg text-xs bg-muted text-muted-foreground hover:bg-muted/80"
                                >
                                  Cancel
                                </button>
                              </>
                            ) : (
                              <button
                                onClick={() => setDeletingAuthId(entry.id)}
                                className="p-2 rounded-lg text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors"
                              >
                                <Trash2 className="w-4 h-4" />
                              </button>
                            )}
                          </div>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <p className="text-sm text-muted-foreground py-4">
                      No domain authentication configured. Add entries above to authenticate URL imports.
                    </p>
                  )}
                </div>
              </div>
            )}

            {/* Relationships */}
            {activeTab === 'relationships' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Relationship Types</h2>
                <p className="text-sm text-muted-foreground">
                  Define relationship types for organizing persons (e.g., Friend, Family, Coworker)
                </p>

                {/* Add New */}
                <div className="space-y-3">
                  <div className="flex flex-col sm:flex-row gap-3">
                    <input
                      type="text"
                      value={newRelationshipName}
                      onChange={(e) => setNewRelationshipName(e.target.value)}
                      placeholder="New relationship type..."
                      className="flex-1 px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                    <button
                      onClick={() => createRelationshipMutation.mutate({ name: newRelationshipName, color: newRelationshipColor })}
                      disabled={!newRelationshipName || createRelationshipMutation.isPending}
                      className="flex-1 sm:flex-none px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2"
                    >
                      <Plus className="w-4 h-4" />
                      Add
                    </button>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    {TAG_COLORS.map((color) => (
                      <button
                        key={color}
                        type="button"
                        onClick={() => setNewRelationshipColor(color)}
                        className={`w-8 h-8 rounded-full border-2 transition-all ${
                          newRelationshipColor === color ? 'border-foreground scale-110' : 'border-transparent'
                        }`}
                        style={{ backgroundColor: color }}
                      />
                    ))}
                  </div>
                </div>

                {/* List */}
                <div className="space-y-2">
                  {relationships.map((rel) => (
                    <div key={rel.id} className="flex items-center gap-3 p-3 rounded-lg bg-secondary/50">
                      {editingRelationship?.id === rel.id ? (
                        <div className="flex-1 space-y-3">
                          <input
                            type="text"
                            value={editingRelationship.name}
                            onChange={(e) => setEditingRelationship({ ...editingRelationship, name: e.target.value })}
                            className="w-full px-3 py-1.5 rounded border border-border bg-background"
                          />
                          <div className="flex flex-wrap gap-2">
                            {TAG_COLORS.map((color) => (
                              <button
                                key={color}
                                type="button"
                                onClick={() => setEditingRelationship({ ...editingRelationship, color })}
                                className={`w-6 h-6 rounded-full border-2 transition-all ${
                                  editingRelationship.color === color ? 'border-foreground scale-110' : 'border-transparent'
                                }`}
                                style={{ backgroundColor: color }}
                              />
                            ))}
                          </div>
                          <div className="flex items-center gap-2">
                            <button
                              onClick={() => setEditingRelationship(null)}
                              className="px-3 py-1.5 rounded-lg bg-secondary hover:bg-secondary/80 text-sm flex items-center gap-1"
                            >
                              <X className="w-4 h-4" />
                              Cancel
                            </button>
                            <button
                              onClick={() => updateRelationshipMutation.mutate(editingRelationship)}
                              className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 text-sm flex items-center gap-1"
                            >
                              <Check className="w-4 h-4" />
                              Save
                            </button>
                          </div>
                        </div>
                      ) : (
                        <>
                          <div className="w-4 h-4 rounded-full" style={{ backgroundColor: rel.color }} />
                          <span className="flex-1 font-medium">{rel.name}</span>
                          <button
                            onClick={() => setEditingRelationship(rel)}
                            className="p-2 rounded hover:bg-secondary"
                          >
                            <Edit className="w-4 h-4" />
                          </button>
                          <button
                            onClick={() => {
                              if (confirm(`Delete "${rel.name}"? This will fail if persons are using it.`)) {
                                deleteRelationshipMutation.mutate(rel.id)
                              }
                            }}
                            className="p-2 rounded hover:bg-destructive/20 text-destructive"
                          >
                            <Trash2 className="w-4 h-4" />
                          </button>
                        </>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Tags */}
            {activeTab === 'tags' && (
              <div className="bg-card rounded-xl border border-border p-6">
                <div className="flex items-center justify-between mb-4">
                  <div>
                    <h2 className="text-lg font-semibold flex items-center">
                      <Tag className="w-5 h-5 mr-2" />
                      Tags
                    </h2>
                    <p className="text-sm text-muted-foreground mt-1">
                      Define tags for categorizing media and posts
                    </p>
                  </div>
                  {!isAddingTag && (
                    <button
                      onClick={() => setIsAddingTag(true)}
                      className="px-3 py-1.5 rounded-lg bg-secondary hover:bg-secondary/80 text-sm flex items-center gap-1"
                    >
                      <Plus className="w-4 h-4" />
                      Add Tag
                    </button>
                  )}
                </div>

                {/* Add new tag form */}
                {isAddingTag && (
                  <div className="mb-4 p-4 bg-secondary/50 rounded-lg space-y-3">
                    <div>
                      <label className="block text-sm font-medium mb-1">Name</label>
                      <input
                        type="text"
                        value={newTagName}
                        onChange={(e) => setNewTagName(e.target.value)}
                        placeholder="Tag name"
                        className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                        autoFocus
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-medium mb-1">Color</label>
                      <div className="flex flex-wrap gap-2">
                        {TAG_COLORS.map((color) => (
                          <button
                            key={color}
                            type="button"
                            onClick={() => setNewTagColor(color)}
                            className={`w-8 h-8 rounded-full border-2 transition-all ${
                              newTagColor === color ? 'border-foreground scale-110' : 'border-transparent'
                            }`}
                            style={{ backgroundColor: color }}
                          />
                        ))}
                      </div>
                    </div>
                    <div className="flex items-center justify-between pt-2">
                      <div className="flex items-center gap-2">
                        <span className="text-sm text-muted-foreground">Preview:</span>
                        <span
                          className="px-3 py-1 rounded-full text-sm font-medium text-white"
                          style={{ backgroundColor: newTagColor }}
                        >
                          {newTagName || 'Tag Name'}
                        </span>
                      </div>
                      <div className="flex items-center gap-2">
                        <button
                          onClick={() => {
                            setIsAddingTag(false)
                            setNewTagName('')
                            setNewTagColor('#f59e0b')
                          }}
                          className="px-3 py-1.5 rounded-lg bg-secondary hover:bg-secondary/80 text-sm"
                        >
                          Cancel
                        </button>
                        <button
                          onClick={() => createTagMutation.mutate({ name: newTagName, color: newTagColor })}
                          disabled={!newTagName.trim() || createTagMutation.isPending}
                          className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 text-sm flex items-center gap-1"
                        >
                          {createTagMutation.isPending ? (
                            <Loader2 className="w-4 h-4 animate-spin" />
                          ) : (
                            <Plus className="w-4 h-4" />
                          )}
                          Create
                        </button>
                      </div>
                    </div>
                  </div>
                )}

                {/* Existing tags list */}
                {tags.length === 0 ? (
                  <p className="text-sm text-muted-foreground text-center py-8">
                    No tags yet. Create one to organize your media.
                  </p>
                ) : (
                  <div className="space-y-2">
                    {tags.map((tag) => (
                      <div
                        key={tag.id}
                        className="flex items-center justify-between p-3 bg-secondary/30 rounded-lg"
                      >
                        {editingTag?.id === tag.id ? (
                          <div className="flex-1 space-y-3">
                            <input
                              type="text"
                              value={editingTag.name}
                              onChange={(e) => setEditingTag({ ...editingTag, name: e.target.value })}
                              className="w-full px-3 py-1.5 rounded-lg border border-border bg-background"
                            />
                            <div className="flex flex-wrap gap-2">
                              {TAG_COLORS.map((color) => (
                                <button
                                  key={color}
                                  type="button"
                                  onClick={() => setEditingTag({ ...editingTag, color })}
                                  className={`w-6 h-6 rounded-full border-2 transition-all ${
                                    editingTag.color === color ? 'border-foreground scale-110' : 'border-transparent'
                                  }`}
                                  style={{ backgroundColor: color }}
                                />
                              ))}
                            </div>
                            <div className="flex items-center gap-2">
                              <button
                                onClick={() => setEditingTag(null)}
                                className="px-3 py-1.5 rounded-lg bg-secondary hover:bg-secondary/80 text-sm flex items-center gap-1"
                              >
                                <X className="w-4 h-4" />
                                Cancel
                              </button>
                              <button
                                onClick={() => updateTagMutation.mutate(editingTag)}
                                disabled={!editingTag.name.trim() || updateTagMutation.isPending}
                                className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 text-sm flex items-center gap-1"
                              >
                                {updateTagMutation.isPending ? (
                                  <Loader2 className="w-4 h-4 animate-spin" />
                                ) : (
                                  <Save className="w-4 h-4" />
                                )}
                                Save
                              </button>
                            </div>
                          </div>
                        ) : (
                          <>
                            <div className="flex items-center gap-3">
                              <span
                                className="px-3 py-1 rounded-full text-sm font-medium text-white"
                                style={{ backgroundColor: tag.color }}
                              >
                                {tag.name}
                              </span>
                            </div>
                            <div className="flex items-center gap-1">
                              <button
                                onClick={() => setEditingTag(tag)}
                                className="p-2 rounded-lg hover:bg-secondary transition-colors text-muted-foreground hover:text-foreground"
                              >
                                <Edit className="w-4 h-4" />
                              </button>
                              <button
                                onClick={() => {
                                  if (confirm(`Delete "${tag.name}"? It will be removed from all media and posts.`)) {
                                    deleteTagMutation.mutate(tag.id)
                                  }
                                }}
                                disabled={deleteTagMutation.isPending}
                                className="p-2 rounded-lg hover:bg-destructive/20 transition-colors text-muted-foreground hover:text-destructive"
                              >
                                <Trash2 className="w-4 h-4" />
                              </button>
                            </div>
                          </>
                        )}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* Persons */}
            {activeTab === 'persons' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Persons</h2>
                <p className="text-sm text-muted-foreground">
                  Manage people in your gallery. Each person automatically becomes an album.
                </p>

                {/* Add New */}
                <div className="space-y-3 p-4 rounded-lg bg-secondary/50">
                  <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                    <input
                      type="text"
                      value={newPersonName}
                      onChange={(e) => setNewPersonName(e.target.value)}
                      placeholder="Name..."
                      className="px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                    <input
                      type="text"
                      value={newPersonSortName}
                      onChange={(e) => setNewPersonSortName(e.target.value)}
                      placeholder="Sort name (optional)..."
                      className="px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                  </div>
                  <div className="flex flex-col sm:flex-row gap-3">
                    <select
                      value={newPersonRelationshipId || ''}
                      onChange={(e) => setNewPersonRelationshipId(parseInt(e.target.value) || undefined)}
                      className="flex-1 px-4 py-2.5 rounded-lg border border-border bg-background"
                    >
                      <option value="">Select relationship...</option>
                      {relationships.map((rel) => (
                        <option key={rel.id} value={rel.id}>
                          {rel.name}
                        </option>
                      ))}
                    </select>
                  </div>
                  {/* Default Tags */}
                  {tags.length > 0 && (
                    <TagSearchSelector
                      tags={tags}
                      selectedTagIds={newPersonDefaultTagIds}
                      onChange={setNewPersonDefaultTagIds}
                      label="Default tags (auto-applied on upload)"
                      compact
                    />
                  )}
                  <button
                    onClick={() =>
                      newPersonName && newPersonRelationshipId &&
                      createPersonMutation.mutate({
                        name: newPersonName,
                        sort_name: newPersonSortName || undefined,
                        relationship_id: newPersonRelationshipId,
                        default_tag_ids: newPersonDefaultTagIds.length > 0 ? newPersonDefaultTagIds : undefined,
                      })
                    }
                    disabled={!newPersonName || !newPersonRelationshipId || createPersonMutation.isPending}
                    className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center justify-center gap-2"
                  >
                    <Plus className="w-4 h-4" />
                    Add Person
                  </button>
                </div>

                {/* List */}
                <div className="space-y-2">
                  {persons.map((person) => (
                    <div key={person.id} className="p-3 rounded-lg bg-secondary/50">
                      {editingPerson?.id === person.id ? (
                        /* Inline Edit Form */
                        <div className="space-y-3">
                          <div className="grid grid-cols-1 sm:grid-cols-2 gap-2">
                            <input
                              type="text"
                              value={editingPerson.name}
                              onChange={(e) => setEditingPerson({ ...editingPerson, name: e.target.value })}
                              className="px-3 py-2 rounded-lg border border-border bg-background text-sm"
                              placeholder="Name..."
                            />
                            <input
                              type="text"
                              value={editingPerson.sort_name || ''}
                              onChange={(e) => setEditingPerson({ ...editingPerson, sort_name: e.target.value || null })}
                              className="px-3 py-2 rounded-lg border border-border bg-background text-sm"
                              placeholder="Sort name..."
                            />
                          </div>
                          <select
                            value={editingPerson.relationship_id}
                            onChange={(e) => setEditingPerson({ ...editingPerson, relationship_id: parseInt(e.target.value) })}
                            className="w-full px-3 py-2 rounded-lg border border-border bg-background text-sm"
                          >
                            {relationships.map((rel) => (
                              <option key={rel.id} value={rel.id}>{rel.name}</option>
                            ))}
                          </select>
                          {tags.length > 0 && (
                            <TagSearchSelector
                              tags={tags}
                              selectedTagIds={editingPerson.default_tag_ids || []}
                              onChange={(ids) => setEditingPerson({ ...editingPerson, default_tag_ids: ids })}
                              label="Default tags"
                              compact
                            />
                          )}
                          <div className="flex gap-2">
                            <button
                              onClick={() => updatePersonMutation.mutate({
                                id: editingPerson.id,
                                name: editingPerson.name,
                                sort_name: editingPerson.sort_name || undefined,
                                relationship_id: editingPerson.relationship_id,
                                default_tag_ids: editingPerson.default_tag_ids || [],
                              })}
                              disabled={updatePersonMutation.isPending}
                              className="px-3 py-1.5 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-1.5 text-sm"
                            >
                              <Save className="w-3.5 h-3.5" />
                              Save
                            </button>
                            <button
                              onClick={() => setEditingPerson(null)}
                              className="px-3 py-1.5 rounded-lg border border-border hover:bg-secondary text-sm"
                            >
                              Cancel
                            </button>
                          </div>
                        </div>
                      ) : (
                        /* Display Mode */
                        <div className="flex items-center gap-3">
                          <div
                            className="w-4 h-4 rounded-full flex-shrink-0"
                            style={{ backgroundColor: person.relationship.color }}
                          />
                          <div className="flex-1 min-w-0">
                            <p className="font-medium truncate">{person.name}</p>
                            <p className="text-sm text-muted-foreground">
                              {person.relationship.name}
                              {person.sort_name && ` \u2022 ${person.sort_name}`}
                            </p>
                            {person.default_tag_ids && person.default_tag_ids.length > 0 && (
                              <div className="flex flex-wrap gap-1 mt-1">
                                {person.default_tag_ids.map(tagId => {
                                  const tag = tags.find(t => t.id === tagId)
                                  if (!tag) return null
                                  return (
                                    <span
                                      key={tagId}
                                      className="px-2 py-0.5 rounded-full text-xs text-white"
                                      style={{ backgroundColor: tag.color }}
                                    >
                                      {tag.name}
                                    </span>
                                  )
                                })}
                              </div>
                            )}
                          </div>
                          <button
                            onClick={() => setEditingPerson(person)}
                            className="p-2 rounded hover:bg-secondary"
                          >
                            <Edit className="w-4 h-4" />
                          </button>
                          <button
                            onClick={() => {
                              if (confirm(`Delete "${person.name}"? Media will be unassigned.`)) {
                                deletePersonMutation.mutate(person.id)
                              }
                            }}
                            className="p-2 rounded hover:bg-destructive/20 text-destructive"
                          >
                            <Trash2 className="w-4 h-4" />
                          </button>
                        </div>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Person Groups */}
            {activeTab === 'groups' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Person Groups</h2>
                <p className="text-sm text-muted-foreground">
                  Organize persons into groups for quick filtering in the gallery.
                </p>
                <PersonGroupsTab persons={persons} tags={tags} relationships={relationships} />
              </div>
            )}

            {/* Reddit Monitor */}
            {activeTab === 'reddit' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Reddit Community Monitor</h2>
                <p className="text-sm text-muted-foreground">
                  Monitor Reddit communities for new posts and automatically import media to the gallery.
                </p>
                <RedditTab persons={persons} />
              </div>
            )}

            {/* Instagram */}
            {activeTab === 'instagram' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Instagram Account Mapping</h2>
                <p className="text-sm text-muted-foreground">
                  Map Instagram scraper accounts to persons and auto-import downloaded media as gallery posts.
                </p>
                <ScraperAccountTab platform="instagram" platformLabel="Instagram" persons={persons} />
              </div>
            )}

            {/* TikTok */}
            {activeTab === 'tiktok' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">TikTok Account Mapping</h2>
                <p className="text-sm text-muted-foreground">
                  Map TikTok scraper accounts to persons and auto-import downloaded media as gallery posts.
                </p>
                <ScraperAccountTab platform="tiktok" platformLabel="TikTok" persons={persons} />
              </div>
            )}

            {/* Snapchat */}
            {activeTab === 'snapchat' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Snapchat Account Mapping</h2>
                <p className="text-sm text-muted-foreground">
                  Map Snapchat scraper accounts to persons and auto-import downloaded media as gallery posts.
                </p>
                <ScraperAccountTab platform="snapchat" platformLabel="Snapchat" persons={persons} />
              </div>
            )}

            {/* Statistics */}
            {activeTab === 'stats' && (
              <div className="space-y-6">
                {isLoadingStats ? (
                  <div className="flex justify-center py-12">
                    <Loader2 className="w-8 h-8 animate-spin text-primary" />
                  </div>
                ) : stats ? (
                  <>
                    {/* Overview Cards */}
                    <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                      <div className="bg-card rounded-xl border border-border p-4">
                        <div className="flex items-center gap-3">
                          <div className="p-2 rounded-lg bg-primary/10">
                            <ImageIcon className="w-5 h-5 text-primary" />
                          </div>
                          <div>
                            <p className="text-sm text-muted-foreground">Total Items</p>
                            <p className="text-2xl font-bold">{stats.total_items}</p>
                          </div>
                        </div>
                      </div>
                      <div className="bg-card rounded-xl border border-border p-4">
                        <div className="flex items-center gap-3">
                          <div className="p-2 rounded-lg bg-emerald-500/10">
                            <Users className="w-5 h-5 text-emerald-500" />
                          </div>
                          <div>
                            <p className="text-sm text-muted-foreground">Persons</p>
                            <p className="text-2xl font-bold">{stats.total_persons}</p>
                          </div>
                        </div>
                      </div>
                      <div className="bg-card rounded-xl border border-border p-4">
                        <div className="flex items-center gap-3">
                          <div className="p-2 rounded-lg bg-amber-500/10">
                            <HardDrive className="w-5 h-5 text-amber-500" />
                          </div>
                          <div>
                            <p className="text-sm text-muted-foreground">Total Size</p>
                            <p className="text-2xl font-bold">{formatFileSize(stats.total_size)}</p>
                          </div>
                        </div>
                      </div>
                      <div className="bg-card rounded-xl border border-border p-4">
                        <div className="flex items-center gap-3">
                          <div className="p-2 rounded-lg bg-blue-500/10">
                            <Calendar className="w-5 h-5 text-blue-500" />
                          </div>
                          <div>
                            <p className="text-sm text-muted-foreground">Last 7 Days</p>
                            <p className="text-2xl font-bold">{stats.recent_7d}</p>
                          </div>
                        </div>
                      </div>
                    </div>

                    {/* By Type */}
                    <div className="bg-card rounded-xl border border-border p-4 sm:p-6">
                      <h3 className="font-semibold mb-4">By Type</h3>
                      <div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
                        <div className="flex items-center gap-3">
                          <ImageIcon className="w-5 h-5 text-muted-foreground" />
                          <span>Images: {stats.by_type?.image || 0}</span>
                        </div>
                        <div className="flex items-center gap-3">
                          <Video className="w-5 h-5 text-muted-foreground" />
                          <span>Videos: {stats.by_type?.video || 0}</span>
                        </div>
                      </div>
                    </div>

                    {/* Storage Usage */}
                    <div className="bg-card rounded-xl border border-border p-6">
                      <h3 className="font-semibold mb-4">Storage Usage</h3>
                      <p className="text-muted-foreground">
                        Encrypted files on disk: {formatFileSize(stats.storage_used)}
                      </p>
                    </div>
                  </>
                ) : null}
              </div>
            )}

            {/* Security */}
            {activeTab === 'security' && (
              <div className="bg-card rounded-xl border border-border p-6 space-y-6">
                <h2 className="text-lg font-semibold">Change Password</h2>
                <p className="text-sm text-muted-foreground">
                  Update your gallery password. You will remain logged in after changing.
                </p>

                {passwordSuccess && (
                  <div className="p-4 rounded-lg bg-emerald-500/10 text-emerald-600 flex items-center gap-2">
                    <Check className="w-5 h-5" />
                    Password changed successfully
                  </div>
                )}

                {passwordError && (
                  <div className="p-4 rounded-lg bg-destructive/10 text-destructive">
                    {passwordError}
                  </div>
                )}

                <div className="space-y-4 max-w-md">
                  <div>
                    <label className="block text-sm font-medium mb-2">Current Password</label>
                    <input
                      type="password"
                      value={currentPassword}
                      onChange={(e) => setCurrentPassword(e.target.value)}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-medium mb-2">New Password</label>
                    <input
                      type="password"
                      value={newPassword}
                      onChange={(e) => setNewPassword(e.target.value)}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                      placeholder="At least 8 characters"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-medium mb-2">Confirm New Password</label>
                    <input
                      type="password"
                      value={confirmPassword}
                      onChange={(e) => setConfirmPassword(e.target.value)}
                      className="w-full px-4 py-2.5 rounded-lg border border-border bg-background"
                    />
                  </div>
                </div>

                <button
                  onClick={handleChangePassword}
                  disabled={isChangingPassword || !currentPassword || !newPassword || !confirmPassword}
                  className="px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 flex items-center gap-2 transition-colors"
                >
                  {isChangingPassword ? (
                    <Loader2 className="w-4 h-4 animate-spin" />
                  ) : (
                    <Lock className="w-4 h-4" />
                  )}
                  Change Password
                </button>
              </div>
            )}
          </div>
    </div>
  )
}
