import {
  Subtitle2,
  Caption1,
  Button,
  ProgressBar,
  makeStyles,
  mergeClasses,
  tokens,
  shorthands
} from '@fluentui/react-components'
import { ArrowDownloadRegular, ArrowClockwiseRegular, DismissRegular } from '@fluentui/react-icons'
import { useDownloads, type DownloadItem } from '../store/downloads'
import { queueSummaryOf } from '../lib/queueStats'
import { DownloadBar } from '../components/DownloadBar'
import { QueueItem } from '../components/QueueItem'
import { VirtualList } from '../components/VirtualList'
import { ScreenHeader, useScreenStyles } from '../components/ui/Screen'
import { EmptyState } from '../components/ui/EmptyState'
import { SPACE, ICON, META_SEP } from '../components/ui/tokens'

// Hoisted so the virtualizer gets stable function identities and doesn't churn its
// measurement/key cache on every render (PERF5).
const estimateRowSize = (): number => 100
const getItemKey = (item: DownloadItem): string => item.id
const renderQueueRow = (item: DownloadItem): React.JSX.Element => <QueueItem item={item} />

const useStyles = makeStyles({
  root: {
    // Fill the `fill` shell (L161) so the queue list below can flex to the
    // remaining height and scroll internally (it's virtualized), instead of the
    // whole page growing to thousands of rows.
    display: 'flex',
    flexDirection: 'column',
    // One section gap on every screen (UI2).
    gap: SPACE.section,
    flexGrow: 1,
    minHeight: 0
  },
  queueHeader: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between'
  },
  headerActions: {
    display: 'flex',
    gap: '8px'
  },
  summary: {
    display: 'flex',
    alignItems: 'center',
    gap: '12px',
    // List-row padding tier (UI3): snug vertical, cozy horizontal (was 10/14).
    padding: `${SPACE.snug} ${SPACE.cozy}`,
    backgroundColor: tokens.colorNeutralBackground1,
    ...shorthands.borderRadius(tokens.borderRadiusLarge),
    border: `1px solid ${tokens.colorNeutralStroke2}`
  },
  summaryBar: {
    flexGrow: 1
  },
  summaryText: {
    flexShrink: 0,
    color: tokens.colorNeutralForeground3,
    whiteSpace: 'nowrap'
  },
  listScroll: {
    flexGrow: 1,
    // The floor keeps the virtualized queue visible on a very short window (the
    // `fill` shell scrolls the overflow); above it, the list shrinks below its
    // content height so it, not the page, owns the scrolling.
    minHeight: '160px'
  }
})

export function DownloadsView(): React.JSX.Element {
  const styles = useStyles()
  const screen = useScreenStyles()
  const items = useDownloads((s) => s.items)
  const clearFinished = useDownloads((s) => s.clearFinished)
  const retryAll = useDownloads((s) => s.retryAll)
  const cancelAll = useDownloads((s) => s.cancelAll)

  const summary = queueSummaryOf(items)
  const hasFinished = items.some(
    (i) => i.status === 'completed' || i.status === 'error' || i.status === 'canceled'
  )
  // The header count is the live queue (work not yet finished), not the whole
  // list -- completed/canceled/error rows linger until "Clear finished" (L11).
  const queueCount = items.filter(
    (i) =>
      i.status === 'downloading' ||
      i.status === 'queued' ||
      i.status === 'paused' ||
      i.status === 'saved'
  ).length
  // Cancelable = the items with a live/pending run (downloading + queued); this is
  // exactly what "Cancel all" acts on (UX15).
  const cancelable = items.filter((i) => i.status === 'downloading' || i.status === 'queued').length

  return (
    <div className={screen.fill}>
      <div className={mergeClasses(styles.root, screen.width)}>
        <ScreenHeader title="Downloads" description="Fetch a video, playlist, or channel by URL." />

        <DownloadBar />

        {summary.active && (
          <div className={styles.summary}>
            <ProgressBar
              className={styles.summaryBar}
              value={summary.progress}
              thickness="large"
              aria-label="Overall download progress"
            />
            <Caption1 className={styles.summaryText}>
              {summary.downloading} downloading
              {summary.queued ? `, ${summary.queued} queued` : ''}
              {summary.speedLabel ? `${META_SEP}${summary.speedLabel}` : ''}
              {summary.etaLabel ? `${META_SEP}~${summary.etaLabel} left` : ''}
            </Caption1>
          </div>
        )}

        <div className={styles.queueHeader}>
          <Subtitle2 as="h2">Queue ({queueCount})</Subtitle2>
          <div className={styles.headerActions}>
            {summary.failed > 0 && (
              <Button
                size="small"
                appearance="subtle"
                icon={<ArrowClockwiseRegular />}
                onClick={retryAll}
              >
                Retry all failed ({summary.failed})
              </Button>
            )}
            {cancelable > 0 && (
              <Button
                size="small"
                appearance="subtle"
                icon={<DismissRegular />}
                onClick={cancelAll}
              >
                Cancel all ({cancelable})
              </Button>
            )}
            {hasFinished && (
              <Button size="small" appearance="subtle" onClick={clearFinished}>
                Clear finished
              </Button>
            )}
          </div>
        </div>

        {items.length === 0 ? (
          <EmptyState
            icon={<ArrowDownloadRegular fontSize={ICON.hero} />}
            message="Nothing queued yet. Paste a URL above, then click Download."
          />
        ) : (
          <VirtualList
            items={items}
            className={styles.listScroll}
            gap={10}
            overscan={6}
            estimateSize={estimateRowSize}
            getKey={getItemKey}
            renderItem={renderQueueRow}
          />
        )}
      </div>
    </div>
  )
}
