import { useEffect, useState, useRef, useCallback } from 'react'
import { Search } from 'lucide-react'
import { Link, useNavigate, useSearchParams } from 'react-router-dom'
import { PageMeta } from '@/components/common/PageMeta'
import { sessionsApi } from '@/api/sessions'
import { aiSessionsApi } from '@/api/aiSessions'
import { treesApi } from '@/api/trees'
import type { Session, TreeListItem, SessionOutcome, AISessionSummary } from '@/types'
import type { DateRange } from 'react-day-picker'
import { SessionFilters } from '@/components/session/SessionFilters'
import type { SessionFilterState } from '@/components/session/SessionFilters'
import { Spinner } from '@/components/common/Spinner'
import { EmptyState } from '@/components/common/EmptyState'
import { SessionIllustration } from '@/components/common/EmptyStateIllustrations'
import { AISessionListItem } from '@/components/flowpilot/AISessionListItem'
import { cn } from '@/lib/utils'
import { toast } from '@/lib/toast'
import { getSessionResumePath } from '@/lib/routing'

export function SessionHistoryPage() {
  const navigate = useNavigate()
  const [searchParams, setSearchParams] = useSearchParams()

  const [aiSessions, setAiSessions] = useState<AISessionSummary[]>([])
  const [aiLoading, setAiLoading] = useState(false)
  const [aiSearchInput, setAiSearchInput] = useState('')
  const aiSearchTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
  const [aiFilters, setAiFilters] = useState({
    q: '',
    problem_domain: '',
    confidence_tier: '',
    date_from: '',
    date_to: '',
  })

  const [sessions, setSessions] = useState<Session[]>([])
  const [hasMore, setHasMore] = useState(false)
  const [trees, setTrees] = useState<TreeListItem[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [filter, setFilter] = useState<'all' | 'completed' | 'active' | 'prepared'>('active')

  // Close session popover state
  const [closingSessionId, setClosingSessionId] = useState<string | null>(null)
  const [closeOutcome, setCloseOutcome] = useState<SessionOutcome | ''>('')
  const [closeNotes, setCloseNotes] = useState('')
  const [closeLoading, setCloseLoading] = useState(false)
  const closePopoverRef = useRef<HTMLDivElement>(null)

  // Initialize filters from URL params
  const [filters, setFilters] = useState<SessionFilterState>(() => {
    const ticketNumber = searchParams.get('ticket') || ''
    const clientName = searchParams.get('client') || ''
    const treeName = searchParams.get('tree') || ''
    const dateType = (searchParams.get('dateType') || 'started') as 'started' | 'completed'

    const from = searchParams.get('from')
    const to = searchParams.get('to')
    const dateRange: DateRange | undefined =
      from && to ? { from: new Date(from), to: new Date(to) } : undefined

    return {
      ticketNumber,
      clientName,
      treeName,
      dateRange,
      dateType,
    }
  })

  // Debounce AI search input → aiFilters.q
  useEffect(() => {
    if (aiSearchTimeout.current) clearTimeout(aiSearchTimeout.current)
    aiSearchTimeout.current = setTimeout(() => {
      setAiFilters(prev => ({ ...prev, q: aiSearchInput }))
    }, 400)
    return () => { if (aiSearchTimeout.current) clearTimeout(aiSearchTimeout.current) }
  }, [aiSearchInput])

  // Load trees for filter dropdown
  useEffect(() => {
    const loadTrees = async () => {
      try {
        const treesData = await treesApi.list({})
        setTrees(treesData)
      } catch (err) {
        console.error('Failed to load trees:', err)
      }
    }
    loadTrees()
  }, [])

  // Load sessions when filters change
  useEffect(() => {
    let cancelled = false

    const loadSessions = async () => {
      setIsLoading(true)
      try {
        const params: Record<string, string | boolean> = {}

        // Tab filter (all/active/completed/prepared)
        if (filter === 'prepared') {
          params.status = 'prepared'
        } else if (filter !== 'all') {
          params.completed = filter === 'completed'
        }

        // Search/filter params
        if (filters.ticketNumber) {
          params.ticket_number = filters.ticketNumber
        }
        if (filters.clientName) {
          params.client_name = filters.clientName
        }
        if (filters.treeName) {
          params.tree_name = filters.treeName
        }

        // Date range params
        if (filters.dateRange?.from) {
          const fromDate = filters.dateRange.from
          const toDate = filters.dateRange.to || filters.dateRange.from
          // Set end-of-day on the "to" date so sessions created that day are included
          const toDateEnd = new Date(toDate)
          toDateEnd.setHours(23, 59, 59, 999)

          if (filters.dateType === 'started') {
            params.started_after = fromDate.toISOString()
            params.started_before = toDateEnd.toISOString()
          } else {
            params.completed_after = fromDate.toISOString()
            params.completed_before = toDateEnd.toISOString()
          }
        }

        const sessionsData = await sessionsApi.list({ ...params, size: 51 })
        if (cancelled) return
        const truncated = sessionsData.length > 50
        setHasMore(truncated)
        setSessions(truncated ? sessionsData.slice(0, 50) : sessionsData)
      } catch (err) {
        if (cancelled) return
        toast.error('Failed to load sessions')
        console.error(err)
      } finally {
        if (!cancelled) setIsLoading(false)
      }
    }

    loadSessions()
    return () => { cancelled = true }
  }, [filter, filters])

  // Update URL params when filters change
  useEffect(() => {
    const params = new URLSearchParams()

    if (filters.ticketNumber) params.set('ticket', filters.ticketNumber)
    if (filters.clientName) params.set('client', filters.clientName)
    if (filters.treeName) params.set('tree', filters.treeName)
    if (filters.dateRange?.from) {
      params.set('from', filters.dateRange.from.toISOString())
      params.set('to', (filters.dateRange.to || filters.dateRange.from).toISOString())
      params.set('dateType', filters.dateType)
    }

    setSearchParams(params, { replace: true })
  }, [filters, setSearchParams])

  // Load AI sessions always
  useEffect(() => {
    let cancelled = false
    const loadAiSessions = async () => {
      setAiLoading(true)
      try {
        const data = await aiSessionsApi.listSessions({
          limit: 50,
          q: aiFilters.q || undefined,
          problem_domain: aiFilters.problem_domain || undefined,
          confidence_tier: aiFilters.confidence_tier || undefined,
          date_from: aiFilters.date_from || undefined,
          date_to: aiFilters.date_to ? `${aiFilters.date_to}T23:59:59.999Z` : undefined,
        })
        if (!cancelled) setAiSessions(data)
      } catch {
        if (!cancelled) toast.error('Failed to load AI sessions')
      } finally {
        if (!cancelled) setAiLoading(false)
      }
    }
    loadAiSessions()
    return () => { cancelled = true }
  }, [aiFilters])

  const handleFilterChange = (newFilters: SessionFilterState) => {
    setFilters(newFilters)
  }

  const handleClearFilters = () => {
    setFilters({
      ticketNumber: '',
      clientName: '',
      treeName: '',
      dateRange: undefined,
      dateType: 'started',
    })
  }

  const handleCloseSession = useCallback(async () => {
    if (!closingSessionId || !closeOutcome) return
    setCloseLoading(true)
    try {
      await sessionsApi.complete(closingSessionId, {
        outcome: closeOutcome,
        outcome_notes: closeNotes || undefined,
      })
      setSessions(prev =>
        prev.map(s =>
          s.id === closingSessionId
            ? { ...s, completed_at: new Date().toISOString(), outcome: closeOutcome, outcome_notes: closeNotes || null }
            : s
        )
      )
      toast.success('Session closed')
      setClosingSessionId(null)
      setCloseOutcome('')
      setCloseNotes('')
    } catch {
      toast.error('Failed to close session')
    } finally {
      setCloseLoading(false)
    }
  }, [closingSessionId, closeOutcome, closeNotes])

  // Close popover on click outside
  useEffect(() => {
    if (!closingSessionId) return
    const handleClickOutside = (e: MouseEvent) => {
      if (closePopoverRef.current && !closePopoverRef.current.contains(e.target as Node)) {
        setClosingSessionId(null)
        setCloseOutcome('')
        setCloseNotes('')
      }
    }
    document.addEventListener('mousedown', handleClickOutside)
    return () => document.removeEventListener('mousedown', handleClickOutside)
  }, [closingSessionId])

  const formatDate = (dateString: string) => {
    return new Date(dateString).toLocaleString()
  }

  const getTreeName = (session: Session): string => {
    return session.tree_snapshot?.name || 'Unknown Tree'
  }

  const formatOutcomeLabel = (outcome: Session['outcome']): string => {
    if (!outcome) return 'Not set'
    const labels: Record<string, string> = {
      resolved: 'Resolved',
      escalated: 'Escalated',
      workaround: 'Workaround',
      unresolved: 'Unresolved',
      cancelled: 'Cancelled',
      resolved_externally: 'Resolved Externally',
    }
    return labels[outcome] ?? outcome
  }

  const hasAiFiltersActive = !!(aiSearchInput || aiFilters.q || aiFilters.problem_domain || aiFilters.confidence_tier || aiFilters.date_from || aiFilters.date_to)
  const hasFlowFiltersActive = !!(filters.ticketNumber || filters.clientName || filters.treeName || filters.dateRange?.from)

  // Determine section visibility
  const showAiSection = aiLoading || aiSessions.length > 0 || hasAiFiltersActive
  const showFlowSection = isLoading || sessions.length > 0 || hasFlowFiltersActive
  const showCombinedEmpty = !showAiSection && !showFlowSection

  return (
    <div className="overflow-y-auto h-full">
    <PageMeta title="Sessions" />
    <div className="container mx-auto px-4 py-6 sm:px-6 sm:py-8">
      <div className="mb-8">
        <h1 className="text-2xl font-heading font-bold text-foreground sm:text-3xl">Sessions</h1>
        <p className="mt-2 text-muted-foreground">
          View and manage all your sessions
        </p>
      </div>

      {showCombinedEmpty && (
        <EmptyState
          illustration={<SessionIllustration />}
          title="No sessions yet"
          description="Start a flow or FlowPilot session to begin. All your sessions will appear here."
          action={
            <div className="flex gap-3">
              <Link
                to="/trees"
                className="inline-flex items-center gap-2 rounded-[10px] bg-gradient-brand px-5 py-2.5 text-sm font-semibold text-[#101114] shadow-lg shadow-primary/20 hover:opacity-90 active:scale-[0.97] transition-all"
              >
                Start a Flow
              </Link>
              <Link
                to="/pilot"
                className="inline-flex items-center gap-2 rounded-[10px] border border-border bg-[rgba(255,255,255,0.04)] px-5 py-2.5 text-sm font-semibold text-foreground hover:border-[rgba(255,255,255,0.12)] transition-all"
              >
                Start AI Session
              </Link>
            </div>
          }
          learnMoreLink="/guides/sessions"
        />
      )}

      {/* FlowPilot Sessions Section */}
      {showAiSection && (
        <>
          <h2 className="font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-3">FlowPilot Sessions</h2>

          {/* AI Session Filter Bar */}
          <div className="glass-card-static p-3 mb-4">
            <div className="flex flex-wrap gap-3 items-center">
              {/* Search input */}
              <div className="relative flex-1 min-w-[180px]">
                <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
                <input
                  type="text"
                  value={aiSearchInput}
                  onChange={(e) => setAiSearchInput(e.target.value)}
                  placeholder="Search sessions..."
                  className="w-full rounded-lg border border-border bg-card pl-8 pr-3 py-1.5 text-sm text-foreground placeholder:text-muted-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none"
                />
              </div>

              {/* Problem domain dropdown */}
              <select
                value={aiFilters.problem_domain}
                onChange={(e) => setAiFilters((f) => ({ ...f, problem_domain: e.target.value }))}
                title="Filter by problem domain"
                className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [&>option]:bg-[#1a1c21] [&>option]:text-foreground"
              >
                <option value="">All domains</option>
                <option value="Active Directory">Active Directory</option>
                <option value="Networking">Networking</option>
                <option value="Microsoft 365">Microsoft 365</option>
                <option value="Hardware">Hardware</option>
                <option value="Security">Security</option>
                <option value="Email">Email</option>
                <option value="Printing">Printing</option>
                <option value="VPN / Remote Access">VPN / Remote Access</option>
                <option value="Cloud Services">Cloud Services</option>
                <option value="Other">Other</option>
              </select>

              {/* Confidence tier pills */}
              <div className="flex gap-1">
                {(['', 'guided', 'exploring', 'discovery'] as const).map((tier) => (
                  <button
                    key={tier}
                    onClick={() => setAiFilters((f) => ({ ...f, confidence_tier: tier }))}
                    className={cn(
                      'rounded-full border px-3 py-1 text-xs font-label transition-colors',
                      aiFilters.confidence_tier === tier
                        ? 'bg-primary/10 text-foreground border-primary/30'
                        : 'bg-card text-muted-foreground border-border hover:text-foreground hover:border-[rgba(255,255,255,0.12)]'
                    )}
                  >
                    {tier === '' ? 'All' : tier.charAt(0).toUpperCase() + tier.slice(1)}
                  </button>
                ))}
              </div>

              {/* Date range inputs */}
              <div className="flex items-center gap-2">
                <input
                  type="date"
                  value={aiFilters.date_from}
                  onChange={(e) => setAiFilters((f) => ({ ...f, date_from: e.target.value }))}
                  title="From date"
                  className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
                />
                <span className="text-xs text-muted-foreground">to</span>
                <input
                  type="date"
                  value={aiFilters.date_to}
                  onChange={(e) => setAiFilters((f) => ({ ...f, date_to: e.target.value }))}
                  title="To date"
                  className="rounded-lg border border-border bg-card px-3 py-1.5 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none [color-scheme:dark]"
                />
              </div>

              {/* Clear filters */}
              {hasAiFiltersActive && (
                <button
                  onClick={() => {
                    setAiSearchInput('')
                    setAiFilters({ q: '', problem_domain: '', confidence_tier: '', date_from: '', date_to: '' })
                  }}
                  className="text-xs text-muted-foreground hover:text-foreground transition-colors"
                >
                  Clear
                </button>
              )}
            </div>
          </div>

          {aiLoading ? (
            <div className="flex justify-center py-12">
              <Spinner />
            </div>
          ) : aiSessions.length === 0 ? (
            <EmptyState
              title="No sessions match your filters"
              description="Try adjusting your search or filters."
              action={
                <button
                  onClick={() => {
                    setAiSearchInput('')
                    setAiFilters({ q: '', problem_domain: '', confidence_tier: '', date_from: '', date_to: '' })
                  }}
                  className="text-foreground hover:underline text-sm"
                >
                  Clear all filters
                </button>
              }
            />
          ) : (
            <div className="space-y-2">
              {aiSessions.map((s) => (
                <AISessionListItem key={s.id} session={s} />
              ))}
            </div>
          )}

          {/* Divider between sections */}
          {showFlowSection && (
            <div className="my-8 border-t border-border" />
          )}
        </>
      )}

      {/* Flow Sessions Section */}
      {showFlowSection && (
      <>
      <h2 className="font-label text-[0.625rem] uppercase tracking-[0.1em] text-muted-foreground mb-3">Flow Sessions</h2>

      {/* Filter Tabs */}
      <div className="mb-6 flex gap-2 border-b border-border">
        {(['active', 'prepared', 'completed', 'all'] as const).map((tab) => (
          <button
            key={tab}
            onClick={() => setFilter(tab)}
            className={cn(
              'px-4 py-2 text-sm font-medium transition-colors',
              filter === tab
                ? 'border-b-2 border-primary text-foreground'
                : 'text-muted-foreground hover:text-foreground'
            )}
          >
            {tab.charAt(0).toUpperCase() + tab.slice(1)}
          </button>
        ))}
      </div>

      <div className="mb-6">
        <SessionFilters
          filters={filters}
          onChange={handleFilterChange}
          onClear={handleClearFilters}
          trees={trees}
        />
      </div>

      {/* Loading State */}
      {isLoading ? (
        <div className="flex justify-center py-12">
          <Spinner />
        </div>
      ) : sessions.length === 0 ? (
        (filters.ticketNumber || filters.clientName || filters.treeName || filters.dateRange?.from) ? (
          <EmptyState
            title="No sessions match your filters"
            description="Try adjusting your search or filters."
            action={
              <button onClick={handleClearFilters} className="text-foreground hover:underline text-sm">
                Clear all filters
              </button>
            }
          />
        ) : (
          <EmptyState
            illustration={<SessionIllustration />}
            title="Your session history will appear here"
            description="Every troubleshooting session is recorded with decisions, timing, and outcomes — ready for export or review."
            action={
              <Link
                to="/trees"
                className="inline-flex items-center gap-2 rounded-[10px] bg-gradient-brand px-5 py-2.5 text-sm font-semibold text-[#101114] shadow-lg shadow-primary/20 hover:opacity-90 active:scale-[0.97] transition-all"
              >
                Start a Session
              </Link>
            }
            learnMoreLink="/guides/sessions"
          />
        )
      ) : (
        <>
        <div className="space-y-4">
          {sessions.map((session, i) => (
            <div
              key={session.id}
              className={cn(
                'stagger-item',
                closingSessionId === session.id && 'relative z-50'
              )}
              style={{ '--stagger-index': i } as React.CSSProperties}
            >
            <div
              className="bg-card border border-border rounded-xl p-4 transition-all hover:bg-accent/50"
            >
              <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                <div className="flex-1">
                  {/* Status and Ticket/Client */}
                  <div className="flex flex-wrap items-center gap-2">
                    <span
                      className={cn(
                        'inline-block h-2.5 w-2.5 rounded-full',
                        session.completed_at ? 'bg-green-500' : 'bg-yellow-500'
                      )}
                    />
                    <span className="font-medium text-foreground">
                      {session.ticket_number || 'No ticket'}
                    </span>
                    {session.client_name && (
                      <span className="rounded-full bg-accent px-2.5 py-0.5 text-xs font-medium text-foreground">
                        {session.client_name}
                      </span>
                    )}
                    {session.completed_at && (
                      <span
                        className={cn(
                          'rounded-full px-2.5 py-0.5 text-xs font-medium',
                          session.outcome === 'resolved' && 'bg-emerald-500/20 text-emerald-300',
                          session.outcome === 'workaround' && 'bg-amber-500/20 text-amber-300',
                          session.outcome === 'escalated' && 'bg-blue-500/20 text-blue-300',
                          session.outcome === 'unresolved' && 'bg-rose-500/20 text-rose-300',
                          session.outcome === 'cancelled' && 'bg-zinc-500/20 text-zinc-300',
                          session.outcome === 'resolved_externally' && 'bg-cyan-500/20 text-cyan-300',
                          !session.outcome && 'bg-accent text-muted-foreground'
                        )}
                      >
                        {formatOutcomeLabel(session.outcome)}
                      </span>
                    )}
                  </div>

                  {/* Tree Name */}
                  <p className="mt-1 text-sm text-muted-foreground">
                    <span className="font-medium">Tree:</span> {getTreeName(session)}
                  </p>

                  {/* Timestamps */}
                  <p className="mt-1 text-sm text-muted-foreground">
                    Started: {session.started_at ? formatDate(session.started_at) : 'Not started'}
                    {session.completed_at && (
                      <> · Completed: {formatDate(session.completed_at)}</>
                    )}
                  </p>

                  {/* Stats */}
                  <p className="mt-1 text-sm text-muted-foreground">
                    {session.decisions.length} decision{session.decisions.length !== 1 ? 's' : ''} recorded
                    {session.scratchpad && session.scratchpad.trim() && (
                      <span> · Has notes</span>
                    )}
                  </p>
                </div>

                {/* Actions */}
                <div className="relative flex gap-2">
                  <button
                    onClick={() => navigate(`/sessions/${session.id}`)}
                    className={cn(
                      'rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground',
                      'hover:bg-accent hover:text-foreground'
                    )}
                  >
                    View Details
                  </button>
                  {!session.completed_at && session.started_at && (
                    <>
                      <button
                        onClick={() => {
                          setClosingSessionId(closingSessionId === session.id ? null : session.id)
                          setCloseOutcome('')
                          setCloseNotes('')
                        }}
                        className={cn(
                          'rounded-md border border-border px-3 py-2 text-sm font-medium text-muted-foreground',
                          'hover:bg-accent hover:text-foreground',
                          closingSessionId === session.id && 'bg-accent text-foreground'
                        )}
                      >
                        Close
                      </button>
                      <button
                        onClick={() => navigate(getSessionResumePath(session.tree_id, session.tree_snapshot?.tree_type), { state: { sessionId: session.id } })}
                        className={cn(
                          'rounded-md bg-gradient-brand px-3 py-2 text-sm font-medium text-white shadow-lg shadow-primary/20',
                          'hover:opacity-90'
                        )}
                      >
                        Resume
                      </button>
                    </>
                  )}

                  {/* Close Session Popover */}
                  {closingSessionId === session.id && (
                    <div
                      ref={closePopoverRef}
                      className="absolute right-0 top-full z-20 mt-2 w-72 rounded-xl border border-border bg-card p-4 shadow-xl"
                    >
                      <p className="text-sm font-heading font-medium text-foreground mb-3">Close Session</p>

                      <label className="block text-xs font-label text-muted-foreground mb-1">Outcome</label>
                      <select
                        value={closeOutcome}
                        onChange={(e) => setCloseOutcome(e.target.value as SessionOutcome)}
                        title="Session outcome"
                        className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none mb-3"
                      >
                        <option value="">Select outcome...</option>
                        <option value="resolved">Resolved</option>
                        <option value="escalated">Escalated</option>
                        <option value="workaround">Workaround</option>
                        <option value="unresolved">Unresolved</option>
                        <option value="cancelled">Cancelled</option>
                        <option value="resolved_externally">Resolved Externally</option>
                      </select>

                      <label className="block text-xs font-label text-muted-foreground mb-1">Notes (optional)</label>
                      <textarea
                        value={closeNotes}
                        onChange={(e) => setCloseNotes(e.target.value)}
                        rows={2}
                        placeholder="Add closure notes..."
                        className="w-full rounded-lg border border-border bg-card px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:border-[rgba(6,182,212,0.3)] focus:outline-none resize-none mb-3"
                      />

                      <div className="flex items-center justify-end gap-2">
                        <button
                          onClick={() => {
                            setClosingSessionId(null)
                            setCloseOutcome('')
                            setCloseNotes('')
                          }}
                          className="rounded-lg px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
                        >
                          Cancel
                        </button>
                        <button
                          onClick={handleCloseSession}
                          disabled={!closeOutcome || closeLoading}
                          className={cn(
                            'rounded-lg px-4 py-1.5 text-sm font-medium shadow-lg shadow-primary/20 transition-opacity',
                            closeOutcome
                              ? 'bg-gradient-brand text-[#101114] hover:opacity-90'
                              : 'bg-gradient-brand text-[#101114] opacity-50 cursor-not-allowed'
                          )}
                        >
                          {closeLoading ? 'Closing...' : 'Confirm'}
                        </button>
                      </div>
                    </div>
                  )}
                </div>
              </div>
            </div>
            </div>
          ))}
        </div>
        {hasMore ? (
          <p className="text-center text-sm text-muted-foreground py-4">
            Showing the 50 most recent sessions
          </p>
        ) : sessions.length > 0 ? (
          <p className="text-center text-sm text-muted-foreground py-4">
            Showing all {sessions.length} sessions
          </p>
        ) : null}
        </>
      )}
      </>
      )}
    </div>
    </div>
  )
}

export default SessionHistoryPage
