import { motion, AnimatePresence } from 'framer-motion'
import {
  Search,
  Filter,
  X,
  ChevronDown,
  ArrowUpDown,
  RefreshCw,
  Loader2,
  Sparkles,
  Wifi,
  Globe,
  Monitor,
  Link2,
  Bell,
  Building2,
  Bookmark,
  CheckSquare,
  Square,
  Share2,
} from 'lucide-react'
import { useState, useCallback, useMemo, useEffect, useRef } from 'react'
import { useNavigate } from 'react-router-dom'
import { usePageTitle } from '@/hooks/usePageTitle'
import { useDebounce } from '@/lib/utils'
import { JobCard, JobCardSkeleton } from '@/components/jobs/JobCard'
import { JobDetail } from '@/components/jobs/JobDetail'
import { ProfileCompletionBanner } from '@/components/ProfileCompletionBanner'
import { useToast } from '@/components/Toast'
import { SaveSearchModal } from '@/components/jobs/SaveSearchModal'
import { BulkApply } from '@/components/jobs/BulkApply'
import {
  JobComparison,
  CompareFloatingButton,
  CompareCheckbox,
} from '@/components/jobs/JobComparison'
import { useProfile } from '@/hooks/useProfile'
import {
  useListings,
  useSaveListing,
  useListingsRealtime,
  useFilterOptions,
  type ListingWithMatch,
} from '@/hooks/useListings'

const SORT_OPTIONS = [
  { value: 'newest', label: 'Newest First' },
  { value: 'match_score', label: 'Best Match' },
  { value: 'company', label: 'Company A-Z' },
  { value: 'location', label: 'Location A-Z' },
] as const

const REMOTE_OPTIONS = [
  { value: '', label: 'All Types' },
  { value: 'remote', label: 'Remote', icon: Wifi },
  { value: 'hybrid', label: 'Hybrid', icon: Globe },
  { value: 'onsite', label: 'On-site', icon: Monitor },
] as const

const DURATION_OPTIONS = [
  { value: '', label: 'Any Duration' },
  { value: '3 months', label: '3 months' },
  { value: '6 months', label: '6 months' },
  { value: '12 months', label: '12 months' },
] as const

