import { useEffect, useState } from 'react';
import { api } from '@/api/client';
import type { AvailableProject } from '@/api/types';
import { sessionEvents } from '@/hooks/sessionEvents';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onAdded: () => void;
}

export function AddProjectModal({ open, onOpenChange, onAdded }: Props) {
  const [available, setAvailable] = useState<AvailableProject[] | null>(null);
  const [customPath, setCustomPath] = useState('');
  const [error, setError] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);

  useEffect(() => {
    if (!open) return;
    setError(null);
    setCustomPath('');
    setAvailable(null);
    api.projects
      .available()
      .then(setAvailable)
      .catch((err) =>
        setError(err instanceof Error ? err.message : 'failed to list available projects')
      );
  }, [open]);

  async function add(path: string) {
    setBusy(true);
    setError(null);
    try {
      const created = await api.projects.add({ path });
      sessionEvents.emit({ type: 'project_created', project: created });
      onAdded();
      onOpenChange(false);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'failed to add');
    } finally {
      setBusy(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Add project</DialogTitle>
          <DialogDescription>
            Pick from detected repos in /opt or type a path.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-3">
          <div className="rounded-md border max-h-64 overflow-y-auto">
            {available === null && (
              <div className="px-3 py-2 text-sm text-muted-foreground">Loading…</div>
            )}
            {available && available.length === 0 && (
              <div className="px-3 py-2 text-sm text-muted-foreground">
                No undiscovered repos in /opt.
              </div>
            )}
            {available?.map((p) => (
              <button
                key={p.path}
                disabled={busy}
                onClick={() => void add(p.path)}
                className="w-full text-left px-3 py-2 hover:bg-muted disabled:opacity-50 border-b last:border-b-0"
              >
                <div className="text-sm font-medium">{p.name}</div>
                <div className="text-xs text-muted-foreground font-mono">{p.path}</div>
              </button>
            ))}
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="custom-path">Custom path</Label>
            <div className="flex gap-2">
              <Input
                id="custom-path"
                placeholder="/opt/some-repo"
                value={customPath}
                onChange={(e) => setCustomPath(e.target.value)}
                disabled={busy}
              />
              <Button
                onClick={() => void add(customPath.trim())}
                disabled={busy || !customPath.trim()}
              >
                Add
              </Button>
            </div>
          </div>

          {error && (
            <div className="text-sm text-destructive">{error}</div>
          )}
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={busy}>
            Cancel
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
