/**
 * The admin add form.
 *
 * Track and visibility are plain selects rather than a clever control because
 * the pairing rule between them is enforced by the API and the database, not
 * here — so the UI's job is to be legible, and disabling the option would only
 * hide a refusal the server is going to make anyway with a better message.
 */
import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import {
  LEARN_TRACKS,
  LEARN_TRACK_LABELS,
  LEARN_VISIBILITIES,
  type LearnTrack,
  type LearnVisibility,
} from '@pig/core';
import { api } from '@/lib/api';
import { Button, Input } from '@/components/ui';
import { FormField } from '@/components/ui/form-field';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import type { LearnResourceView } from './model';

export function AddResourceDialog({
  open,
  onOpenChange,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const queryClient = useQueryClient();
  const [track, setTrack] = useState<LearnTrack>('platform');
  const [visibility, setVisibility] = useState<LearnVisibility>('code');
  const [title, setTitle] = useState('');
  const [summary, setSummary] = useState('');
  const [url, setUrl] = useState('');
  const [minutes, setMinutes] = useState('');

  const create = useMutation({
    mutationFn: () => {
      const parsedMinutes = Number(minutes);
      return api<LearnResourceView>('/api/learn/resources', {
        method: 'POST',
        body: JSON.stringify({
          track,
          visibility,
          title: title.trim(),
          summary: summary.trim() || undefined,
          url: url.trim(),
          durationSeconds:
            minutes.trim() && Number.isFinite(parsedMinutes) && parsedMinutes > 0
              ? Math.round(parsedMinutes * 60)
              : undefined,
        }),
      });
    },
    onSuccess: async (created) => {
      await queryClient.invalidateQueries({ queryKey: ['learn'] });
      onOpenChange(false);
      setTitle('');
      setSummary('');
      setUrl('');
      setMinutes('');
      toast.success(`Added “${created.title}”.`);
    },
    onError: (error: unknown) => {
      toast.error(error instanceof Error ? error.message : 'Could not add that video.');
    },
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[90dvh] w-[calc(100vw-1.5rem)] max-w-lg overflow-y-auto">
        <DialogHeader>
          <DialogTitle>Add a video</DialogTitle>
          <DialogDescription>
            Paste a share link from video.karti.ai. Other hosts are rejected until they are added
            to the allowlist.
          </DialogDescription>
        </DialogHeader>
        <form
          className="flex min-w-0 flex-col gap-3"
          onSubmit={(event) => {
            event.preventDefault();
            create.mutate();
          }}
        >
          <FormField label="Share link">
            <Input
              id="learn-url"
              value={url}
              onChange={(event) => setUrl(event.target.value)}
              placeholder="https://video.karti.ai/s/…"
              autoComplete="off"
              spellCheck={false}
            />
          </FormField>
          <FormField label="Title">
            <Input
              id="learn-title"
              value={title}
              onChange={(event) => setTitle(event.target.value)}
            />
          </FormField>
          <FormField label="Summary">
            <Input
              id="learn-summary"
              value={summary}
              onChange={(event) => setSummary(event.target.value)}
              placeholder="What someone learns from it"
            />
          </FormField>
          <div className="grid min-w-0 gap-3 sm:grid-cols-2">
            <FormField label="Track">
              <NativeSelect
                id="learn-track"
                value={track}
                onChange={(value) => setTrack(value as LearnTrack)}
                options={LEARN_TRACKS.map((value) => ({
                  value,
                  label: LEARN_TRACK_LABELS[value],
                }))}
              />
            </FormField>
            <FormField label="Visibility">
              <NativeSelect
                id="learn-visibility"
                value={visibility}
                onChange={(value) => setVisibility(value as LearnVisibility)}
                options={LEARN_VISIBILITIES.map((value) => ({
                  value,
                  label: value === 'code' ? 'Anyone with the code' : 'Members only',
                }))}
              />
            </FormField>
          </div>
          <FormField label="Length in minutes">
            <Input
              id="learn-minutes"
              value={minutes}
              onChange={(event) => setMinutes(event.target.value)}
              inputMode="decimal"
              placeholder="Optional"
            />
          </FormField>
          <div className="flex min-w-0 flex-col gap-2 pt-1 sm:flex-row sm:justify-end">
            <Button type="button" variant="ghost" onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button
              type="submit"
              variant="primary"
              disabled={create.isPending || !url.trim() || !title.trim()}
            >
              {create.isPending ? 'Adding…' : 'Add video'}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function NativeSelect({
  value,
  onChange,
  options,
  ...field
}: {
  id?: string;
  'aria-label'?: string;
  'aria-describedby'?: string;
  value: string;
  onChange: (value: string) => void;
  options: { value: string; label: string }[];
}) {
  return (
    <select
      {...field}
      value={value}
      onChange={(event) => onChange(event.target.value)}
      className="h-11 w-full min-w-0 rounded-lg border border-border bg-surface px-3 text-base text-fg focus-visible:border-accent"
    >
      {options.map((option) => (
        <option key={option.value} value={option.value}>
          {option.label}
        </option>
      ))}
    </select>
  );
}
