import { useState } from 'react';
import { useTranslation } from 'react-i18next';

import {
  type DisplaySurfaceHint,
  getPresetParams,
  getScreenShareSettings,
  PRESET_ORDER,
  type ScreenSharePreset,
  updateScreenShareSettings,
} from '../lib/screenShareSettings';
import {
  MonitorShareIcon,
  SpinnerIcon,
  XIcon,
} from './icons';

interface Props {
  open: boolean;
  onClose: () => void;
  onStart: (opts: {
    preset: ScreenSharePreset;
    displaySurface: DisplaySurfaceHint;
    framerate: number | null;
  }) => Promise<void>;
}

const FRAMERATE_OPTIONS: ReadonlyArray<{ value: number | null; label: string }> = [
  { value: null, label: 'Preset-Standard' },
  { value: 15, label: '15 fps' },
  { value: 30, label: '30 fps' },
  { value: 60, label: '60 fps' },
];

// Discord-style pre-share dialog. The OS still owns the final source picker
// (browser/OS limitation — only Chrome/Edge plus a native plugin can enumerate
// windows from JS), but we pre-filter with the `displaySurface` hint and lock
// in quality + framerate up-front so the user doesn't have to re-open the
// system picker to adjust them mid-call.
export function ScreenShareDialog({ open, onClose, onStart }: Props) {
  const { t } = useTranslation(['app']);
  const initial = getScreenShareSettings();
  const [surface, setSurface] = useState<DisplaySurfaceHint>(initial.displaySurface);
  const [preset, setPreset] = useState<ScreenSharePreset>(initial.preset);
  const [framerate, setFramerate] = useState<number | null>(initial.framerateOverride);
  const [includeAudio, setIncludeAudio] = useState<boolean>(initial.includeSystemAudio);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  if (!open) return null;

  async function handleStart() {
    setBusy(true);
    setError(null);
    try {
      // Persist the audio choice alongside the other picker prefs so the
      // upstream startScreenShare picks it up on its settings read.
      updateScreenShareSettings({ includeSystemAudio: includeAudio });
      await onStart({ preset, displaySurface: surface, framerate });
      onClose();
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : 'screenshare failed');
    } finally {
      setBusy(false);
    }
  }

  const presetParams = getPresetParams(preset);
  const effectiveFps = framerate ?? presetParams.framerate;

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-label={t('app:call.share_dialog_title', { defaultValue: 'Bildschirm teilen' })}
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
      onClick={onClose}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        className="flex w-full max-w-lg flex-col overflow-hidden rounded-2xl border border-line bg-surface-3 shadow-xl"
      >
        <header className="flex items-center justify-between border-b border-line px-5 py-3">
          <div className="flex items-center gap-2">
            <MonitorShareIcon className="h-4 w-4 text-accent" />
            <h3 className="font-display text-sm font-semibold text-fg">
              {t('app:call.share_dialog_title', { defaultValue: 'Bildschirm teilen' })}
            </h3>
          </div>
          <button
            type="button"
            onClick={onClose}
            aria-label="Close"
            className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg text-fg-muted transition hover:bg-surface-2 hover:text-fg"
          >
            <XIcon className="h-4 w-4" />
          </button>
        </header>

        <div className="space-y-5 p-5">
          <div>
            <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-fg-muted">
              {t('app:call.share_surface', { defaultValue: 'Quelle' })}
            </p>
            <div className="grid grid-cols-3 gap-2">
              <SurfaceOption
                active={surface === null}
                onClick={() => setSurface(null)}
                label={t('app:call.share_any', { defaultValue: 'Alle anzeigen' })}
                sub={t('app:call.share_any_sub', { defaultValue: 'Bildschirm + Fenster' })}
              />
              <SurfaceOption
                active={surface === 'monitor'}
                onClick={() => setSurface('monitor')}
                label={t('app:call.share_monitor', { defaultValue: 'Bildschirm' })}
                sub={t('app:call.share_monitor_sub', { defaultValue: 'Ganzer Monitor' })}
              />
              <SurfaceOption
                active={surface === 'window'}
                onClick={() => setSurface('window')}
                label={t('app:call.share_window', { defaultValue: 'Fenster' })}
                sub={t('app:call.share_window_sub', { defaultValue: 'Einzelnes Fenster' })}
              />
            </div>
          </div>

          <div>
            <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-fg-muted">
              {t('app:call.share_quality', { defaultValue: 'Qualität' })}
            </p>
            <select
              value={preset}
              onChange={(e) => setPreset(e.target.value as ScreenSharePreset)}
              className="w-full rounded-lg border border-line bg-surface-2 px-3 py-2 text-sm text-fg focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/30"
            >
              {PRESET_ORDER.map((p) => (
                <option key={p} value={p}>
                  {getPresetParams(p).label} · ≤ {getPresetParams(p).bitrateKbps} kbps
                </option>
              ))}
            </select>
          </div>

          <div>
            <p className="mb-2 text-xs font-semibold uppercase tracking-wider text-fg-muted">
              {t('app:call.share_fps', { defaultValue: 'Bildrate' })}
            </p>
            <div className="flex flex-wrap gap-2">
              {FRAMERATE_OPTIONS.map((opt) => (
                <button
                  key={String(opt.value)}
                  type="button"
                  onClick={() => setFramerate(opt.value)}
                  className={
                    'cursor-pointer rounded-lg border px-3 py-1.5 text-xs font-medium transition ' +
                    (framerate === opt.value
                      ? 'border-accent bg-accent/15 text-accent'
                      : 'border-line bg-surface-2 text-fg hover:bg-surface')
                  }
                >
                  {opt.label}
                </button>
              ))}
            </div>
            <p className="mt-2 text-[11px] text-fg-muted">
              {t('app:call.share_fps_effective', {
                defaultValue: 'Effektiv: {{fps}} fps',
                fps: effectiveFps,
              })}
            </p>
          </div>

          <div>
            <label className="flex cursor-pointer items-start gap-2 rounded-lg border border-line bg-surface-2 px-3 py-2 text-xs hover:bg-surface">
              <input
                type="checkbox"
                checked={includeAudio}
                onChange={(e) => setIncludeAudio(e.target.checked)}
                className="mt-0.5 accent-accent"
              />
              <span className="min-w-0 flex-1">
                <span className="block font-semibold text-fg">
                  {t('app:call.share_system_audio', {
                    defaultValue: 'System-Sound mit übertragen',
                  })}
                </span>
                <span className="mt-0.5 block text-[11px] text-fg-muted">
                  {t('app:call.share_system_audio_hint', {
                    defaultValue:
                      '"Go Live" — Systemsound wird mitgesendet. Auf macOS braucht das extra Berechtigungen; wird sonst stumm geteilt.',
                  })}
                </span>
              </span>
            </label>
          </div>

          {error && (
            <p role="alert" className="text-sm text-rose-600 dark:text-rose-300">
              {error}
            </p>
          )}

          <p className="text-[11px] text-fg-muted">
            {t('app:call.share_hint', {
              defaultValue:
                'Nach "Teilen starten" öffnet das Betriebssystem den Quellen-Picker. Qualität + Bildrate werden bereits angewendet.',
            })}
          </p>
        </div>

        <footer className="flex items-center justify-end gap-2 border-t border-line bg-surface-2 px-5 py-3">
          <button
            type="button"
            onClick={onClose}
            className="cursor-pointer rounded-md border border-line bg-surface-3 px-3 py-2 text-sm text-fg transition hover:bg-surface-2"
          >
            {t('app:friends.action_cancel', { defaultValue: 'Abbrechen' })}
          </button>
          <button
            type="button"
            onClick={() => void handleStart()}
            disabled={busy}
            className="inline-flex cursor-pointer items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-semibold text-accent-fg transition hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-60"
          >
            {busy && <SpinnerIcon className="h-4 w-4" />}
            <span>
              {t('app:call.share_start', { defaultValue: 'Teilen starten' })}
            </span>
          </button>
        </footer>
      </div>
    </div>
  );
}

function SurfaceOption({
  active,
  onClick,
  label,
  sub,
}: {
  active: boolean;
  onClick: () => void;
  label: string;
  sub: string;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={
        'flex flex-col items-start gap-0.5 rounded-lg border p-2.5 text-left transition ' +
        (active
          ? 'border-accent bg-accent/10 text-fg'
          : 'border-line bg-surface-2 text-fg hover:bg-surface')
      }
    >
      <span className="text-xs font-semibold">{label}</span>
      <span className="text-[10px] text-fg-muted">{sub}</span>
    </button>
  );
}
