import { Clock, Download, Pause, Play, Trash2, X } from 'lucide-solid'
import { Show, splitProps, type JSX } from 'solid-js'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { CircularProgress, Progress } from '@/components/ui/progress'
import type { DownloadJob } from '@/types/domain'
import { cn } from '@/utils/cn'

export interface DownloadCardProps extends JSX.HTMLAttributes<HTMLDivElement> {
  job: DownloadJob
  onCancel?: () => void
  onPause?: () => void
  onResume?: () => void
}

const statusConfig: Record<DownloadJob['status'], { label: string; variant: 'neutral' | 'accent' | 'success' | 'warning' | 'danger' }> = {
  queued: { label: 'Queued', variant: 'neutral' },
  downloading: { label: 'Downloading', variant: 'accent' },
  stalled: { label: 'Stalled', variant: 'warning' },
  completed: { label: 'Completed', variant: 'success' },
  failed: { label: 'Failed', variant: 'danger' },
}

const formatSpeed = (mbps: number): string => {
  if (mbps >= 100) return `${mbps.toFixed(0)} MB/s`
  if (mbps >= 10) return `${mbps.toFixed(1)} MB/s`
  return `${mbps.toFixed(2)} MB/s`
}

const formatEta = (minutes: number): string => {
  if (minutes >= 60) {
    const hours = Math.floor(minutes / 60)
    const mins = minutes % 60
    return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`
  }
  return `${minutes}m`
}

export const DownloadCard = (props: DownloadCardProps) => {
  const [local, rest] = splitProps(props, ['class', 'job', 'onCancel', 'onPause', 'onResume'])

  const config = () => statusConfig[local.job.status]
  const isActive = () => ['downloading', 'queued'].includes(local.job.status)
  const isStalled = () => local.job.status === 'stalled'
  const isCompleted = () => local.job.status === 'completed'
  const isFailed = () => local.job.status === 'failed'

  return (
    <div
      class={cn(
        'rounded-2xl bg-surface-container overflow-hidden',
        'border border-outline-variant/15',
        'transition-all duration-300',
        'hover:bg-surface-high hover:shadow-ambient',
        local.class,
      )}
      {...rest}
    >
      <div class="p-5 space-y-4">
        {/* Header */}
        <div class="flex items-start justify-between gap-4">
          <div class="flex-1 min-w-0 space-y-1">
            <h4 class="text-sm font-semibold text-fg line-clamp-1">{local.job.title}</h4>
            <div class="flex items-center gap-2">
              <Badge variant={config().variant}>{config().label}</Badge>
              <span class="text-[10px] font-semibold uppercase tracking-widest text-muted-fg">
                {local.job.sourceType}
              </span>
            </div>
          </div>

          {/* Status Indicator */}
          <Show when={isActive() || isStalled()}>
            <CircularProgress
              value={local.job.progressPercent}
              size={44}
              strokeWidth={3}
              variant={isStalled() ? 'warning' : 'accent'}
            />
          </Show>

          <Show when={isCompleted()}>
            <div class="flex h-11 w-11 items-center justify-center rounded-full bg-success/20">
              <Download class="h-5 w-5 text-success" />
            </div>
          </Show>

          <Show when={isFailed()}>
            <div class="flex h-11 w-11 items-center justify-center rounded-full bg-danger/20">
              <X class="h-5 w-5 text-danger" />
            </div>
          </Show>
        </div>

        {/* Progress Bar */}
        <Show when={isActive() || isStalled()}>
          <Progress
            value={local.job.progressPercent}
            variant={isStalled() ? 'warning' : 'accent'}
            size="sm"
          />
        </Show>

        {/* Stats */}
        <Show when={isActive()}>
          <div class="flex items-center gap-6 text-xs text-muted-fg">
            <Show when={local.job.downloadSpeedMbps > 0}>
              <span class="flex items-center gap-1.5">
                <Download class="h-3.5 w-3.5" />
                {formatSpeed(local.job.downloadSpeedMbps)}
              </span>
            </Show>
            <Show when={local.job.etaMinutes > 0}>
              <span class="flex items-center gap-1.5">
                <Clock class="h-3.5 w-3.5" />
                {formatEta(local.job.etaMinutes)} left
              </span>
            </Show>
            <span class="ml-auto font-semibold text-fg tabular-nums">
              {local.job.progressPercent}%
            </span>
          </div>
        </Show>

        {/* Stalled Warning */}
        <Show when={isStalled()}>
          <div class="rounded-lg bg-warning/10 px-3 py-2 text-xs text-warning">
            Download stalled. Check connection or try restarting.
          </div>
        </Show>

        {/* Failed Error */}
        <Show when={isFailed()}>
          <div class="rounded-lg bg-danger/10 px-3 py-2 text-xs text-danger">
            Download failed. Please try again or check the source.
          </div>
        </Show>

        {/* Actions */}
        <Show when={local.onCancel || local.onPause || local.onResume}>
          <div class="flex items-center gap-2 pt-2">
            <Show when={isActive() && local.onPause}>
              {(onPause) => (
                <Button variant="ghost" size="sm" onClick={onPause()}>
                  <Pause class="h-3.5 w-3.5" />
                  Pause
                </Button>
              )}
            </Show>

            <Show when={local.job.status === 'queued' && local.onResume}>
              {(onResume) => (
                <Button variant="ghost" size="sm" onClick={onResume()}>
                  <Play class="h-3.5 w-3.5" />
                  Start
                </Button>
              )}
            </Show>

            <Show when={local.onCancel}>
              {(onCancel) => (
                <Button variant="ghost" size="sm" onClick={onCancel()} class="text-danger hover:text-danger hover:bg-danger/10">
                  <Trash2 class="h-3.5 w-3.5" />
                  Cancel
                </Button>
              )}
            </Show>
          </div>
        </Show>
      </div>
    </div>
  )
}
