import {
  Field,
  Input,
  SpinButton,
  Switch,
  Button,
  Card,
  Subtitle2
} from '@fluentui/react-components'
import { FolderRegular, ArrowDownloadRegular } from '@fluentui/react-icons'
import { type MediaKind } from '@shared/ipc'
import { useSettings } from '../../store/settings'
import { useDownloads } from '../../store/downloads'
import { QUALITY_OPTIONS } from '../../lib/qualityOptions'
import { Select } from '../../components/Select'
import { SegmentedControl } from '../../components/ui/SegmentedControl'
import { useSettingsStyles } from './settingsStyles'

export function DownloadsCard(): React.JSX.Element {
  const styles = useSettingsStyles()
  const videoFolder = useSettings((s) => s.videoFolder)
  const audioFolder = useSettings((s) => s.audioFolder)
  const chooseFolder = useSettings((s) => s.chooseFolder)
  const clearFolder = useSettings((s) => s.clearFolder)
  const defaultKind = useSettings((s) => s.defaultKind)
  const defaultVideoQuality = useSettings((s) => s.defaultVideoQuality)
  const defaultAudioQuality = useSettings((s) => s.defaultAudioQuality)
  const maxConcurrent = useSettings((s) => s.maxConcurrent)
  const watchClipboard = useSettings((s) => s.watchClipboard)
  const notifyOnComplete = useSettings((s) => s.notifyOnComplete)
  const minimizeToTray = useSettings((s) => s.minimizeToTray)
  const launchAtStartup = useSettings((s) => s.launchAtStartup)
  const update = useSettings((s) => s.update)

  const formatQuality = defaultKind === 'audio' ? defaultAudioQuality : defaultVideoQuality

  function onKindSelect(kind: MediaKind): void {
    update({ defaultKind: kind })
  }

  function onQualitySelect(quality: string): void {
    update(
      defaultKind === 'audio' ? { defaultAudioQuality: quality } : { defaultVideoQuality: quality }
    )
  }

  return (
    <Card className={styles.card}>
      <div className={styles.sectionHeader}>
        <ArrowDownloadRegular className={styles.sectionIcon} />
        <Subtitle2 as="h3">Downloads</Subtitle2>
      </div>

      <Field
        label="Video folder"
        hint="Where video downloads are saved. Leave blank to use Documents\Video."
      >
        <div className={styles.folderRow}>
          <Input
            className={styles.folderInput}
            value={videoFolder}
            placeholder="Documents\Video (default)"
            contentBefore={<FolderRegular />}
            onChange={(_, d) => update({ videoFolder: d.value })}
          />
          <Button icon={<FolderRegular />} onClick={() => chooseFolder('videoFolder')}>
            Browse…
          </Button>
          {videoFolder && (
            <Button appearance="subtle" onClick={() => clearFolder('videoFolder')}>
              Reset
            </Button>
          )}
        </div>
      </Field>

      <Field
        label="Audio folder"
        hint="Where audio downloads are saved. Leave blank to use Documents\Audio."
      >
        <div className={styles.folderRow}>
          <Input
            className={styles.folderInput}
            value={audioFolder}
            placeholder="Documents\Audio (default)"
            contentBefore={<FolderRegular />}
            onChange={(_, d) => update({ audioFolder: d.value })}
          />
          <Button icon={<FolderRegular />} onClick={() => chooseFolder('audioFolder')}>
            Browse…
          </Button>
          {audioFolder && (
            <Button appearance="subtle" onClick={() => clearFolder('audioFolder')}>
              Reset
            </Button>
          )}
        </div>
      </Field>

      <Field label="Default format">
        <div className={styles.formatRow}>
          <SegmentedControl<MediaKind>
            value={defaultKind}
            options={[
              { value: 'video', label: 'Video' },
              { value: 'audio', label: 'Audio' }
            ]}
            onChange={onKindSelect}
            ariaLabel="Default download type"
          />
          <Select
            className={styles.formatQuality}
            value={formatQuality}
            options={QUALITY_OPTIONS[defaultKind].map((q) => ({ value: q, label: q }))}
            onChange={onQualitySelect}
          />
        </div>
      </Field>

      <Field
        label="Maximum simultaneous downloads"
        hint="How many downloads run at once. 2-3 is a good balance."
      >
        <SpinButton
          value={maxConcurrent}
          min={1}
          max={5}
          onChange={(_, d) => {
            const v = d.value ?? Number(d.displayValue)
            if (typeof v === 'number' && Number.isFinite(v)) {
              update({ maxConcurrent: Math.min(5, Math.max(1, Math.round(v))) })
              // Raising the cap should start queued items right away.
              useDownloads.getState().pump()
            }
          }}
        />
      </Field>

      <Field
        label="Detect links from clipboard"
        hint="When AeroFetch gains focus, offer a video link you've just copied."
      >
        <Switch
          checked={watchClipboard}
          onChange={(_, d) => update({ watchClipboard: d.checked })}
        />
      </Field>

      <Field
        label="Notify when downloads finish"
        hint="Shows a native Windows notification when a download completes or fails."
      >
        <Switch
          checked={notifyOnComplete}
          onChange={(_, d) => update({ notifyOnComplete: d.checked })}
        />
      </Field>

      <Field
        label="Keep running in the tray"
        hint="Closing the window minimizes to the system tray instead of quitting, so downloads and watched-channel syncing keep running."
      >
        <Switch
          checked={minimizeToTray}
          onChange={(_, d) => update({ minimizeToTray: d.checked })}
        />
      </Field>

      <Field
        label="Start with Windows"
        hint="Launch AeroFetch automatically when you sign in -- useful with auto-download so watched channels stay current in the background."
      >
        <Switch
          checked={launchAtStartup}
          onChange={(_, d) => update({ launchAtStartup: d.checked })}
        />
      </Field>
    </Card>
  )
}
