import {
  Field,
  Input,
  Switch,
  SpinButton,
  Button,
  Card,
  Subtitle2,
  Spinner
} from '@fluentui/react-components'
import { GlobeRegular } from '@fluentui/react-icons'
import { useSettings } from '../../store/settings'
import { useSettingsStyles } from './settingsStyles'
import { useNetworkCard } from './useNetworkCard'

export function NetworkCard(): React.JSX.Element {
  const styles = useSettingsStyles()
  const proxy = useSettings((s) => s.proxy)
  const rateLimit = useSettings((s) => s.rateLimit)
  const sleepRequests = useSettings((s) => s.sleepRequests)
  const sleepInterval = useSettings((s) => s.sleepInterval)
  const maxSleepInterval = useSettings((s) => s.maxSleepInterval)
  const useAria2c = useSettings((s) => s.useAria2c)
  const aria2cConnections = useSettings((s) => s.aria2cConnections)
  const youtubePlayerClient = useSettings((s) => s.youtubePlayerClient)
  const youtubePoToken = useSettings((s) => s.youtubePoToken)
  const update = useSettings((s) => s.update)

  // View-model hook owns the PO-token minting state + IPC (L93/CC13), plus the
  // aria2c-presence probe that keeps the toggle below honest.
  const { mintingPot, potHint, clearPotHint, mintPoToken, aria2cAvailable } = useNetworkCard()
  // Only treat aria2c as missing once the probe has actually resolved false, so a
  // slow check doesn't briefly disable a working toggle.
  const aria2cMissing = aria2cAvailable === false

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

      <Field
        label="Proxy"
        hint="HTTP/HTTPS/SOCKS proxy URL, e.g. socks5://127.0.0.1:1080. Leave blank to use the system default."
      >
        <Input
          type="password"
          value={proxy}
          placeholder="socks5://127.0.0.1:1080"
          onChange={(_, d) => update({ proxy: d.value })}
        />
      </Field>

      <Field
        label="Rate limit"
        hint="Caps download speed (e.g. 500K or 2M). Leave blank for unlimited."
      >
        <Input
          value={rateLimit}
          placeholder="2M"
          onChange={(_, d) => update({ rateLimit: d.value })}
        />
      </Field>

      <Field
        label="Pause between requests"
        hint="Seconds yt-dlp waits between requests (--sleep-requests). The key setting for downloading a whole channel without YouTube rate-limiting you (the &quot;unavailable, try again later&quot; / 403 errors). Try 2-5s for large channels. 0 = off."
      >
        <SpinButton
          value={sleepRequests}
          min={0}
          max={300}
          onChange={(_, d) => {
            const v = d.value ?? Number(d.displayValue)
            if (typeof v === 'number' && Number.isFinite(v)) {
              update({ sleepRequests: Math.min(300, Math.max(0, Math.round(v))) })
            }
          }}
        />
      </Field>

      <Field
        label="Pause before each download (min)"
        hint="Minimum seconds to wait before starting each download (--sleep-interval). Combined with the max below, yt-dlp waits a random amount in that range. 0 = off."
      >
        <SpinButton
          value={sleepInterval}
          min={0}
          max={300}
          onChange={(_, d) => {
            const v = d.value ?? Number(d.displayValue)
            if (typeof v === 'number' && Number.isFinite(v)) {
              update({ sleepInterval: Math.min(300, Math.max(0, Math.round(v))) })
            }
          }}
        />
      </Field>

      <Field
        label="Pause before each download (max)"
        hint="Maximum seconds for the random pre-download pause (--max-sleep-interval). Only used when it's set above the minimum above; otherwise the minimum is used as a fixed pause."
      >
        <SpinButton
          value={maxSleepInterval}
          min={0}
          max={300}
          disabled={sleepInterval <= 0}
          onChange={(_, d) => {
            const v = d.value ?? Number(d.displayValue)
            if (typeof v === 'number' && Number.isFinite(v)) {
              update({ maxSleepInterval: Math.min(300, Math.max(0, Math.round(v))) })
            }
          }}
        />
      </Field>

      <Field
        label="Use aria2c downloader"
        hint="Multi-connection downloads for faster speeds on supported sites. Falls back to the standard downloader if the accelerator isn't available."
        validationState={aria2cMissing ? 'warning' : 'none'}
        validationMessage={
          aria2cMissing
            ? "aria2c isn't included in this build, so this setting has no effect."
            : undefined
        }
      >
        <Switch
          checked={useAria2c}
          disabled={aria2cMissing}
          onChange={(_, d) => update({ useAria2c: d.checked })}
        />
      </Field>

      {useAria2c && !aria2cMissing && (
        <Field
          label="aria2c connections"
          hint="Parallel connections per download (1–16). More can be faster on throttled connections; fewer is gentler on servers."
        >
          <SpinButton
            value={aria2cConnections}
            min={1}
            max={16}
            onChange={(_, d) => {
              const v = d.value ?? Number(d.displayValue)
              if (typeof v === 'number' && Number.isFinite(v)) {
                update({ aria2cConnections: Math.min(16, Math.max(1, Math.round(v))) })
              }
            }}
          />
        </Field>
      )}

      <Field
        label="YouTube client (advanced)"
        hint="Override how AeroFetch identifies itself to YouTube when downloads start failing. Try web_safari, tv, or mweb. Leave blank for the automatic default."
      >
        <datalist id="yt-client-list">
          {['web', 'web_safari', 'web_embedded', 'mweb', 'tv', 'ios', 'android'].map((c) => (
            <option key={c} value={c} />
          ))}
        </datalist>
        <Input
          value={youtubePlayerClient}
          placeholder="web_safari"
          list="yt-client-list"
          onChange={(_, d) => update({ youtubePlayerClient: d.value })}
        />
      </Field>

      <Field
        label="YouTube PO Token (advanced)"
        hint={
          potHint ??
          'A token that helps get past YouTube\'s bot check. Click "Fetch" to grab one automatically, or paste it manually. Signing in with cookies (above) is usually the easier fix.'
        }
      >
        <div className={styles.folderRow}>
          <Input
            type="password"
            style={{ flexGrow: 1 }}
            value={youtubePoToken}
            placeholder="Optional -- paste a token"
            onChange={(_, d) => {
              update({ youtubePoToken: d.value })
              clearPotHint()
            }}
          />
          <Button
            size="small"
            disabled={mintingPot}
            icon={mintingPot ? <Spinner size="tiny" /> : undefined}
            onClick={mintPoToken}
          >
            {mintingPot ? 'Fetching…' : 'Fetch'}
          </Button>
        </div>
      </Field>
    </Card>
  )
}
