import { useState, useEffect, useMemo, useRef } from 'react'
import facesApi, { 
  AutoMatchPersonSummary,
  AutoMatchFaceItem
} from '../api/faces'
import peopleApi, { Person } from '../api/people'
import { apiClient } from '../api/client'
import { useDeveloperMode } from '../context/DeveloperModeContext'

const DEFAULT_TOLERANCE = 0.6

export default function AutoMatch() {
  const { isDeveloperMode } = useDeveloperMode()
  const [tolerance, setTolerance] = useState(DEFAULT_TOLERANCE)
  const [autoAcceptThreshold, setAutoAcceptThreshold] = useState(70)
  const [isActive, setIsActive] = useState(false)
  const [people, setPeople] = useState<AutoMatchPersonSummary[]>([])
  const [filteredPeople, setFilteredPeople] = useState<AutoMatchPersonSummary[]>([])
  // Store matches separately, keyed by person_id
  const [matchesCache, setMatchesCache] = useState<Record<number, AutoMatchFaceItem[]>>({})
  const [currentIndex, setCurrentIndex] = useState(0)
  const [searchQuery, setSearchQuery] = useState('')
  const [allPeople, setAllPeople] = useState<Person[]>([])
  const [loadingPeople, setLoadingPeople] = useState(false)
  const [showPeopleDropdown, setShowPeopleDropdown] = useState(false)
  const searchInputRef = useRef<HTMLInputElement>(null)
  const dropdownRef = useRef<HTMLDivElement>(null)
  const [selectedFaces, setSelectedFaces] = useState<Record<number, boolean>>({})
  const [originalSelectedFaces, setOriginalSelectedFaces] = useState<Record<number, boolean>>({})
  const [busy, setBusy] = useState(false)
  const [saving, setSaving] = useState(false)
  const [hasNoResults, setHasNoResults] = useState(false)
  const [isRefreshing, setIsRefreshing] = useState(false)

  // SessionStorage keys for persisting state and settings
  const STATE_KEY = 'automatch_state'
  const SETTINGS_KEY = 'automatch_settings'

  // Track if initial load has happened
  const initialLoadRef = useRef(false)
  // Track if settings have been loaded from sessionStorage
  const [settingsLoaded, setSettingsLoaded] = useState(false)
  // Track if state has been restored from sessionStorage
  const [stateRestored, setStateRestored] = useState(false)
  // Track if initial restoration is complete (prevents reload effects from firing during restoration)
  const restorationCompleteRef = useRef(false)

  const currentPerson = useMemo(() => {
    const activePeople = filteredPeople.length > 0 ? filteredPeople : people
    return activePeople[currentIndex]
  }, [filteredPeople, people, currentIndex])

  const currentMatches = useMemo(() => {
    if (!currentPerson) return []
    return matchesCache[currentPerson.person_id] || []
  }, [currentPerson, matchesCache])

  // Check if any matches are selected
  const hasSelectedMatches = useMemo(() => {
    return currentMatches.some(match => selectedFaces[match.id] === true)
  }, [currentMatches, selectedFaces])

  // Load matches for a specific person (lazy loading)
  const loadPersonMatches = async (personId: number) => {
    // Skip if already cached
    if (matchesCache[personId]) {
      return
    }

    try {
      const response = await facesApi.getAutoMatchPersonMatches(personId, {
        tolerance,
        filter_frontal_only: false
      })
      
      setMatchesCache(prev => ({
        ...prev,
        [personId]: response.matches
      }))
      
      // Update total_matches in people list
      setPeople(prev => prev.map(p => 
        p.person_id === personId 
          ? { ...p, total_matches: response.total_matches }
          : p
      ))
      
      // If no matches found, remove person from list (matching original behavior)
      // Original endpoint only returns people who have matches
      if (response.total_matches === 0) {
        setPeople(prev => {
          const removedIndex = prev.findIndex(p => p.person_id === personId)
          // Adjust current index if needed
          if (removedIndex !== -1) {
            setCurrentIndex(currentIdx => {
              if (currentIdx >= removedIndex) {
                return Math.max(0, currentIdx - 1)
              }
              return currentIdx
            })
          }
          return prev.filter(p => p.person_id !== personId)
        })
        setFilteredPeople(prev => prev.filter(p => p.person_id !== personId))
      }
    } catch (error) {
      console.error('Failed to load matches for person:', error)
      // Set empty matches on error, and remove person from list
      setMatchesCache(prev => ({
        ...prev,
        [personId]: []
      }))
      // Remove person if matches failed to load (assume no matches)
      setPeople(prev => prev.filter(p => p.person_id !== personId))
      setFilteredPeople(prev => prev.filter(p => p.person_id !== personId))
    }
  }

  // Shared function for auto-load and refresh (loads people list only - fast)
  const loadAutoMatch = async (clearState: boolean = false) => {
    if (tolerance < 0 || tolerance > 1) {
      return
    }

    setBusy(true)
    setIsRefreshing(true)
    try {
      // Clear saved state if explicitly requested (Refresh button)
      if (clearState) {
        sessionStorage.removeItem(STATE_KEY)
        setMatchesCache({}) // Clear matches cache
      }

      // Load people list only (fast - no match calculations)
      const response = await facesApi.getAutoMatchPeople({
        filter_frontal_only: false
      })
      
      if (response.people.length === 0) {
        setHasNoResults(true)
        setPeople([])
        setFilteredPeople([])
        setIsActive(false)
        setBusy(false)
        setIsRefreshing(false)
        return
      }

      setHasNoResults(false)
      setPeople(response.people)
      setFilteredPeople([])
      setCurrentIndex(0)
      setSelectedFaces({})
      setOriginalSelectedFaces({})
      setIsActive(true)
      
      // Load matches for first person immediately
      if (response.people.length > 0) {
        await loadPersonMatches(response.people[0].person_id)
      }
    } catch (error) {
      console.error('Auto-match failed:', error)
    } finally {
      setBusy(false)
      setIsRefreshing(false)
    }
  }

  // Load settings from sessionStorage on mount
  useEffect(() => {
    try {
      const saved = sessionStorage.getItem(SETTINGS_KEY)
      if (saved) {
        const settings = JSON.parse(saved)
        if (settings.tolerance !== undefined) setTolerance(settings.tolerance)
        if (settings.autoAcceptThreshold !== undefined) setAutoAcceptThreshold(settings.autoAcceptThreshold)
      }
    } catch (error) {
      console.error('Error loading settings from sessionStorage:', error)
    } finally {
      setSettingsLoaded(true)
    }
  }, [])

  // Load state from sessionStorage on mount (people, current index, selected faces)
  // Note: This effect runs after settings are loaded, so tolerance is already set
  useEffect(() => {
    if (!settingsLoaded) return // Wait for settings to load first
    
    try {
      const saved = sessionStorage.getItem(STATE_KEY)
      if (saved) {
        const state = JSON.parse(saved)
        // Only restore state if tolerance matches (cached state is for current tolerance)
        if (state.people && Array.isArray(state.people) && state.people.length > 0 && 
            state.tolerance === tolerance) {
          setPeople(state.people)
          if (state.currentIndex !== undefined) {
            setCurrentIndex(Math.min(state.currentIndex, state.people.length - 1))
          }
          if (state.selectedFaces && typeof state.selectedFaces === 'object') {
            setSelectedFaces(state.selectedFaces)
          }
          if (state.originalSelectedFaces && typeof state.originalSelectedFaces === 'object') {
            setOriginalSelectedFaces(state.originalSelectedFaces)
          }
          if (state.matchesCache && typeof state.matchesCache === 'object') {
            setMatchesCache(state.matchesCache)
          }
          if (state.isActive !== undefined) {
            setIsActive(state.isActive)
          }
          if (state.hasNoResults !== undefined) {
            setHasNoResults(state.hasNoResults)
          }
          // Mark that we restored state, so we don't reload
          initialLoadRef.current = true
          // Mark restoration as complete after state is restored
          setTimeout(() => {
            restorationCompleteRef.current = true
          }, 50)
        } else if (state.tolerance !== undefined && state.tolerance !== tolerance) {
          // Tolerance changed, clear old cache
          sessionStorage.removeItem(STATE_KEY)
        }
      }
    } catch (error) {
      console.error('Error loading state from sessionStorage:', error)
    } finally {
      setStateRestored(true)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [settingsLoaded])

  // Save state to sessionStorage whenever it changes (but only after initial restore)
  useEffect(() => {
    if (!stateRestored) return // Don't save during initial restore
    
    try {
      const state = {
        people,
        currentIndex,
        selectedFaces,
        originalSelectedFaces,
        matchesCache,
        isActive,
        hasNoResults,
        tolerance, // Include tolerance to validate cache on restore
      }
      sessionStorage.setItem(STATE_KEY, JSON.stringify(state))
    } catch (error) {
      console.error('Error saving state to sessionStorage:', error)
    }
  }, [people, currentIndex, selectedFaces, originalSelectedFaces, matchesCache, isActive, hasNoResults, tolerance, stateRestored])

  // Save state on unmount (when navigating away) - use refs to capture latest values
  const peopleRef = useRef(people)
  const currentIndexRef = useRef(currentIndex)
  const selectedFacesRef = useRef(selectedFaces)
  const originalSelectedFacesRef = useRef(originalSelectedFaces)
  const matchesCacheRef = useRef(matchesCache)
  const isActiveRef = useRef(isActive)
  const hasNoResultsRef = useRef(hasNoResults)
  const toleranceRef = useRef(tolerance)

  // Update refs whenever state changes
  useEffect(() => {
    peopleRef.current = people
    currentIndexRef.current = currentIndex
    selectedFacesRef.current = selectedFaces
    originalSelectedFacesRef.current = originalSelectedFaces
    matchesCacheRef.current = matchesCache
    isActiveRef.current = isActive
    hasNoResultsRef.current = hasNoResults
    toleranceRef.current = tolerance
  }, [people, currentIndex, selectedFaces, originalSelectedFaces, matchesCache, isActive, hasNoResults, tolerance])

  // Save state on unmount (when navigating away)
  useEffect(() => {
    return () => {
      try {
        const state = {
          people: peopleRef.current,
          currentIndex: currentIndexRef.current,
          selectedFaces: selectedFacesRef.current,
          originalSelectedFaces: originalSelectedFacesRef.current,
          matchesCache: matchesCacheRef.current,
          isActive: isActiveRef.current,
          hasNoResults: hasNoResultsRef.current,
          tolerance: toleranceRef.current, // Include tolerance to validate cache on restore
        }
        sessionStorage.setItem(STATE_KEY, JSON.stringify(state))
      } catch (error) {
        console.error('Error saving state on unmount:', error)
      }
    }
  }, [])

  // Save settings to sessionStorage whenever they change (but only after initial load)
  useEffect(() => {
    if (!settingsLoaded) return // Don't save during initial load
    try {
      const settings = {
        tolerance,
        autoAcceptThreshold,
      }
      sessionStorage.setItem(SETTINGS_KEY, JSON.stringify(settings))
    } catch (error) {
      console.error('Error saving settings to sessionStorage:', error)
    }
  }, [tolerance, autoAcceptThreshold, settingsLoaded])

  // Load all people for dropdown
  useEffect(() => {
    const loadAllPeople = async () => {
      try {
        setLoadingPeople(true)
        const response = await peopleApi.list()
        setAllPeople(response.items || [])
      } catch (error) {
        console.error('Failed to load people:', error)
        setAllPeople([])
      } finally {
        setLoadingPeople(false)
      }
    }
    loadAllPeople()
  }, [])

  // Initial load on mount (after settings and state are loaded)
  useEffect(() => {
    if (!initialLoadRef.current && settingsLoaded && stateRestored) {
      initialLoadRef.current = true
      // Only load if we didn't restore state (no people means we need to load)
      if (people.length === 0) {
        loadAutoMatch()
        // If we're loading fresh, mark restoration as complete immediately
        restorationCompleteRef.current = true
      } else {
        // If state was restored, restorationCompleteRef is already set in the state restoration effect
        // But ensure it's set in case state restoration didn't happen
        if (!restorationCompleteRef.current) {
          setTimeout(() => {
            restorationCompleteRef.current = true
          }, 50)
        }
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [settingsLoaded, stateRestored])

  // Reload when tolerance changes (immediate reload)
  // But only if restoration is complete (prevents reload during initial restoration)
  useEffect(() => {
    if (initialLoadRef.current && restorationCompleteRef.current) {
      // Clear matches cache when tolerance changes (matches depend on tolerance)
      setMatchesCache({})
      loadAutoMatch()
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tolerance])

  // Apply search filter
  useEffect(() => {
    if (!searchQuery.trim()) {
      setFilteredPeople([])
      return
    }

    const query = searchQuery.trim().toLowerCase()
    const filtered = people.filter(person => {
      // Extract last name from person name (matching desktop logic)
      let lastName = ''
      if (person.person_name.includes(',')) {
        lastName = person.person_name.split(',')[0].trim().toLowerCase()
      } else {
        const nameParts = person.person_name.trim().split(' ')
        if (nameParts.length > 0) {
          lastName = nameParts[nameParts.length - 1].toLowerCase()
        }
      }
      return lastName.includes(query)
    })

    setFilteredPeople(filtered)
    setCurrentIndex(0)
  }, [searchQuery, people])

  const startAutoMatch = async () => {
    if (tolerance < 0 || tolerance > 1) {
      alert('Please enter a valid tolerance value between 0.0 and 1.0.')
      return
    }

    if (autoAcceptThreshold < 0 || autoAcceptThreshold > 100) {
      alert('Please enter a valid auto-accept threshold between 0 and 100.')
      return
    }

    setBusy(true)
    try {
      const response = await facesApi.autoMatch({ 
        tolerance,
        auto_accept: true,
        auto_accept_threshold: autoAcceptThreshold
      })
      
      // Show summary if auto-accept was performed
      if (response.auto_accepted) {
        const summary = [
          `✅ Auto-matched ${response.auto_accepted_faces || 0} faces`,
          response.skipped_persons ? `⚠️ Skipped ${response.skipped_persons} persons (non-frontal reference)` : '',
          response.skipped_matches ? `ℹ️ Skipped ${response.skipped_matches} matches (didn't meet criteria)` : ''
        ].filter(Boolean).join('\n')
        
        if (summary) {
          alert(summary)
        }
        
        // Reload faces after auto-accept to remove auto-accepted faces from the list
        // Clear cache to get fresh data after auto-accept
        await loadAutoMatch(true)
        return
      }
      
      if (response.people.length === 0) {
        alert('🔍 No similar faces found for auto-identification')
        setHasNoResults(true)
        setPeople([])
        setFilteredPeople([])
        setIsActive(false)
        setBusy(false)
        return
      }

      setHasNoResults(false)
      setPeople(response.people)
      setFilteredPeople([])
      setCurrentIndex(0)
      setSelectedFaces({})
      setOriginalSelectedFaces({})
      setIsActive(true)
    } catch (error) {
      console.error('Auto-match failed:', error)
      alert('Failed to start auto-match. Please try again.')
    } finally {
      setBusy(false)
    }
  }

  const handleFaceToggle = (faceId: number) => {
    setSelectedFaces(prev => ({
      ...prev,
      [faceId]: !prev[faceId],
    }))
  }

  const selectAll = () => {
    const newSelected: Record<number, boolean> = {}
    currentMatches.forEach(match => {
      newSelected[match.id] = true
    })
    setSelectedFaces(newSelected)
  }

  const clearAll = () => {
    const newSelected: Record<number, boolean> = {}
    currentMatches.forEach(match => {
      newSelected[match.id] = false
    })
    setSelectedFaces(newSelected)
  }

  const saveChanges = async () => {
    if (!currentPerson) return

    setSaving(true)
    try {
      const faceIds = currentMatches
        .filter(match => selectedFaces[match.id] === true)
        .map(match => match.id)

      await peopleApi.acceptMatches(currentPerson.person_id, faceIds)

      // Update original selected faces to current state
      const newOriginal: Record<number, boolean> = {}
      currentMatches.forEach(match => {
        newOriginal[match.id] = selectedFaces[match.id] || false
      })
      setOriginalSelectedFaces(prev => ({ ...prev, ...newOriginal }))

      alert(`✅ Saved ${faceIds.length} match(es)`)
    } catch (error) {
      console.error('Save failed:', error)
      alert('Failed to save matches. Please try again.')
    } finally {
      setSaving(false)
    }
  }

  // Load matches when current person changes (lazy loading)
  useEffect(() => {
    if (currentPerson && restorationCompleteRef.current) {
      loadPersonMatches(currentPerson.person_id)
      
      // Preload matches for next person in background
      const activePeople = filteredPeople.length > 0 ? filteredPeople : people
      if (currentIndex + 1 < activePeople.length) {
        const nextPerson = activePeople[currentIndex + 1]
        loadPersonMatches(nextPerson.person_id)
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentPerson?.person_id, currentIndex])

  // Restore selected faces when navigating to a different person
  useEffect(() => {
    if (currentPerson) {
      const matches = matchesCache[currentPerson.person_id] || []
      const restored: Record<number, boolean> = {}
      matches.forEach(match => {
        restored[match.id] = originalSelectedFaces[match.id] || false
      })
      setSelectedFaces(restored)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentIndex, filteredPeople.length, people.length, currentPerson?.person_id, matchesCache])

  const goBack = () => {
    if (currentIndex > 0) {
      setCurrentIndex(currentIndex - 1)
    }
  }

  const goNext = () => {
    const activePeople = filteredPeople.length > 0 ? filteredPeople : people
    if (currentIndex < activePeople.length - 1) {
      setCurrentIndex(currentIndex + 1)
    }
  }

  const clearSearch = () => {
    setSearchQuery('')
    setFilteredPeople([])
    setCurrentIndex(0)
    setShowPeopleDropdown(false)
  }

  const formatPersonName = (person: Person): string => {
    const parts: string[] = []
    
    // Last name with comma
    if (person.last_name) {
      parts.push(`${person.last_name},`)
    }
    
    // Middle name between last and first
    if (person.middle_name) {
      parts.push(person.middle_name)
    }
    
    // First name
    if (person.first_name) {
      parts.push(person.first_name)
    }
    
    // Maiden name in parentheses
    if (person.maiden_name) {
      parts.push(`(${person.maiden_name})`)
    }
    
    if (parts.length === 0) {
      return person.first_name || person.last_name || 'Unknown'
    }
    
    // Format as "Last, Middle First (Maiden)"
    return parts.join(' ')
  }

  const formatFullPersonName = (personId: number): string => {
    const person = allPeople.find(p => p.id === personId)
    if (!person) {
      // Fallback to person_name if person not found in allPeople
      const currentPersonData = people.find(p => p.person_id === personId) || 
                                filteredPeople.find(p => p.person_id === personId)
      return currentPersonData?.person_name || 'Unknown'
    }
    
    return formatPersonName(person)
  }

  const handlePersonSelect = (personId: number) => {
    const person = allPeople.find(p => p.id === personId)
    if (person) {
      // Extract last name and set as search query
      const lastName = person.last_name || ''
      setSearchQuery(lastName)
      setShowPeopleDropdown(false)
    }
  }

  // Filter people based on search query for dropdown
  const filteredPeopleForDropdown = useMemo(() => {
    if (!searchQuery.trim()) {
      return allPeople
    }
    const query = searchQuery.trim().toLowerCase()
    return allPeople.filter(person => {
      const lastName = (person.last_name || '').toLowerCase()
      const firstName = (person.first_name || '').toLowerCase()
      const middleName = (person.middle_name || '').toLowerCase()
      const fullName = `${lastName}, ${firstName}${middleName ? ` ${middleName}` : ''}`.toLowerCase()
      return fullName.includes(query) || lastName.includes(query) || firstName.includes(query)
    })
  }, [searchQuery, allPeople])

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node) &&
        searchInputRef.current &&
        !searchInputRef.current.contains(event.target as Node)
      ) {
        setShowPeopleDropdown(false)
      }
    }

    document.addEventListener('mousedown', handleClickOutside)
    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
    }
  }, [])

  const activePeople = filteredPeople.length > 0 ? filteredPeople : people
  const canGoBack = currentIndex > 0
  const canGoNext = currentIndex < activePeople.length - 1

  return (
    <div className="flex flex-col h-full">

      {/* Configuration */}
      <div className="bg-white rounded-lg shadow p-4 mb-4">
        <div className="flex items-center gap-4">
          <button
            onClick={() => loadAutoMatch(true)}
            disabled={busy}
            className="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 disabled:bg-gray-400 disabled:cursor-not-allowed"
            title="Refresh and start from beginning"
          >
            {isRefreshing ? 'Refreshing...' : '🔄 Refresh'}
          </button>
          {isDeveloperMode && (
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium text-gray-700">Tolerance:</label>
              <input
                type="number"
                min="0"
                max="1"
                step="0.1"
                value={tolerance}
                onChange={(e) => setTolerance(parseFloat(e.target.value) || 0)}
                disabled={busy}
                className="w-20 px-2 py-1 border border-gray-300 rounded text-sm"
              />
              <span className="text-xs text-gray-500">(lower = stricter matching)</span>
            </div>
          )}
          <div className="flex items-center gap-2">
            <button
              onClick={startAutoMatch}
              disabled={busy || hasNoResults}
              className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed"
              title={hasNoResults ? 'No matches found. Adjust tolerance or process more photos.' : ''}
            >
              {busy ? 'Processing...' : hasNoResults ? 'No Matches Available' : '🚀 Run Auto-Match'}
            </button>
          </div>
          {isDeveloperMode && (
            <div className="flex items-center gap-2">
              <label className="text-sm font-medium text-gray-700">Auto-Accept Threshold:</label>
              <input
                type="number"
                min="0"
                max="100"
                step="5"
                value={autoAcceptThreshold}
                onChange={(e) => setAutoAcceptThreshold(parseInt(e.target.value) || 70)}
                disabled={busy || hasNoResults}
                className="w-20 px-2 py-1 border border-gray-300 rounded text-sm"
              />
              <span className="text-xs text-gray-500">% (min similarity)</span>
            </div>
          )}
        </div>
        <div className="mt-2 text-xs text-gray-600 bg-blue-50 border border-blue-200 rounded p-2">
          <span className="font-medium">ℹ️ Auto-Match Criteria:</span> Only faces with similarity higher than 70% and picture quality higher than 50% will be auto-matched. Profile faces are excluded for better accuracy.
        </div>
      </div>

      {isActive && (
        <>
          {/* Main panels */}
          <div className="flex-1 grid grid-cols-2 gap-4 mb-4">
            {/* Left panel - Identified Person */}
            <div className="bg-white rounded-lg shadow p-4 flex flex-col">
              <h2 className="text-lg font-semibold mb-4">Identified Person</h2>

              {/* Search controls */}
              <div className="mb-4">
                <div className="flex gap-2 mb-2 relative">
                  <div className="flex-1 relative">
                    <input
                      ref={searchInputRef}
                      type="text"
                      placeholder="Type Last Name or Select Person"
                      value={searchQuery}
                      onChange={(e) => {
                        setSearchQuery(e.target.value)
                        setShowPeopleDropdown(true)
                      }}
                      onFocus={() => setShowPeopleDropdown(true)}
                      disabled={people.length === 1 || loadingPeople}
                      className="w-full px-3 py-2 border border-gray-300 rounded text-sm"
                    />
                    {showPeopleDropdown && filteredPeopleForDropdown.length > 0 && !loadingPeople && (
                      <div
                        ref={dropdownRef}
                        className="absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded shadow-lg max-h-60 overflow-auto"
                      >
                        {filteredPeopleForDropdown.map((person) => (
                          <div
                            key={person.id}
                            onClick={() => handlePersonSelect(person.id)}
                            className="px-3 py-2 hover:bg-blue-50 cursor-pointer text-sm"
                          >
                            {formatPersonName(person)}
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                  <button
                    onClick={clearSearch}
                    disabled={people.length === 1}
                    className="px-3 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:bg-gray-100 disabled:cursor-not-allowed text-sm"
                  >
                    Clear
                  </button>
                </div>
                {people.length === 1 && (
                  <p className="text-xs text-gray-500">(Search disabled - only one person found)</p>
                )}
              </div>

              {/* Person info */}
              {currentPerson && (
                <>
                  <div className="mb-4">
                    <div className="flex items-center justify-between mb-2">
                      {isDeveloperMode && (
                        <div className="text-sm text-gray-600">
                          Person {currentIndex + 1}
                        </div>
                      )}
                      <div className="space-x-2">
                        <button
                          onClick={goBack}
                          disabled={!canGoBack}
                          className="px-2 py-1 text-sm border rounded hover:bg-gray-50 disabled:bg-gray-100 disabled:cursor-not-allowed disabled:text-gray-400"
                        >
                          Prev
                        </button>
                        <button
                          onClick={goNext}
                          disabled={!canGoNext}
                          className="px-2 py-1 text-sm border rounded hover:bg-gray-50 disabled:bg-gray-100 disabled:cursor-not-allowed disabled:text-gray-400"
                        >
                          Next
                        </button>
                      </div>
                    </div>
                    <p className="font-semibold">👤 Person: {formatFullPersonName(currentPerson.person_id)}</p>
                    <p className="text-sm text-gray-600">
                      📁 Photo: {currentPerson.reference_photo_filename}
                    </p>
                    {isDeveloperMode && (
                      <p className="text-sm text-gray-600">
                        📍 Face location: {currentPerson.reference_location}
                      </p>
                    )}
                    <p className="text-sm text-gray-600">
                      📊 {currentPerson.face_count} faces already identified
                    </p>
                  </div>

                  {/* Person face image */}
                  <div className="mb-4 flex justify-center">
                    <div
                      className="cursor-pointer hover:opacity-90 transition-opacity"
                      onClick={() => {
                        const photoUrl = `${apiClient.defaults.baseURL}/api/v1/photos/${currentPerson.reference_photo_id}/image`
                        window.open(photoUrl, '_blank')
                      }}
                      title="Click to open full photo"
                    >
                      <img
                        src={`/api/v1/faces/${currentPerson.reference_face_id}/crop`}
                        alt="Reference face"
                        className="max-w-[300px] max-h-[300px] rounded border border-gray-300"
                      />
                    </div>
                  </div>

                  {/* Save button */}
                  <div className="flex justify-center">
                    <button
                      onClick={saveChanges}
                      disabled={saving || !hasSelectedMatches}
                      className="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 disabled:bg-gray-400 disabled:cursor-not-allowed"
                    >
                      {saving ? '💾 Saving...' : `💾 Save matches for ${currentPerson.person_name}`}
                    </button>
                  </div>
                </>
              )}
            </div>

            {/* Right panel - Unidentified Faces */}
            <div className="bg-white rounded-lg shadow p-4 flex flex-col">
              <h2 className="text-lg font-semibold mb-4">Unidentified Faces to Match</h2>

              {/* Select All / Clear All buttons */}
              <div className="flex gap-2 mb-4">
                <button
                  onClick={selectAll}
                  disabled={currentMatches.length === 0}
                  className="px-3 py-1 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:bg-gray-100 disabled:cursor-not-allowed text-sm"
                >
                  ☑️ Select All
                </button>
                <button
                  onClick={clearAll}
                  disabled={currentMatches.length === 0}
                  className="px-3 py-1 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:bg-gray-100 disabled:cursor-not-allowed text-sm"
                >
                  ☐ Clear All
                </button>
              </div>

              {/* Matches grid */}
              <div className="flex-1 overflow-y-auto">
                {currentMatches.length === 0 ? (
                  <p className="text-gray-500 text-center py-8">No matches found</p>
                ) : (
                  <div className="space-y-2">
                    {currentMatches.map((match) => (
                      <div
                        key={match.id}
                        className="flex items-center gap-3 p-2 border border-gray-200 rounded hover:bg-gray-50"
                      >
                        <input
                          type="checkbox"
                          checked={selectedFaces[match.id] || false}
                          onChange={() => handleFaceToggle(match.id)}
                          className="w-4 h-4"
                        />
                        <div
                          className="cursor-pointer hover:opacity-90 transition-opacity"
                          onClick={() => {
                            const photoUrl = `${apiClient.defaults.baseURL}/api/v1/photos/${match.photo_id}/image`
                            window.open(photoUrl, '_blank')
                          }}
                          title="Click to open full photo"
                        >
                          <img
                            src={`/api/v1/faces/${match.id}/crop`}
                            alt="Match face"
                            className="w-20 h-20 object-cover rounded border border-gray-300"
                          />
                        </div>
                        <div className="flex-1">
                          <div className="flex items-center gap-2 mb-1">
                            <span
                              className={`px-2 py-1 rounded text-xs font-semibold ${
                                match.similarity >= 70
                                  ? 'bg-green-100 text-green-800'
                                  : match.similarity >= 60
                                  ? 'bg-yellow-100 text-yellow-800'
                                  : 'bg-orange-100 text-orange-800'
                              }`}
                            >
                              {Math.round(match.similarity)}% Match
                            </span>
                          </div>
                          <p className="text-xs text-gray-600">📁 {match.photo_filename}</p>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </div>
          </div>

          {/* Navigation controls */}
          <div className="flex items-center justify-between bg-white rounded-lg shadow p-4">
            <div className="flex gap-2">
              <button
                onClick={goBack}
                disabled={!canGoBack}
                className="px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:bg-gray-100 disabled:cursor-not-allowed"
              >
                ⏮️ Back
              </button>
              <button
                onClick={goNext}
                disabled={!canGoNext}
                className="px-4 py-2 bg-gray-100 text-gray-700 rounded hover:bg-gray-200 disabled:bg-gray-100 disabled:cursor-not-allowed"
              >
                ⏭️ Next
              </button>
            </div>
            <div className="text-sm text-gray-600">
              {isDeveloperMode && `Person ${currentIndex + 1} `}
              {currentPerson && `• ${currentPerson.total_matches} matches`}
            </div>
          </div>
        </>
      )}

    </div>
  )
}