export default function Jobs() {
  usePageTitle('Job Feed', 'Browse thousands of internships from 100+ sources. Filter by skills, location, and remote type. AI-matched to your profile.')
  const navigate = useNavigate()
  const { toast } = useToast()
  const {
    listings,
    loading,
    loadingMore,
    filters,
    hasMore,
    totalCount,
    loadMore,
    updateFilters,
    resetFilters,
    refresh,
  } = useListings()
  const { saveListing, unsaveListing } = useSaveListing()
  const { countries, companies: availableCompanies, skills: availableSkills, durations: availableDurations } = useFilterOptions()

  const { profile } = useProfile()

  const [selectedListing, setSelectedListing] = useState<ListingWithMatch | null>(null)
  const [showFilters, setShowFilters] = useState(false)
  const [showSort, setShowSort] = useState(false)
  const [newListingsCount, setNewListingsCount] = useState(0)
  const [showSaveSearch, setShowSaveSearch] = useState(false)
  const [bulkMode, setBulkMode] = useState(false)
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
  const [showBulkApply, setShowBulkApply] = useState(false)
  const [compareIds, setCompareIds] = useState<Set<string>>(new Set())
  const [showComparison, setShowComparison] = useState(false)
  const sortRef = useRef<HTMLDivElement>(null)

  // Debounced search: local state updates instantly, filter updates after 300ms
  const [localSearch, setLocalSearch] = useState(filters.search)
  const debouncedSearch = useDebounce(localSearch, 300)

  useEffect(() => {
    if (debouncedSearch !== filters.search) {
      updateFilters({ search: debouncedSearch })
    }
  }, [debouncedSearch]) // eslint-disable-line react-hooks/exhaustive-deps

  // Comparison handlers
  const toggleCompare = useCallback((id: string) => {
    setCompareIds((prev) => {
      const next = new Set(prev)
      if (next.has(id)) {
        next.delete(id)
      } else if (next.size < 3) {
        next.add(id)
      }
      return next
    })
  }, [])

  const compareJobs = useMemo(
    () => listings.filter((l) => compareIds.has(l.id)),
    [listings, compareIds]
  )

  // Close sort dropdown on click outside (JO-01) + Escape key
  useEffect(() => {
    if (!showSort) return
    function handleClickOutside(e: MouseEvent) {
      if (sortRef.current && !sortRef.current.contains(e.target as Node)) {
        setShowSort(false)
      }
    }
    function handleEscape(e: KeyboardEvent) {
      if (e.key === 'Escape') setShowSort(false)
    }
    document.addEventListener('mousedown', handleClickOutside)
    document.addEventListener('keydown', handleEscape)
    return () => {
      document.removeEventListener('mousedown', handleClickOutside)
      document.removeEventListener('keydown', handleEscape)
    }
  }, [showSort])

  // Close filters panel on Escape
  useEffect(() => {
    if (!showFilters) return
    function handleEscape(e: KeyboardEvent) {
      if (e.key === 'Escape') setShowFilters(false)
    }
    document.addEventListener('keydown', handleEscape)
    return () => document.removeEventListener('keydown', handleEscape)
  }, [showFilters])

  // Real-time: track new listings arriving
  useListingsRealtime(
    useCallback(() => {
      setNewListingsCount((c) => c + 1)
    }, [])
  )

  // Count active filters
  const activeFilterCount = useMemo(() => {
    let count = 0
    if (filters.location_country) count++
    if (filters.remote_type) count++
    if (filters.company) count++
    if (filters.duration) count++
    if (filters.skills.length > 0) count += filters.skills.length
    return count
  }, [filters])

  // Handle save/unsave with optimistic update
  const handleSave = useCallback(
    async (listingId: string) => {
      const success = await saveListing(listingId)
      if (success) {
        // Optimistic update in selected listing
        if (selectedListing?.id === listingId) {
          setSelectedListing((prev) => (prev ? { ...prev, is_saved: true } : prev))
        }
        refresh()
        toast('Saved! View in Tracker \u2192')
      }
    },
    [saveListing, selectedListing, refresh, toast]
  )

  const handleUnsave = useCallback(
    async (listingId: string) => {
      const success = await unsaveListing(listingId)
      if (success) {
        if (selectedListing?.id === listingId) {
          setSelectedListing((prev) => (prev ? { ...prev, is_saved: false } : prev))
        }
        refresh()
        toast('Job removed from saved')
      }
    },
    [unsaveListing, selectedListing, refresh, toast]
  )

  const handleNewListingsBanner = useCallback(() => {
    setNewListingsCount(0)
    refresh()
  }, [refresh])

  const handleSkillToggle = useCallback(
    (skill: string) => {
      const current = filters.skills
      if (current.includes(skill)) {
        updateFilters({ skills: current.filter((s) => s !== skill) })
      } else {
        updateFilters({ skills: [...current, skill] })
      }
    },
    [filters.skills, updateFilters]
  )

  // Bulk select handlers
  const toggleBulkSelect = useCallback(
    (listingId: string) => {
      setSelectedIds((prev) => {
        const next = new Set(prev)
        if (next.has(listingId)) {
          next.delete(listingId)
        } else {
          next.add(listingId)
        }
        return next
      })
    },
    []
  )

  const selectedJobs = useMemo(
    () => listings.filter((l) => selectedIds.has(l.id)),
    [listings, selectedIds]
  )

  const handleShare = useCallback(
    async (listing: ListingWithMatch) => {
      const url = listing.source_url || window.location.href
      const text = `${listing.title} at ${listing.company || 'Unknown'}`

      if (navigator.share) {
        try {
          await navigator.share({ title: text, url })
          return
        } catch {
          // Fall through to clipboard
        }
      }

      await navigator.clipboard.writeText(url)
      toast('Link copied to clipboard')
    },
    [toast]
  )

  const handleLoadSearch = useCallback(
    (searchFilters: typeof filters) => {
      updateFilters(searchFilters)
    },
    [updateFilters]
  )

  return (
    <div className="space-y-6">
      {/* Page Header */}
      <motion.div
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        className="flex items-start justify-between"
      >
        <div>
          <h1 className="text-2xl font-bold">Job Feed</h1>
          <p className="text-[var(--color-text-secondary)] text-sm mt-1">
            {loading
              ? 'Loading opportunities...'
              : totalCount > 0
                ? `${totalCount} internships and jobs from 100+ sources`
                : 'AI-matched internships and jobs from 100+ sources'}
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => setShowSaveSearch(true)}
            className="btn btn-secondary text-sm"
            title="Saved Searches"
          >
            <Bookmark size={16} />
            <span className="hidden sm:inline">Saved Searches</span>
          </button>
          <button
            onClick={() => {
              setBulkMode(!bulkMode)
              if (bulkMode) setSelectedIds(new Set())
            }}
            className={`btn text-sm ${bulkMode ? 'bg-[var(--color-bg-secondary)] border border-[var(--color-border)] text-[var(--color-text-primary)]' : 'btn-secondary'}`}
            title={bulkMode ? 'Exit bulk mode' : 'Select multiple jobs'}
          >
            <CheckSquare size={16} />
            <span className="hidden sm:inline">{bulkMode ? 'Cancel' : 'Bulk'}</span>
          </button>
          <button
            onClick={refresh}
            className="btn btn-ghost p-2"
            aria-label="Refresh listings"
            title="Refresh"
          >
            <RefreshCw size={18} className={loading ? 'animate-spin' : ''} />
          </button>
        </div>
      </motion.div>

      {/* Profile Completion Banner */}
      <ProfileCompletionBanner />

      {/* New Listings Banner */}
      <AnimatePresence>
        {newListingsCount > 0 && (
          <motion.button
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            onClick={handleNewListingsBanner}
            className="w-full btn bg-[var(--color-bg-secondary)] border border-[var(--color-border)] text-[var(--color-text-primary)] hover:bg-[var(--color-bg-elevated)] transition-colors"
          >
            <Bell size={16} />
            {newListingsCount} new {newListingsCount === 1 ? 'job' : 'jobs'} just arrived — click
            to refresh
          </motion.button>
        )}
      </AnimatePresence>

      {/* Search + Filter Bar */}
      <motion.div
        initial={{ opacity: 0, y: 20 }}
        animate={{ opacity: 1, y: 0 }}
        transition={{ delay: 0.05 }}
        className="flex flex-col sm:flex-row gap-3"
      >
        {/* Search Input */}
        <div className="relative flex-1">
          <Search
            size={18}
            className="absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)]"
          />
          <input
            type="text"
            placeholder="Search by title, company, or skill... (e.g. 'Python', 'UBS', 'ML intern')"
            value={localSearch}
            onChange={(e) => setLocalSearch(e.target.value)}
            className="input pl-10 pr-28"
          />
          {localSearch ? (
            <button
              onClick={() => { setLocalSearch(''); updateFilters({ search: '' }) }}
              className="absolute right-3 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-[var(--color-bg-elevated)]"
              aria-label="Clear search"
            >
              <X size={14} className="text-[var(--color-text-muted)]" />
            </button>
          ) : (
            <span className="absolute right-3 top-1/2 -translate-y-1/2 text-[10px] text-[var(--color-text-muted)] bg-[var(--color-bg-elevated)] border border-[var(--color-border)] rounded px-1.5 py-0.5 pointer-events-none select-none">
              Press Enter
            </span>
          )}
        </div>

        {/* Filter Toggle */}
        <button
          onClick={() => setShowFilters(!showFilters)}
          className={`btn ${activeFilterCount > 0 ? 'bg-[var(--color-bg-secondary)] border border-[var(--color-border)] text-[var(--color-text-primary)]' : 'btn-secondary'}`}
        >
          <Filter size={16} />
          Filters
          {activeFilterCount > 0 && (
            <span className="badge bg-[var(--color-text-primary)] text-white text-[10px] px-1.5 py-0 min-w-[18px] text-center">
              {activeFilterCount}
            </span>
          )}
        </button>

        {/* Sort Dropdown */}
        <div className="relative" ref={sortRef}>
          <button
            onClick={() => setShowSort(!showSort)}
            className="btn btn-secondary whitespace-nowrap"
          >
            <ArrowUpDown size={16} />
            {SORT_OPTIONS.find((o) => o.value === filters.sort_by)?.label}
            <ChevronDown size={14} />
          </button>
          <AnimatePresence>
            {showSort && (
              <motion.div
                initial={{ opacity: 0, y: 5 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, y: 5 }}
                className="absolute right-0 top-full mt-1 w-44 card-glow p-1 z-30"
              >
                {SORT_OPTIONS.map((option) => (
                  <button
                    key={option.value}
                    onClick={() => {
                      updateFilters({ sort_by: option.value })
                      setShowSort(false)
                    }}
                    className={`w-full text-left px-3 py-2 text-sm rounded-md transition-colors ${
                      filters.sort_by === option.value
                        ? 'bg-[var(--color-bg-secondary)] text-[var(--color-text-primary)]'
                        : 'text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-elevated)] hover:text-[var(--color-text-primary)]'
                    }`}
                  >
                    {option.label}
                  </button>
                ))}
              </motion.div>
            )}
          </AnimatePresence>
        </div>
      </motion.div>

      {/* Expanded Filter Panel */}
      <AnimatePresence>
        {showFilters && (
          <motion.div
            initial={{ opacity: 0, height: 0 }}
            animate={{ opacity: 1, height: 'auto' }}
            exit={{ opacity: 0, height: 0 }}
            className="overflow-hidden"
          >
            <div className="card-glow p-5 space-y-5">
              <div className="flex items-center justify-between">
                <h3 className="text-sm font-semibold">Filters</h3>
                {activeFilterCount > 0 && (
                  <button
                    onClick={resetFilters}
                    className="text-xs text-[var(--color-text-primary)] hover:underline"
                  >
                    Clear all
                  </button>
                )}
              </div>

              <div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
                {/* Country */}
                <div>
                  <label className="text-xs text-[var(--color-text-muted)] block mb-1.5">
                    Country
                  </label>
                  <select
                    value={filters.location_country}
                    onChange={(e) => updateFilters({ location_country: e.target.value })}
                    className="input"
                  >
                    <option value="">All Countries</option>
                    {countries.map((c) => (
                      <option key={c} value={c}>
                        {c}
                      </option>
                    ))}
                  </select>
                </div>

                {/* Company */}
                {availableCompanies.length > 0 && (
                  <div>
                    <label className="text-xs text-[var(--color-text-muted)] block mb-1.5">
                      Company
                    </label>
                    <select
                      value={filters.company}
                      onChange={(e) => updateFilters({ company: e.target.value })}
                      className="input"
                    >
                      <option value="">All Companies</option>
                      {availableCompanies.map((c) => (
                        <option key={c} value={c}>
                          {c}
                        </option>
                      ))}
                    </select>
                  </div>
                )}

                {/* Remote Type */}
                <div>
                  <label className="text-xs text-[var(--color-text-muted)] block mb-1.5">
                    Work Type
                  </label>
                  <select
                    value={filters.remote_type}
                    onChange={(e) => updateFilters({ remote_type: e.target.value })}
                    className="input"
                  >
                    {REMOTE_OPTIONS.map((opt) => (
                      <option key={opt.value} value={opt.value}>
                        {opt.label}
                      </option>
                    ))}
                  </select>
                </div>

                {/* Duration — only show if at least 1 listing has duration data */}
                {availableDurations.length > 0 && (
                  <div>
                    <label className="text-xs text-[var(--color-text-muted)] block mb-1.5">
                      Duration
                    </label>
                    <select
                      value={filters.duration}
                      onChange={(e) => updateFilters({ duration: e.target.value })}
                      className="input"
                    >
                      {DURATION_OPTIONS.map((opt) => (
                        <option key={opt.value} value={opt.value}>
                          {opt.label}
                        </option>
                      ))}
                    </select>
                  </div>
                )}
              </div>

              {/* Skills Chips */}
              {availableSkills.length > 0 && (
                <div>
                  <label className="text-xs text-[var(--color-text-muted)] block mb-2">
                    Skills
                  </label>
                  <div className="flex flex-wrap gap-1.5">
                    {availableSkills.map((skill) => {
                      const selected = filters.skills.includes(skill)
                      return (
                        <button
                          key={skill}
                          onClick={() => handleSkillToggle(skill)}
                          className={`badge cursor-pointer transition-colors px-2.5 py-1 focus-visible:outline-2 focus-visible:outline-[var(--color-text-primary)] focus-visible:outline-offset-2 ${
                            selected
                              ? 'bg-[var(--color-bg-secondary)] text-[var(--color-text-primary)] border border-[var(--color-text-primary)]/40'
                              : 'bg-[var(--color-bg-elevated)] text-[var(--color-text-secondary)] border border-[var(--color-border)] hover:border-[var(--color-border-hover)]'
                          }`}
                        >
                          {skill}
                          {selected && <X size={10} className="ml-1" />}
                        </button>
                      )
                    })}
                  </div>
                </div>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Active Filter Chips (always visible) */}
      <AnimatePresence>
        {activeFilterCount > 0 && !showFilters && (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="flex flex-wrap gap-2"
          >
            {filters.location_country && (
              <FilterChip
                label={filters.location_country}
                onRemove={() => updateFilters({ location_country: '' })}
              />
            )}
            {filters.company && (
              <FilterChip
                label={filters.company}
                onRemove={() => updateFilters({ company: '' })}
              />
            )}
            {filters.remote_type && (
              <FilterChip
                label={
                  REMOTE_OPTIONS.find((o) => o.value === filters.remote_type)?.label ||
                  filters.remote_type
                }
                onRemove={() => updateFilters({ remote_type: '' })}
              />
            )}
            {filters.duration && (
              <FilterChip
                label={filters.duration}
                onRemove={() => updateFilters({ duration: '' })}
              />
            )}
            {filters.skills.map((skill) => (
              <FilterChip
                key={skill}
                label={skill}
                onRemove={() => handleSkillToggle(skill)}
              />
            ))}
            <button
              onClick={resetFilters}
              className="text-xs text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors px-2 py-1"
            >
              Clear all
            </button>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Browse by Company */}
      {!loading && listings.length > 0 && (
        <CompanyBrowse
          listings={listings}
          onSelectCompany={(company) => updateFilters({ search: company })}
        />
      )}

      {/* Loading State */}
      {loading && (
        <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
          {Array.from({ length: 6 }).map((_, i) => (
            <JobCardSkeleton key={i} index={i} />
          ))}
        </div>
      )}

      {/* Bulk Action Bar */}
      <AnimatePresence>
        {bulkMode && selectedIds.size > 0 && (
          <motion.div
            initial={{ opacity: 0, y: 10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: 10 }}
            className="sticky top-0 z-20 card-glow p-3 flex items-center gap-3 bg-[var(--color-bg-secondary)] border-[var(--color-border)]"
          >
            <span className="text-sm font-medium">
              {selectedIds.size} job{selectedIds.size !== 1 ? 's' : ''} selected
            </span>
            <div className="flex-1" />
            <button
              onClick={() => setSelectedIds(new Set())}
              className="btn btn-ghost text-sm"
            >
              Clear
            </button>
            <button
              onClick={() => setShowBulkApply(true)}
              className="btn btn-primary text-sm"
            >
              <Sparkles size={14} />
              Generate All
            </button>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Listings Grid */}
      {!loading && listings.length > 0 && (
        <>
          <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4">
            {listings.map((listing, i) => (
              <div key={listing.id} className="relative">
                {/* Bulk select checkbox */}
                {bulkMode && (
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      toggleBulkSelect(listing.id)
                    }}
                    className="absolute top-3 left-3 z-10 p-0.5 rounded"
                    aria-label={selectedIds.has(listing.id) ? 'Deselect' : 'Select'}
                  >
                    {selectedIds.has(listing.id) ? (
                      <CheckSquare size={18} className="text-[var(--color-text-primary)]" />
                    ) : (
                      <Square size={18} className="text-[var(--color-text-muted)]" />
                    )}
                  </button>
                )}
                {/* Compare checkbox */}
                {!bulkMode && (
                  <CompareCheckbox
                    checked={compareIds.has(listing.id)}
                    disabled={compareIds.size >= 3}
                    onToggle={() => toggleCompare(listing.id)}
                  />
                )}
                <JobCard
                  listing={listing}
                  index={i}
                  onSelect={bulkMode ? () => toggleBulkSelect(listing.id) : setSelectedListing}
                  onSave={handleSave}
                  onUnsave={handleUnsave}
                />
                {/* Share button overlay */}
                <button
                  onClick={(e) => {
                    e.stopPropagation()
                    handleShare(listing)
                  }}
                  className="absolute bottom-[17px] right-[52px] p-1.5 rounded-md hover:bg-[var(--color-bg-elevated)] transition-colors opacity-0 group-hover:opacity-100 z-10"
                  aria-label="Share job"
                  title="Share"
                  style={{ opacity: 1 }}
                >
                  <Share2 size={15} className="text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]" />
                </button>
              </div>
            ))}
          </div>

          {/* Load More */}
          {hasMore && (
            <div className="flex justify-center pt-4">
              <button
                onClick={loadMore}
                disabled={loadingMore}
                className="btn btn-secondary"
              >
                {loadingMore ? (
                  <>
                    <Loader2 size={16} className="animate-spin" />
                    Loading...
                  </>
                ) : (
                  'Load More Jobs'
                )}
              </button>
            </div>
          )}
        </>
      )}

      {/* Empty State */}
      {!loading && listings.length === 0 && (
        <motion.div
          className="card-glow p-12 text-center"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ delay: 0.2 }}
        >
          <div className="w-16 h-16 rounded-full bg-[var(--color-bg-secondary)] flex items-center justify-center mx-auto mb-4">
            <Search size={28} className="text-[var(--color-text-secondary)]" />
          </div>

          {activeFilterCount > 0 || filters.search ? (
            <>
              {/* Empty search illustration */}
              <svg width="120" height="90" viewBox="0 0 120 90" fill="none" className="mx-auto mb-4 opacity-60" aria-hidden="true">
                <rect x="20" y="15" width="80" height="55" rx="8" stroke="var(--color-border-hover)" strokeWidth="2" strokeDasharray="6 3" fill="none" />
                <circle cx="60" cy="38" r="14" stroke="var(--color-text-muted)" strokeWidth="2" fill="none" />
                <line x1="70" y1="48" x2="80" y2="58" stroke="var(--color-text-muted)" strokeWidth="2" strokeLinecap="round" />
                <line x1="50" y1="35" x2="70" y2="35" stroke="var(--color-text-muted)" strokeWidth="1.5" strokeLinecap="round" opacity="0.5" />
                <line x1="55" y1="41" x2="65" y2="41" stroke="var(--color-text-muted)" strokeWidth="1.5" strokeLinecap="round" opacity="0.5" />
              </svg>
              <h3 className="text-lg font-semibold mb-2">No results for those filters</h3>
              <p className="text-[var(--color-text-muted)] text-sm max-w-md mx-auto">
                Try widening your search or removing a filter — there might be a great match hiding just outside your criteria.
              </p>
              <div className="flex gap-3 justify-center mt-6">
                <button onClick={resetFilters} className="btn btn-primary">
                  <X size={16} />
                  Clear Filters
                </button>
              </div>
            </>
          ) : (
            <>
              <h3 className="text-lg font-semibold mb-2">We're scanning the market for you</h3>
              <p className="text-[var(--color-text-muted)] text-sm max-w-md mx-auto">
                New internships are being pulled from Indeed, Glassdoor, LinkedIn, and 100+ other sources every few hours. Complete your profile and we'll notify you the moment something matches.
              </p>
              <div className="flex gap-3 justify-center mt-6">
                <button
                  onClick={() => navigate('/profile')}
                  className="btn btn-primary"
                >
                  <Sparkles size={16} />
                  Set Up Your Profile
                </button>
                <button
                  onClick={() => navigate('/import')}
                  className="btn btn-secondary"
                >
                  <Link2 size={16} />
                  Paste a Job URL
                </button>
              </div>
            </>
          )}
        </motion.div>
      )}

      {/* Job Detail Slide-over */}
      <JobDetail
        listing={selectedListing}
        onClose={() => setSelectedListing(null)}
        onSave={handleSave}
        onUnsave={handleUnsave}
      />

      {/* Save Search Modal */}
      <SaveSearchModal
        isOpen={showSaveSearch}
        filters={filters}
        onClose={() => setShowSaveSearch(false)}
        onLoadSearch={handleLoadSearch}
      />

      {/* Bulk Apply Modal */}
      <AnimatePresence>
        {showBulkApply && selectedJobs.length > 0 && (
          <BulkApply
            selectedJobs={selectedJobs}
            onClose={() => setShowBulkApply(false)}
            onComplete={() => {
              setBulkMode(false)
              setSelectedIds(new Set())
              navigate('/tracker')
            }}
          />
        )}
      </AnimatePresence>

      {/* Compare Floating Button */}
      <CompareFloatingButton
        count={compareIds.size}
        onClick={() => setShowComparison(true)}
      />

      {/* Job Comparison Modal */}
      <AnimatePresence>
        {showComparison && compareJobs.length >= 2 && (
          <JobComparison
            jobs={compareJobs}
            userSkills={profile?.skills ?? []}
            onClose={() => setShowComparison(false)}
            onRemove={(id) => {
              setCompareIds((prev) => {
                const next = new Set(prev)
                next.delete(id)
                return next
              })
              if (compareIds.size <= 2) setShowComparison(false)
            }}
          />
        )}
      </AnimatePresence>
    </div>
  )
}

