import { useEffect, useState, useRef, useCallback } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { ChevronLeft, RefreshCw, Wrench } from 'lucide-react'
import { treesApi } from '@/api/trees'
import { sessionsApi } from '@/api/sessions'
import { BatchStatusCard } from '@/components/maintenance/BatchStatusCard'
import { Spinner } from '@/components/common/Spinner'
import { cn } from '@/lib/utils'
import type { Tree, Session } from '@/types'

// Batch sessions are created with a shared batch_id and individual target_labels.
// Some targets may not have a session yet if created via a pre-populated target list
// where sessions were created all at once — in practice all sessions exist at batch
// launch time, so we group by target_label from the sessions we get back.

export default function BatchStatusPage() {
  const { id: treeId, batchId } = useParams<{ id: string; batchId: string }>()
  const navigate = useNavigate()

  const [tree, setTree] = useState<Tree | null>(null)
  const [sessions, setSessions] = useState<Session[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [isRefreshing, setIsRefreshing] = useState(false)
  const [loadError, setLoadError] = useState<string | null>(null)
  const [batchDate, setBatchDate] = useState<Date | null>(null)
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)

  const loadSessions = useCallback(async (showRefreshing = false) => {
    if (!batchId) return
    if (showRefreshing) setIsRefreshing(true)
    try {
      const data = await sessionsApi.list({ batch_id: batchId, size: 100 })
      setSessions(Array.isArray(data) ? data : [])
      setLoadError(null)
      if (data.length > 0 && data[0].started_at) {
        setBatchDate(new Date(data[0].started_at))
      }
    } catch {
      setLoadError('Failed to load batch sessions')
    } finally {
      if (showRefreshing) setIsRefreshing(false)
    }
  }, [batchId])

  // Initial load
  useEffect(() => {
    if (!treeId || !batchId) return
    const load = async () => {
      try {
        const [treeData] = await Promise.all([
          treesApi.get(treeId),
          loadSessions(),
        ])
        setTree(treeData)
      } catch {
        setLoadError('Failed to load batch data')
      } finally {
        setIsLoading(false)
      }
    }
    load()
  }, [treeId, batchId, loadSessions])

  // Polling: refresh every 5s while any session is in-progress
  useEffect(() => {
    const hasInProgress = sessions.some(s => s.started_at && !s.completed_at)
    if (hasInProgress) {
      pollRef.current = setInterval(() => loadSessions(), 5000)
    } else {
      if (pollRef.current) {
        clearInterval(pollRef.current)
        pollRef.current = null
      }
    }
    return () => {
      if (pollRef.current) clearInterval(pollRef.current)
    }
  }, [sessions, loadSessions])

  if (isLoading) {
    return (
      <div className="flex h-64 items-center justify-center">
        <Spinner size="sm" className="h-6 w-6 border-primary border-t-transparent" />
      </div>
    )
  }

  const total = sessions.length
  const completed = sessions.filter(s => s.completed_at).length
  const inProgress = sessions.filter(s => s.started_at && !s.completed_at).length
  const allDone = total > 0 && completed === total

  // Outcome summary for completion
  const outcomeCounts = sessions.reduce<Record<string, number>>((acc, s) => {
    if (s.outcome) acc[s.outcome] = (acc[s.outcome] ?? 0) + 1
    return acc
  }, {})

  const progressPercent = total > 0 ? Math.round((completed / total) * 100) : 0

  return (
    <div className="container mx-auto max-w-3xl space-y-6 px-4 py-6 sm:px-6 sm:py-8">
      {/* Breadcrumb */}
      <div className="flex items-center justify-between">
        <button
          onClick={() => treeId && navigate(`/flows/${treeId}/maintenance`)}
          className="flex items-center gap-1.5 text-[0.875rem] text-muted-foreground hover:text-foreground transition-colors"
        >
          <ChevronLeft className="h-4 w-4" />
          {tree?.name ?? 'Maintenance Flow'}
        </button>
        <button
          onClick={() => loadSessions(true)}
          disabled={isRefreshing}
          className="flex items-center gap-1.5 rounded-lg border border-border px-3 py-1.5 text-[0.8125rem] text-muted-foreground hover:bg-accent hover:text-foreground transition-colors disabled:opacity-50"
        >
          <RefreshCw className={cn('h-3.5 w-3.5', isRefreshing && 'animate-spin')} />
          Refresh
        </button>
      </div>

      {/* Header */}
      <div className="flex items-start gap-3">
        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-amber-500/10 text-amber-400">
          <Wrench className="h-5 w-5" />
        </div>
        <div>
          <h1 className="text-xl font-semibold text-foreground">Batch Run</h1>
          {batchDate && (
            <p className="text-[0.875rem] text-muted-foreground">
              {batchDate.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })}
            </p>
          )}
        </div>
      </div>

      {/* Progress bar */}
      {total > 0 && (
        <div className="rounded-xl border border-border bg-card p-5 space-y-3">
          <div className="flex items-center justify-between text-[0.875rem]">
            <span className="font-medium text-foreground">
              {completed} of {total} complete
            </span>
            <span className={cn(
              'font-label text-[0.6875rem] uppercase tracking-wide rounded-full px-2 py-0.5',
              allDone
                ? 'text-emerald-400 bg-emerald-500/10'
                : inProgress > 0
                  ? 'text-amber-400 bg-amber-500/10'
                  : 'text-muted-foreground bg-muted'
            )}>
              {allDone ? 'Complete' : inProgress > 0 ? `${inProgress} in progress` : 'Not started'}
            </span>
          </div>
          <div className="h-2 rounded-full bg-muted overflow-hidden">
            <div
              className={cn(
                'h-full rounded-full transition-all duration-500',
                allDone ? 'bg-emerald-500' : 'bg-amber-500'
              )}
              style={{ width: `${progressPercent}%` }}
            />
          </div>

          {/* Completion summary */}
          {allDone && Object.keys(outcomeCounts).length > 0 && (
            <div className="flex flex-wrap gap-3 pt-1">
              {outcomeCounts.resolved && (
                <span className="text-[0.8125rem] text-emerald-400">{outcomeCounts.resolved} resolved</span>
              )}
              {outcomeCounts.escalated && (
                <span className="text-[0.8125rem] text-red-400">{outcomeCounts.escalated} escalated</span>
              )}
              {outcomeCounts.workaround && (
                <span className="text-[0.8125rem] text-amber-400">{outcomeCounts.workaround} workaround</span>
              )}
              {outcomeCounts.unresolved && (
                <span className="text-[0.8125rem] text-muted-foreground">{outcomeCounts.unresolved} unresolved</span>
              )}
            </div>
          )}
        </div>
      )}

      {/* Target cards */}
      <div className="space-y-2">
        {loadError ? (
          <div className="rounded-lg border border-red-400/20 bg-red-400/10 p-4 text-center">
            <p className="text-sm text-red-400 mb-3">{loadError}</p>
            <button
              onClick={() => loadSessions(true)}
              className="rounded-md border border-border px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors"
            >
              Try again
            </button>
          </div>
        ) : sessions.length === 0 ? (
          <p className="text-center text-[0.875rem] text-muted-foreground py-8">
            No sessions found for this batch.
          </p>
        ) : (
          sessions
            .sort((a, b) => {
              // Sort: in-progress first, then not-started, then complete
              const rank = (s: Session) => {
                if (s.started_at && !s.completed_at) return 0
                if (!s.started_at) return 1
                return 2
              }
              return rank(a) - rank(b)
            })
            .map((session) => (
              <BatchStatusCard
                key={session.id}
                session={session}
                targetLabel={session.target_label ?? session.id}
                treeId={treeId!}
                batchId={batchId!}
              />
            ))
        )}
      </div>
    </div>
  )
}

