'use client'

import { useCallback, useEffect, useRef, useState } from 'react'
import {
  AlertTriangle,
  Bell,
  BellOff,
  Calendar,
  CalendarDays,
  CircleUser,
  Clock,
  Cookie,
  ExternalLink,
  Loader2,
  MapPin,
  Mail,
  Phone,
  RefreshCw,
  ShieldCheck,
  X,
  Zap,
} from 'lucide-react'
import { tone } from './Badge'
import './AccountView.css'

interface Profile {
  candidateId?: string | null
  candidateSFId?: string | null
  firstName?: string | null
  middleName?: string | null
  lastName?: string | null
  preferredFirstName?: string | null
  preferredLastName?: string | null
  emailId?: string | null
  phoneNumber?: string | null
  phoneCountryCode?: string | null
  locale?: string | null
  timezone?: string | null
  language?: string | null
  dateOfBirth?: string | null
  address?: {
    addressLine1?: string | null
    addressLine2?: string | null
    city?: string | null
    state?: string | null
    country?: string | null
    zipcode?: string | null
    countryCode?: string | null
  } | null
}

interface AppointmentSlot {
  kind: string
  timeSlotId?: string
  applicationId?: string
  status?: string | null
  startDate?: string | null
  startTime?: string | null
  endDate?: string | null
  endTime?: string | null
  locationType?: string | null
  displayReadyLocation?: string | null
}

interface Application {
  applicationId: string
  jobId?: string
  jobTitle?: string
  location?: string
  state?: string
  workflowName?: string
  step?: string | null
  stepLabel?: string | null
  subStep?: string | null
  active?: boolean
  submitted?: boolean
  lastModificationDate?: string | null
  firstDayOnSite?: string | null
  scheduleText?: string | null
  appStatus?: string
  continueApplicationLink?: string
  appointments: AppointmentSlot[]
}

interface Account {
  _id: string
  source: string
  label: string
  applicantName: string
  email: string
  candidateId: string | null
  profile: Profile | null
  applications: Application[]
  appointments: AppointmentSlot[]
  lastStatus: string
  connected: boolean
  disconnectedAt: string | null
  lastScrapeAt: string | null
  lastScrapeError: string | null
  lastCheckAt: string | null
  formUrl: string
  createdAt: string
}

interface SessionRow {
  _id: string
  applicantName: string
  email: string
  source: string
  lastStatus: string
  candidateId?: string
  connected?: boolean
}

function timeAgo(iso: string | null | undefined): string {
  if (!iso) return 'never scraped'
  const sec = Math.max(0, Math.round((Date.now() - new Date(iso).getTime()) / 1000))
  if (sec < 60) return `${sec}s ago`
  if (sec < 3600) return `${Math.floor(sec / 60)}m ago`
  return `${Math.floor(sec / 3600)}h ago`
}

function fmtDate(iso?: string | null): string {
  if (!iso) return '—'
  return new Date(iso).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })
}

function fmtTime(iso?: string | null): string {
  if (!iso) return '—'
  const t = new Date(iso)
  if (isNaN(t.getTime())) return iso
  return t.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })
}

function displayName(p: Profile | null | undefined, fallback: string): string {
  if (!p) return fallback
  const pref = [p.preferredFirstName, p.preferredLastName].filter(Boolean).join(' ')
  if (pref) return pref
  return [p.firstName, p.middleName, p.lastName].filter(Boolean).join(' ') || fallback
}

function fullAddress(p: Profile | null | undefined): string {
  const a = p?.address
  if (!a) return ''
  return [a.addressLine1, a.addressLine2, a.city, a.state, a.country, a.zipcode]
    .filter(Boolean)
    .join(', ')
}