// ─── Browse by Company ──────────────────────────────────────────────

function CompanyBrowse({
  listings,
  onSelectCompany,
}: {
  listings: ListingWithMatch[]
  onSelectCompany: (company: string) => void
}) {
  // Deduplicate companies + count occurrences
  const companies = useMemo(() => {
    const map = new Map<string, { name: string; logo: string | null; count: number }>()
    for (const l of listings) {
      if (!l.company) continue
      const existing = map.get(l.company)
      if (existing) {
        existing.count++
        if (!existing.logo && l.company_logo_url) existing.logo = l.company_logo_url
      } else {
        map.set(l.company, { name: l.company, logo: l.company_logo_url, count: 1 })
      }
    }
    // Sort by count descending, take top 15
    return Array.from(map.values())
      .sort((a, b) => b.count - a.count)
      .slice(0, 15)
  }, [listings])

  if (companies.length < 2) return null

  return (
    <motion.div
      initial={{ opacity: 0, y: 10 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ delay: 0.1 }}
    >
      <h3 className="text-xs font-semibold text-[var(--color-text-muted)] uppercase tracking-wider mb-2">
        Browse by Company
      </h3>
      <div className="flex gap-2 overflow-x-auto pb-2 scrollbar-hide">
        {companies.map((c) => (
          <button
            key={c.name}
            onClick={() => onSelectCompany(c.name)}
            className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-[var(--color-bg-card)] border border-[var(--color-border)] hover:border-[var(--color-border-hover)] hover:bg-[var(--color-bg-elevated)] transition-all shrink-0 group"
          >
            <div className="w-5 h-5 rounded-md bg-[var(--color-bg-elevated)] border border-[var(--color-border)] flex items-center justify-center overflow-hidden shrink-0">
              {c.logo ? (
                <img src={c.logo} alt={c.name} className="w-full h-full object-cover rounded-md" loading="lazy" />
              ) : (
                <Building2 size={10} className="text-[var(--color-text-muted)]" />
              )}
            </div>
            <span className="text-xs font-medium text-[var(--color-text-secondary)] group-hover:text-[var(--color-text-primary)] transition-colors whitespace-nowrap">
              {c.name}
            </span>
            <span className="text-[10px] text-[var(--color-text-muted)] bg-[var(--color-bg-elevated)] px-1.5 py-0.5 rounded-full">
              {c.count}
            </span>
          </button>
        ))}
      </div>
    </motion.div>
  )
}

// ─── Filter Chip ────────────────────────────────────────────────────

function FilterChip({ label, onRemove }: { label: string; onRemove: () => void }) {
  return (
    <motion.button
      initial={{ opacity: 0, scale: 0.9 }}
      animate={{ opacity: 1, scale: 1 }}
      exit={{ opacity: 0, scale: 0.9 }}
      onClick={onRemove}
      className="badge bg-[var(--color-bg-secondary)] text-[var(--color-text-primary)] border border-[var(--color-border)] px-2.5 py-1 cursor-pointer hover:bg-[var(--color-bg-elevated)] transition-colors gap-1"
    >
      {label}
      <X size={12} />
    </motion.button>
  )
}
