import { Activity, Download, Plus, TimerReset, Zap } from 'lucide-solid'
import { For, Show, createMemo, createResource, createSignal } from 'solid-js'
import { DownloadCard } from '@/components/media/download-card'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
import { EmptyState } from '@/components/ui/empty-state'
import { MetricCard } from '@/components/ui/metric-card'
import { Skeleton } from '@/components/ui/skeleton'
import { downloadService, type DownloadCreateInput } from '@/services/download-service'
import { useAuth } from '@/stores/auth-store'

export const DownloadsPage = () => {
  const auth = useAuth()
  const [actionError, setActionError] = createSignal<string | null>(null)
  const [activeDownloadsData, { refetch }] = createResource(async () => {
    const accessToken = auth.accessToken()

    if (!accessToken) {
      return []
    }

    return downloadService.list(accessToken, { limit: 30 })
  })
  const activeDownloads = createMemo(() =>
    (activeDownloadsData() ?? []).filter((job) =>
      ['queued', 'downloading', 'stalled'].includes(job.status),
    ),
  )
  const totalThroughput = createMemo(() =>
    activeDownloads().reduce((total, job) => total + job.downloadSpeedMbps, 0),
  )
  const stalledCount = createMemo(() => activeDownloads().filter((job) => job.status === 'stalled').length)
  const queuedCount = createMemo(() => activeDownloads().filter((job) => job.status === 'queued').length)
  const downloadingCount = createMemo(() => activeDownloads().filter((job) => job.status === 'downloading').length)

  const handleCancel = async (id: string) => {
    const accessToken = auth.accessToken()
    if (!accessToken) {
      setActionError('Your session expired. Please sign in again.')
      return
    }

    try {
      setActionError(null)
      await downloadService.cancel(accessToken, id)
      await refetch()
    } catch (error) {
      setActionError(error instanceof Error ? error.message : 'Failed to cancel download')
    }
  }

  const handleAddSample = async () => {
    const accessToken = auth.accessToken()
    if (!accessToken) {
      setActionError('Your session expired. Please sign in again.')
      return
    }

    const sampleInput: DownloadCreateInput = {
      sourceType: 'http',
      source: 'https://example.com/sample-media.mkv',
      title: 'Sample download',
    }
    try {
      setActionError(null)
      await downloadService.create(accessToken, sampleInput)
      await refetch()
    } catch (error) {
      setActionError(error instanceof Error ? error.message : 'Failed to create download')
    }
  }

  return (
    <section class="space-y-8" data-testid="downloads-page">
      {/* Header */}
      <div class="animate-stagger space-y-6">
        <div class="flex items-center justify-between">
          <div>
            <h1 class="text-2xl font-semibold text-fg">Downloads</h1>
            <p class="text-sm text-muted-fg mt-1">Manage your active transfers and queue</p>
          </div>
          <div class="flex items-center gap-2">
            <Button variant="primary" size="sm" onClick={handleAddSample}>
              <Plus class="h-4 w-4" />
              Add Download
            </Button>
            <Button variant="subtle" size="sm" onClick={() => refetch()}>
              Refresh
            </Button>
          </div>
        </div>

        {/* Metrics */}
        <div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
          <MetricCard
            icon={Download}
            label="Active"
            value={String(downloadingCount())}
            detail="downloading now"
            tone="accent"
          />
          <MetricCard
            icon={Zap}
            label="Throughput"
            value={activeDownloads().length > 0 ? `${totalThroughput().toFixed(1)} MB/s` : '0 MB/s'}
            detail="combined speed"
          />
          <MetricCard
            icon={Activity}
            label="Stalled"
            value={String(stalledCount())}
            detail="need attention"
            tone="secondary"
          />
          <MetricCard
            icon={TimerReset}
            label="Queued"
            value={String(queuedCount())}
            detail="waiting"
          />
        </div>
      </div>

      {/* Downloads Grid */}
      <Show when={activeDownloadsData.loading && activeDownloads().length === 0}>
        <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <For each={Array.from({ length: 6 }, (_, i) => i)}>{() => <Skeleton class="h-40" />}</For>
        </div>
      </Show>

      <Show
        when={activeDownloads().length > 0}
        fallback={
          <Card>
            <CardContent class="py-12">
              <EmptyState
                title="No active downloads"
                description="Add a magnet link, torrent, or direct download to get started."
              />
            </CardContent>
          </Card>
        }
      >
        <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <For each={activeDownloads()}>
            {(job) => (
              <DownloadCard
                job={job}
                onCancel={() => handleCancel(job.id)}
              />
            )}
          </For>
        </div>
      </Show>

      {/* Error State */}
      <Show when={actionError() || activeDownloadsData.error}>
        <div class="flex items-center justify-between rounded-xl bg-danger/15 px-4 py-3 text-sm text-danger">
          <span>
            {actionError() ??
              (activeDownloadsData.error instanceof Error
                ? activeDownloadsData.error.message
                : 'Failed to load downloads')}
          </span>
          <Button variant="secondary" size="sm" onClick={() => refetch()}>
            Retry
          </Button>
        </div>
      </Show>
    </section>
  )
}