function absoluteJobsUrl(link?: string): string {
  if (!link) return ''
  if (/^https?:\/\//i.test(link)) return link
  return `https://www.jobsatamazon.co.uk${link.startsWith('/') ? '' : '/'}${link}`
}

function parseAnyCookieFormat(raw: string): Record<string, string> {
  const cookies: Record<string, string> = {}
  const cleaned = raw.replace(/\^/g, '')
  const lines = cleaned.split(/[;\n]+/)
  for (const line of lines) {
    const t = line.trim()
    if (!t || t.startsWith('#') || t.startsWith('//')) continue
    const eqIdx = t.indexOf('=')
    if (eqIdx > 0) {
      const k = t.slice(0, eqIdx).trim().replace(/[^\x20-\x7E]/g, '')
      const v = t.slice(eqIdx + 1).trim().replace(/[^\x20-\x7E]/g, '')
      if (k && v) cookies[k] = v
    }
  }
  return cookies
}

function parseJsonCookies(raw: string): Record<string, string> {
  try {
    const arr = JSON.parse(raw.trim())
    if (!Array.isArray(arr)) return {}
    const out: Record<string, string> = {}
    for (const item of arr) {
      if (item?.name && item?.value !== undefined) out[String(item.name)] = String(item.value)
    }
    return out
  } catch { return {} }
}

interface ConnectFormProps {
  onConnect: () => void
  connecting: boolean
  connectError: string
  setConnectError: (e: string) => void
  pasteText: string
  setPasteText: (t: string) => void
}

function ConnectForm({ onConnect, connecting, connectError, setConnectError, pasteText, setPasteText }: ConnectFormProps) {
  const [tab, setTab] = useState<'curl' | 'json'>('curl')
  const [jsonText, setJsonText] = useState('')

  const curlCount = Object.keys(parseAnyCookieFormat(pasteText)).length
  const jsonCount = Object.keys(parseJsonCookies(jsonText)).length

  return (
    <div className="account-connect">
      <div className="account-connect-icon"><Cookie size={34} /></div>
      <b>Connect your Amazon Jobs account</b>

      {/* Tabs */}
      <div className="connect-form-tabs">
        <button
          className={`connect-form-tab ${tab === 'curl' ? 'active' : ''}`}
          onClick={() => setTab('curl')}
        >
          cURL / Cookie Header
        </button>
        <button
          className={`connect-form-tab ${tab === 'json' ? 'active' : ''}`}
          onClick={() => setTab('json')}
        >
          JSON Cookies
        </button>
      </div>

      {tab === 'curl' ? (
        <>
          <p style={{margin:0, fontSize:'12px', color:'#64748b'}}>
            Log in at jobsatamazon.co.uk → F12 → Network tab → right-click any request → Copy as cURL → paste below.
          </p>
          <textarea
            rows={4}
            placeholder="Paste cURL command or Cookie: header here…"
            value={pasteText}
            onChange={(e) => { setPasteText(e.target.value); setConnectError('') }}
          />
          {pasteText.trim() && (
            <p className="connect-cookie-count">
              {curlCount > 0 ? `✓ ${curlCount} cookies detected` : '⚠ No cookies found — check format'}
            </p>
          )}
        </>
      ) : (
        <>
          <p style={{margin:0, fontSize:'12px', color:'#64748b'}}>
            Use a browser extension (e.g. "Cookie Editor") → Export All → paste the JSON array below.
          </p>
          <textarea
            rows={4}
            placeholder={`[{"name":"HVH_ACCESS_TOKEN","value":"eyJ..."},{"name":"JSESSIONID","value":"xxx"},...]`}
            value={jsonText}
            onChange={(e) => { setJsonText(e.target.value); setConnectError('') }}
          />
          {jsonText.trim() && (
            <p className="connect-cookie-count">
              {jsonCount > 0 ? `✓ ${jsonCount} cookies detected` : '⚠ No cookies found — check JSON format'}
            </p>
          )}
        </>
      )}

      {connectError && (
        <div className="connect-error"><AlertTriangle size={13} /> {connectError}</div>
      )}

      <button
        className="refresh account-connect-btn"
        onClick={() => {
          if (tab === 'json' && jsonText.trim()) {
            // Merge JSON cookies into pasteText format for handleConnect
            const parsed = parseJsonCookies(jsonText)
            const cookieStr = Object.entries(parsed).map(([k,v]) => `${k}=${v}`).join('; ')
            setPasteText(cookieStr)
          }
          setTimeout(onConnect, 0)
        }}
        disabled={connecting || (tab === 'curl' ? curlCount === 0 : jsonCount === 0)}
      >
        {connecting ? <Loader2 className="spin" size={14} /> : <ShieldCheck size={14} />}
        {connecting ? 'Connecting…' : 'Connect account'}
      </button>
    </div>
  )
}

function simplifyError(err: string | null | undefined): string {
  if (!err) return ''
  if (/session.expired|401|403|re.?login|auth/i.test(err)) return 'Session expired — reconnect'
  if (/invalid cookie|protocol error/i.test(err)) return 'Cookies invalid — paste fresh cookies'
  if (/network|ECONNREFUSED/i.test(err)) return 'Network error'
  if (/playwright|chromium|executable|browser/i.test(err)) return 'Could not connect — cookies may be expired'
  if (/rate.?limit|429|throttl/i.test(err)) return 'Amazon rate limited'
  if (/profile not extractable/i.test(err)) return 'Could not read profile — cookies may be expired'
  if (/unauthenticated|empty response/i.test(err)) return 'Cookies expired — please reconnect'
  return err.split('|')[0].trim().slice(0, 80)
}

export function AccountView() {
  const [sessions, setSessions] = useState<SessionRow[]>([])
  const [selectedId, setSelectedId] = useState<string | null>(null)
  const [account, setAccount] = useState<Account | null>(null)
  const [loading, setLoading] = useState(true)
  const [scraping, setScraping] = useState(false)
  const [error, setError] = useState('')
  const [pasteText, setPasteText] = useState('')
  const [connecting, setConnecting] = useState(false)
  const [showAdd, setShowAdd] = useState(false)
  const [connectError, setConnectError] = useState('')
  const scraperEnabled = useRef<boolean>(true)

  // ── Shift picking state ──
  const [pickingShiftKey, setPickingShiftKey] = useState<string | null>(null)
  const [pickResult, setPickResult] = useState<{ key: string; ok: boolean; message: string } | null>(null)
  const [pickElapsed, setPickElapsed] = useState(0)
  const pickTimerRef = useRef<ReturnType<typeof setInterval> | null>(null)

  // Start/stop elapsed timer when picking
  useEffect(() => {
    if (pickingShiftKey) {
      setPickElapsed(0)
      pickTimerRef.current = setInterval(() => setPickElapsed(s => s + 1), 1000)
    } else {
      if (pickTimerRef.current) clearInterval(pickTimerRef.current)
    }
    return () => { if (pickTimerRef.current) clearInterval(pickTimerRef.current) }
  }, [pickingShiftKey])

  // ── Shift filters ──
  const [filterDays, setFilterDays] = useState<string[]>([])
  const [filterHours, setFilterHours] = useState<string>('all')
  const [showFilterDropdown, setShowFilterDropdown] = useState(false)

  const DAYS = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
  const HOURS_BANDS = [
    { label: '40h+ (Full-time)', value: '40', min: 40, max: 999 },
    { label: '30–39h', value: '30-39', min: 30, max: 39 },
    { label: '20–29h', value: '20-29', min: 20, max: 29 },
    { label: 'Under 20h', value: 'u20', min: 0, max: 19 },
  ]

  function toggleDay(day: string) {
    setFilterDays(prev => prev.includes(day) ? prev.filter(d => d !== day) : [...prev, day])
  }

  function matchesFilters(scheduleText: string | null | undefined, hoursPerWeek: number | null | undefined): boolean {
    const text = (scheduleText || '').toUpperCase()
    if (filterDays.length > 0) {
      const matched = filterDays.some(d => text.includes(d.toUpperCase()))
      if (!matched) return false
    }
    if (filterHours !== 'all') {
      const band = HOURS_BANDS.find(b => b.value === filterHours)
      if (band && hoursPerWeek != null) {
        if (hoursPerWeek < band.min || hoursPerWeek > band.max) return false
      }
    }
    return true
  }

  const activeFilterCount = filterDays.length + (filterHours !== 'all' ? 1 : 0)

  // ── Radar alert system ──
  interface RadarAlert {
    id: string
    jobTitle: string
    location: string
    scheduleText: string
    hoursPerWeek: number | null
    payText: string
    postingStatus: string
    applyUrl: string
    jobId: string
    scheduleId?: string
    detectedAt: string
  }

  const [radarAlerts, setRadarAlerts] = useState<RadarAlert[]>([])
  const [radarMonitoring, setRadarMonitoring] = useState(true)
  const [dismissedAlerts, setDismissedAlerts] = useState<Set<string>>(new Set())
  const seenShiftKeys = useRef<Set<string>>(new Set())
  const accountRef = useRef<typeof account>(null)
  const filterDaysRef = useRef(filterDays)
  const filterHoursRef = useRef(filterHours)

  // Keep refs in sync
  useEffect(() => { accountRef.current = account }, [account])
  useEffect(() => { filterDaysRef.current = filterDays }, [filterDays])
  useEffect(() => { filterHoursRef.current = filterHours }, [filterHours])

  function playAlertSound() {
    try {
      const ctx = new (window.AudioContext || (window as any).webkitAudioContext)()
      const beep = (freq: number, start: number, dur: number) => {
        const o = ctx.createOscillator()
        const g = ctx.createGain()
        o.connect(g); g.connect(ctx.destination)
        o.frequency.value = freq
        o.type = 'sine'
        g.gain.setValueAtTime(0, ctx.currentTime + start)
        g.gain.linearRampToValueAtTime(0.6, ctx.currentTime + start + 0.01)
        g.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + start + dur)
        o.start(ctx.currentTime + start)
        o.stop(ctx.currentTime + start + dur)
      }
      beep(880, 0, 0.15)
      beep(1100, 0.18, 0.15)
      beep(1320, 0.36, 0.25)
      beep(880, 0.65, 0.15)
      beep(1100, 0.83, 0.15)
      beep(1320, 1.01, 0.35)
    } catch { /* audio blocked */ }
  }

  const pollRadarForAlerts = useCallback(async () => {
    const currentAccount = accountRef.current
    if (!currentAccount || !currentAccount.applications?.length) return

    // Get jobIds from active applications
    const watchJobIds = new Set(
      currentAccount.applications
        .filter(app => {
          const s = (app.appStatus || app.state || '').toLowerCase()
          return !s.includes('withdrawn') && !s.includes('closed') && !s.includes('rejected')
        })
        .map(app => app.jobId)
        .filter(Boolean) as string[]
    )
    if (watchJobIds.size === 0) return

    try {
      const res = await fetch('/api/shift-radar', { cache: 'no-store' })
      if (!res.ok) return
      const data = await res.json()
      const shifts: any[] = data.shifts || []

      const newAlerts: RadarAlert[] = []

      for (const shift of shifts) {
        // Only show shifts for our watched jobs
        if (!watchJobIds.has(shift.jobId)) continue

        const key = shift.scheduleKey
        if (seenShiftKeys.current.has(key)) continue

        // Apply day filter
        const days = filterDaysRef.current
        if (days.length > 0) {
          const text = (shift.scheduleText || '').toUpperCase()
          const matched = days.some((d: string) => text.includes(d.toUpperCase()))
          if (!matched) continue
        }

        // Apply hours filter
        const hf = filterHoursRef.current
        if (hf !== 'all') {
          const bands: Record<string, [number,number]> = {
            '40': [40, 999], '30-39': [30, 39], '20-29': [20, 29], 'u20': [0, 19]
          }
          const [min, max] = bands[hf] || [0, 999]
          const hw = shift.hoursPerWeek ?? 0
          if (hw < min || hw > max) continue
        }

        seenShiftKeys.current.add(key)
        newAlerts.push({
          id: key,
          jobTitle: shift.title,
          location: shift.location,
          scheduleText: shift.scheduleText,
          hoursPerWeek: shift.hoursPerWeek,
          payText: shift.payText,
          postingStatus: shift.postingStatus,
          applyUrl: shift.applyUrl,
          jobId: shift.jobId,
          scheduleId: shift.scheduleId || shift.scheduleKey,
          detectedAt: new Date().toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' }),
        })
      }

      if (newAlerts.length > 0) {
        setRadarAlerts(prev => [...newAlerts, ...prev].slice(0, 10))
        playAlertSound()
        // Repeat beep 3 times
        setTimeout(playAlertSound, 1200)
        setTimeout(playAlertSound, 2400)
      }
    } catch { /* ignore */ }
  }, [])

  useEffect(() => {
    if (!radarMonitoring) return
    const interval = setInterval(pollRadarForAlerts, 10000)
    return () => clearInterval(interval)
  }, [radarMonitoring, pollRadarForAlerts])

  const loadSessions = useCallback(async () => {
    try {
      const res = await fetch('/api/sessions?include=disconnected', { cache: 'no-store' })
      if (res.ok) {
        const data = await res.json()
        const rows: SessionRow[] = (data.sessions || []).map((s: any) => ({
          _id: s._id,
          applicantName: s.applicantName,
          email: s.email,
          source: s.source || 'cookies',
          lastStatus: s.lastStatus,
          candidateId: s.candidateId,
          connected: s.connected !== false,
        }))
        setSessions(rows)
        setSelectedId((cur) => {
          if (cur && rows.some((r) => r._id === cur)) return cur
          const next = rows.find((r) => r.connected !== false) || rows[0]
          return next?._id || null
        })
      }
    } catch {
      setError('Failed to load accounts')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => { loadSessions() }, [loadSessions])

  const loadAccount = useCallback(async (id: string) => {
    setScraping(false)
    setError('')
    try {
      const res = await fetch(`/api/sessions/${id}/account`, { cache: 'no-store' })
      if (!res.ok) throw new Error('Failed to load account')
      const data = await res.json()
      setAccount(data)
    } catch (err: any) {
      setError(err.message || 'Could not load account')
    }
  }, [])

  useEffect(() => {
    if (selectedId) loadAccount(selectedId)
  }, [selectedId, loadAccount])

  const handleScrape = useCallback(async (id: string) => {
    setScraping(true)
    setError('')
    try {
      const res = await fetch(`/api/sessions/${id}/scrape`, { method: 'POST' })
      const data = await res.json()
      if (!data.ok) {
        const err = data.error || 'Scrape failed'
        setError(err)
        return
      }
      scraperEnabled.current = data.scraperEnabled !== false
      await loadAccount(id)
      await loadSessions()
    } catch (err: any) {
      setError(err.message || 'Scrape failed')
    } finally {
      setScraping(false)
    }
  }, [loadAccount, loadSessions])

  const handleConnect = useCallback(async () => {
    setConnectError('')
    const cookies = parseAnyCookieFormat(pasteText)
    if (Object.keys(cookies).length === 0) {
      setConnectError('No cookies found. Paste the Cookie header or cURL from jobsatamazon.co.uk.')
      return
    }
    setConnecting(true)
    try {
      const res = await fetch('/api/connect', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ cookies }),
      })
      const data = await res.json()
      if (!res.ok) {
        setConnectError(data.error || 'Failed to connect')
        return
      }
      setPasteText('')
      await loadSessions()
      if (data.sessionId) {
        setSelectedId(data.sessionId)
        // Always scrape — even if GraphQL profile failed, Playwright will get it
        setScraping(true)
        try {
          const scrapeRes = await fetch(`/api/sessions/${data.sessionId}/scrape`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({}),
          })
          const scrapeData = await scrapeRes.json()
          scraperEnabled.current = scrapeData.scraperEnabled !== false
          if (scrapeData.authRequired) {
            setConnectError('Cookies are expired — please log in again on Amazon Jobs and paste fresh cookies')
          }
        } catch { /* scrape failure is non-fatal */ }
        finally { setScraping(false) }
        await loadAccount(data.sessionId)
        await loadSessions()
        // Continue polling every 5s for 30s to pick up background scrape name update
        let t = 0
        const poll = setInterval(async () => {
          t++
          await Promise.all([loadAccount(data.sessionId), loadSessions()])
          if (t >= 6) clearInterval(poll)
        }, 5000)
      }
    } catch {
      setConnectError('Network error')
    } finally {
      setConnecting(false)
    }
  }, [pasteText, loadSessions, handleScrape])

  const handleConnection = useCallback(async (id: string, connected: boolean) => {
    setError('')
    try {
      const res = await fetch(`/api/sessions/${id}/connection`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ connected }),
      })
      const data = await res.json()
      if (!res.ok || !data.ok) throw new Error(data.error || 'Failed to update connection')
      await Promise.all([loadSessions(), selectedId === id ? loadAccount(id) : Promise.resolve()])
    } catch (err: any) {
      setError(err.message || 'Failed to update connection')
    }
  }, [loadSessions, loadAccount, selectedId])

  const handleDelete = useCallback(async (id: string, name: string) => {
    if (!window.confirm(`Delete "${name}" and all its stored data? This cannot be undone.`)) return
    setError('')
    try {
      const res = await fetch(`/api/sessions/${id}`, { method: 'DELETE' })
      if (!res.ok) throw new Error('Failed to delete account')
      await loadSessions()
      setAccount(null)
    } catch (err: any) {
      setError(err.message || 'Failed to delete account')
    }
  }, [loadSessions])

  const handlePickShift = useCallback(async (
    sessionId: string,
    key: string,
    jobId: string,
    applicationId?: string,
    scheduleId?: string
  ) => {
    setPickingShiftKey(key)
    setPickResult(null)

    const controller = new AbortController()
    const clientTimeout = setTimeout(() => controller.abort(), 85_000)

    try {
      // Resolve applicationId from account's applications if not provided
      let resolvedAppId = applicationId
      if (!resolvedAppId && accountRef.current?.applications?.length) {
        const app = accountRef.current.applications.find((a) => a.jobId === jobId)
        if (app?.applicationId) resolvedAppId = app.applicationId
      }

      const res = await fetch(`/api/sessions/${sessionId}/pick-shift`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ jobId, applicationId: resolvedAppId, scheduleId }),
        signal: controller.signal,
      })
      const data = await res.json()
      setPickResult({
        key,
        ok: data.ok,
        message: data.status === 'unavailable'
          ? '⚠ Auto-pick is not available on this server. Please pick manually — click the  icon next to the button.'
          : data.message || (data.ok ? 'Shift picked!' : data.error || 'Pick failed.'),
      })
      setTimeout(() => setPickResult(p => p?.key === key ? null : p), 20000)
    } catch (err: any) {
      setPickResult({
        key,
        ok: false,
        message: err?.name === 'AbortError'
          ? 'Timed out — check Amazon Jobs to see if the shift was picked.'
          : 'Network error.',
      })
    } finally {
      clearTimeout(clientTimeout)
      setPickingShiftKey(null)
    }
  }, [])

  const selected = sessions.find((s) => s._id === selectedId)
  const connectedSessions = sessions.filter((s) => s.connected !== false)
  const disconnectedSessions = sessions.filter((s) => s.connected === false)
  const showPaste = connectedSessions.length === 0 && !loading
  const showSessionList = connectedSessions.length > 1 || disconnectedSessions.length > 0

  const pasteForm = (
    <div className="account-connect">
      <div className="account-connect-icon"><Cookie size={34} /></div>
      <b>Add another Amazon Jobs account</b>
      <p>Log in at jobsatamazon.co.uk with the new account → open DevTools (F12) → Network tab → copy any request as cURL → paste below.</p>
      <textarea
        rows={4}
        placeholder="Paste cURL command here…"
        value={pasteText}
        onChange={(e) => { setPasteText(e.target.value); setConnectError('') }}
      />
      {connectError && <div className="connect-error"><AlertTriangle size={13} /> {connectError}</div>}
      <button className="refresh account-connect-btn" onClick={handleConnect} disabled={connecting || !pasteText.trim()}>
        {connecting ? <Loader2 className="spin" size={14} /> : <ShieldCheck size={14} />}
        {connecting ? 'Connecting…' : 'Connect this account'}
      </button>
    </div>
  )

  return (
    <section className="panel account-panel">
      <div className="panel-heading">
        <div>
          <h2>Connected Amazon account</h2>
          <p>Your logged-in profile, applications and appointment slots pulled straight from Amazon Jobs.</p>
        </div>
        <div className="panel-tools">
          {selected && (
            <button className="refresh small" onClick={() => handleScrape(selected._id)} disabled={scraping || selected.connected === false}>
              {scraping ? <Loader2 className="spin" size={14} /> : <RefreshCw size={14} />}
              {scraping ? 'Fetching…' : 'Fetch live data'}
            </button>
          )}
          {!showPaste && (
            <button className="refresh small" onClick={() => setShowAdd((v) => !v)}>
              {showAdd ? 'Close' : 'Add account'}
            </button>
          )}
        </div>
      </div>

      {error && (
        <div className="account-error">
          <AlertTriangle size={14} /> {error}
        </div>
      )}

      {showPaste ? (
        <ConnectForm onConnect={handleConnect} connecting={connecting} connectError={connectError} setConnectError={setConnectError} pasteText={pasteText} setPasteText={setPasteText} />
      ) : (
        <>
        <div className="account-layout">
          {showSessionList && (
            <div className="account-session-list">
              {sessions.map((s) => (
                <button
                  key={s._id}
                  className={`account-session-row ${s._id === selectedId ? 'active' : ''} ${s.connected === false ? 'account-session-off' : ''}`}
                  onClick={() => setSelectedId(s._id)}
                >
                  <span className={`account-session-dot tone-dot ${
                    s.connected === false ? 'tone-dot-slate' :
                    s.lastStatus === 'slot_detected' ? 'tone-dot-green' :
                    s.lastStatus === 'error' || s.lastStatus === 'session_expired' ? 'tone-dot-red' :
                    'tone-dot-blue'
                  }`} />
                  <div>
                    <b>{s.applicantName}</b>
                    <small>{s.email || 'no email'}{s.connected === false ? ' · disconnected' : ''}</small>
                  </div>
                </button>
              ))}
            </div>
          )}

          <div className="account-main">
            {account ? (
              <>
                <div className="account-profile-card">
                  <div className="account-avatar">
                    {account.applicantName.charAt(0).toUpperCase()}
                  </div>
                  <div className="account-identity">
                    <div className="account-name-row">
                      <h3>{displayName(account.profile, account.applicantName)}</h3>
                      {account.connected === false ? (
                        <span className="status">
                          <span className="dot" />
                          Disconnected
                        </span>
                      ) : (
                        <span className={`status ${tone(
                          account.lastStatus === 'slot_detected' ? 'available' :
                          account.lastStatus === 'error' ? 'red' :
                          account.lastStatus === 'checking' ? 'amber' : 'blue'
                        )}`}>
                          <span className="dot" />
                          {account.lastStatus === 'slot_detected' ? 'Slots found' : account.lastStatus.replace('_', ' ')}
                        </span>
                      )}
                    </div>
                    <div className="account-meta-grid">
                      <span><Mail size={13} /> {account.profile?.emailId || account.email || '—'}</span>
                      <span><Phone size={13} /> {account.profile?.phoneNumber || '—'}</span>
                      <span><MapPin size={13} /> {fullAddress(account.profile) || '—'}</span>
                      {account.profile?.dateOfBirth && <span><Calendar size={13} /> Born {fmtDate(account.profile.dateOfBirth)}</span>}
                    </div>
                    {account.candidateId && (
                      <div className="account-id">Candidate ID <code>{account.candidateId}</code></div>
                    )}
                    <div className="account-scrape-time">
                      Last scraped {timeAgo(account.lastScrapeAt)} · {account.lastScrapeError ? <span className="muted">{simplifyError(account.lastScrapeError)}</span> : 'fresh'}
                    </div>
                  </div>
                  <div className="account-controls">
                    <a className="account-open" href={account.formUrl} target="_blank" rel="noreferrer">
                      Open on Amazon <ExternalLink size={13} />
                    </a>
                    {account.connected === false ? (
                      <button className="account-control-btn reconnect" onClick={() => handleConnection(account._id, true)}>
                        Reconnect
                      </button>
                    ) : (
                      <button className="account-control-btn disconnect" onClick={() => handleConnection(account._id, false)}>
                        Disconnect
                      </button>
                    )}
                    <button className="account-control-btn delete" onClick={() => handleDelete(account._id, account.applicantName)}>
                      Delete
                    </button>
                  </div>
                </div>

                {/* ── Radar Alert Banner ── */}
                {radarAlerts.filter(a => !dismissedAlerts.has(a.id)).length > 0 && (
                  <div className="radar-alert-list">
                    {radarAlerts.filter(a => !dismissedAlerts.has(a.id)).map(alert => (
                      <div key={alert.id} className={`radar-alert-card ${alert.postingStatus === 'UNPOSTED' ? 'unposted' : ''}`}>
                        <div className="radar-alert-top">
                          <div className="radar-alert-badge">
                            <Zap size={13} />
                            {alert.postingStatus === 'UNPOSTED' ? 'UNPOSTED SHIFT DETECTED!' : 'NEW SHIFT AVAILABLE!'}
                          </div>
                          <span className="radar-alert-time">{alert.detectedAt}</span>
                          <button className="radar-alert-dismiss" onClick={() => setDismissedAlerts(p => new Set([...p, alert.id]))}>
                            <X size={14} />
                          </button>
                        </div>
                        <div className="radar-alert-body">
                          <b>{alert.jobTitle}</b>
                          <div className="radar-alert-meta">
                            {alert.location && <span><MapPin size={11} /> {alert.location}</span>}
                            {alert.scheduleText && <span><Clock size={11} /> {alert.scheduleText}{alert.hoursPerWeek ? ` (${alert.hoursPerWeek}h)` : ''}</span>}
                            {alert.payText && <span>💷 {alert.payText}</span>}
                          </div>
                        </div>
                        <div className="radar-alert-pick-row">
                          <button
                            className={`radar-alert-pick ${pickingShiftKey === alert.id ? 'picking' : ''}`}
                            disabled={pickingShiftKey === alert.id}
                            onClick={() => {
                              if (selectedId) {
                                handlePickShift(selectedId, alert.id, alert.jobId, undefined, alert.scheduleId)
                              }
                            }}
                          >
                            {pickingShiftKey === alert.id
                              ? <><Loader2 className="spin" size={13} /> Picking shift… {pickElapsed > 0 ? `(${pickElapsed}s)` : ''}</>
                              : <>Pick this shift</>
                            }
                          </button>
                          <a
                            className="radar-alert-open"
                            href={alert.applyUrl}
                            target="_blank"
                            rel="noreferrer"
                            title="Open on Amazon Jobs"
                          >
                            <ExternalLink size={13} />
                          </a>
                        </div>
                        {pickResult?.key === alert.id && (
                          <div className={`pick-result ${pickResult.ok ? 'pick-ok' : 'pick-fail'}`}>
                            {pickResult.ok ? '✓' : '✗'} {pickResult.message}
                          </div>
                        )}
                      </div>
                    ))}
                  </div>
                )}

                {/* ── Applications + Slots (combined) ── */}
                <div className="account-section">
                  <div className="feed-head">
                    <h3>Applications &amp; slots</h3>
                    <div style={{display:'flex', alignItems:'center', gap:'8px'}}>
                      {/* Monitoring toggle */}
                      <button
                        className={`radar-monitor-btn ${radarMonitoring ? 'on' : 'off'}`}
                        onClick={() => setRadarMonitoring(v => !v)}
                        title={radarMonitoring ? 'Pause shift alerts' : 'Start shift alerts'}
                      >
                        {radarMonitoring ? <Bell size={13} /> : <BellOff size={13} />}
                        {radarMonitoring ? 'Monitoring' : 'Paused'}
                      </button>
                      {/* Filter dropdown */}
                      <div className="shift-filter-wrap">
                      <button
                        className={`shift-filter-btn ${activeFilterCount > 0 ? 'active' : ''}`}
                        onClick={() => setShowFilterDropdown(v => !v)}
                      >
                        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M3 6h18M6 12h12M9 18h6"/></svg>
                        Filter{activeFilterCount > 0 ? ` (${activeFilterCount})` : ''}
                      </button>

                      {showFilterDropdown && (
                        <div className="shift-filter-dropdown">
                          <div className="sfd-section">
                            <p className="sfd-label">Day of week</p>
                            <div className="sfd-chips">
                              {DAYS.map(day => (
                                <button
                                  key={day}
                                  className={`sfd-chip ${filterDays.includes(day) ? 'active' : ''}`}
                                  onClick={() => toggleDay(day)}
                                >{day}</button>
                              ))}
                            </div>
                          </div>
                          <div className="sfd-section">
                            <p className="sfd-label">Hours per week</p>
                            <div className="sfd-chips">
                              <button
                                className={`sfd-chip ${filterHours === 'all' ? 'active' : ''}`}
                                onClick={() => setFilterHours('all')}
                              >All</button>
                              {HOURS_BANDS.map(b => (
                                <button
                                  key={b.value}
                                  className={`sfd-chip ${filterHours === b.value ? 'active' : ''}`}
                                  onClick={() => setFilterHours(filterHours === b.value ? 'all' : b.value)}
                                >{b.label}</button>
                              ))}
                            </div>
                          </div>
                          {activeFilterCount > 0 && (
                            <button className="sfd-clear" onClick={() => { setFilterDays([]); setFilterHours('all') }}>
                              Clear all filters
                            </button>
                          )}
                        </div>
                      )}
                      </div>
                    </div>
                  </div>
                  {(account.applications?.length || 0) === 0 ? (
                    <div className="account-empty">No applications loaded yet. Click "Fetch live data".</div>
                  ) : (
                    <div className="app-shift-list">
                      {account.applications
                        .filter((app) => {
                          const s = (app.appStatus || app.state || '').toLowerCase()
                          return !s.includes('withdrawn') && !s.includes('closed') && !s.includes('rejected')
                        })
                        .filter((app) => {
                          // If filters active, check scheduleText and hoursPerWeek
                          if (filterDays.length === 0 && filterHours === 'all') return true
                          // Extract hoursPerWeek from scheduleText e.g. "(20h)"
                          const hwMatch = (app.scheduleText || '').match(/\((\d+)h\)/)
                          const hw = hwMatch ? parseInt(hwMatch[1]) : null
                          return matchesFilters(app.scheduleText, hw)
                        })
                        .map((app) => {
                        // Only show slots that belong to this specific application.
                        // account.appointments may contain slots from any application —
                        // only include them if they have a matching applicationId.
                        const appSlots: AppointmentSlot[] = app.appointments || []
                        const accountSlotsForApp: AppointmentSlot[] = (account.appointments || [])
                          .filter((s) => s.applicationId === app.applicationId)
                        const allSlots: AppointmentSlot[] = [...appSlots, ...accountSlotsForApp]
                        const matchedSlots = Array.from(
                          new Map(allSlots.map((s) => [s.timeSlotId || JSON.stringify(s), s])).values()
                        )

                        return (
                          <div key={app.applicationId} className="app-shift-card">
                            {/* Header: title + status */}
                            <div className="app-shift-header">
                              <div className="app-shift-title">
                                <b>{app.jobTitle || 'Amazon role'}</b>
                                <span className={`status ${tone(app.appStatus || app.state || 'slate')}`}>
                                  <span className="dot" />
                                  {app.appStatus || app.state || 'Unknown'}
                                </span>
                              </div>

                              {/* Meta row */}
                              <div className="app-shift-meta">
                                {app.location && (
                                  <span><MapPin size={11} /> {app.location}</span>
                                )}
                                {app.scheduleText && (
                                  <span><Clock size={11} /> {app.scheduleText}</span>
                                )}
                                {app.firstDayOnSite && (
                                  <span><CalendarDays size={11} /> First day: {fmtDate(app.firstDayOnSite)}</span>
                                )}
                                {(app.stepLabel || app.step) && (
                                  <span>
                                    <Zap size={11} />
                                    {app.stepLabel || app.step}
                                    {app.stepLabel && app.subStep ? ` · ${app.subStep}` : ''}
                                  </span>
                                )}
                              </div>

                              {/* Continue link */}
                              {app.continueApplicationLink && (
                                <a
                                  className="app-shift-link"
                                  href={absoluteJobsUrl(app.continueApplicationLink)}
                                  target="_blank"
                                  rel="noreferrer"
                                >
                                  Continue application <ExternalLink size={12} />
                                </a>
                              )}
                            </div>

                            {/* Slots */}
                            {matchedSlots.length > 0 ? (
                              <div className="app-shift-slots">
                                <div className="app-shift-slots-label">
                                  <CalendarDays size={12} /> Available slots ({matchedSlots.length})
                                </div>
                                {matchedSlots.map((slot, si) => {
                                  const loc = slot.displayReadyLocation || slot.locationType || 'Amazon site'
                                  const dateStr = fmtDate(slot.startDate)
                                  const timeStr = fmtTime(slot.startTime)

                                  // Build Amazon shift selection URL
                                  const jobId = app.jobId || ''
                                  const slotKey = slot.timeSlotId || `${app.applicationId}-${si}`
                                  const selectUrl = app.continueApplicationLink
                                    ? absoluteJobsUrl(app.continueApplicationLink)
                                    : jobId
                                    ? `https://www.jobsatamazon.co.uk/selfservice/schedule/available-schedule/${slot.timeSlotId || ''}/${jobId}`
                                    : 'https://www.jobsatamazon.co.uk/app#/myApplications'

                                  return (
                                    <div key={si} className="app-shift-slot">
                                      <div className="app-shift-slot-info">
                                        <span className={`status tone-green`}>
                                          <span className="dot" />
                                          {slot.kind || 'Shift'}
                                        </span>
                                        <span><CalendarDays size={11} /> {dateStr}</span>
                                        <span><Clock size={11} /> {timeStr !== '—' ? timeStr : 'TBD'}</span>
                                        <span><MapPin size={11} /> {loc}</span>
                                      </div>
                                      <div className="slot-select-row">
                                        <button
                                          className={`slot-select-btn ${pickingShiftKey === slotKey ? 'picking' : ''}`}
                                          disabled={pickingShiftKey === slotKey}
                                          onClick={() => {
                                            if (selectedId) {
                                              handlePickShift(
                                                selectedId,
                                                slotKey,
                                                app.jobId || '',
                                                app.applicationId,
                                                slot.timeSlotId
                                              )
                                            }
                                          }}
                                          title="Auto-pick this shift on Amazon Jobs"
                                        >
                                          {pickingShiftKey === slotKey
                                            ? <><Loader2 className="spin" size={11} /> Picking… {pickElapsed > 0 ? `(${pickElapsed}s)` : ''}</>
                                            : <>Pick this shift</>
                                          }
                                        </button>
                                        <a
                                          className="slot-open-btn"
                                          href={selectUrl}
                                          target="_blank"
                                          rel="noreferrer"
                                          title="Open on Amazon Jobs"
                                        >
                                          <ExternalLink size={12} />
                                        </a>
                                      </div>
                                      {pickResult?.key === slotKey && (
                                        <div className={`pick-result ${pickResult.ok ? 'pick-ok' : 'pick-fail'}`}>
                                          {pickResult.ok ? '✓' : '✗'} {pickResult.message}
                                        </div>
                                      )}
                                    </div>
                                  )
                                })}
                              </div>
                            ) : (
                              <div className="app-shift-no-slots">
                                No slots visible yet — monitoring automatically
                              </div>
                            )}
                          </div>
                        )
                      })}
                    </div>
                  )}
                </div>
              </>
            ) : (
              <div className="account-loading">
                {loading ? <Loader2 className="spin" size={22} /> : <CircleUser size={34} />}
                <span>{loading ? 'Loading account…' : 'Select an account to view details'}</span>
              </div>
            )}
          </div>
        </div>
        {showAdd && <div className="account-add-section">{pasteForm}</div>}
        </>
      )}
    </section>
  )
}
