import { useState } from 'react';
import { X } from 'lucide-react';
import { toast } from 'sonner';
import { z } from 'zod';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Muted } from '@/components/ui/typography';
import { useInviteMembers } from '@/hooks/use-member-management';

const emailSchema = z.string().email();

function EmailChip({
  email,
  onRemove,
}: {
  email: string;
  onRemove: () => void;
}) {
  return (
    <span className="bg-secondary text-secondary-foreground inline-flex items-center gap-1 rounded-md py-0.5 pl-2 pr-1 text-xs">
      {email}
      <Button
        type="button"
        variant="ghost"
        size="icon-sm"
        onClick={onRemove}
        aria-label={`Remove ${email}`}
        className="text-muted-foreground hover:text-foreground size-5"
      >
        <X className="size-3" />
      </Button>
    </span>
  );
}

export function AddMembersDialog({
  networkId,
  open,
  onOpenChange,
}: {
  networkId: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const [emails, setEmails] = useState<string[]>([]);
  const [input, setInput] = useState('');
  const [error, setError] = useState<string | null>(null);
  const inviteMembers = useInviteMembers(networkId);

  const reset = () => {
    setEmails([]);
    setInput('');
    setError(null);
  };

  const handleOpenChange = (next: boolean) => {
    if (!next) reset();
    onOpenChange(next);
  };

  // Commits the current input as a chip. Returns the next list of emails so
  // callers (like submit) can act on the freshly-committed value.
  const commit = (raw: string): string[] | null => {
    const trimmed = raw.trim().replace(/,$/, '').trim();
    if (!trimmed) return emails;
    if (!emailSchema.safeParse(trimmed).success) {
      setError(`"${trimmed}" doesn't look like a valid email.`);
      return null;
    }
    if (emails.includes(trimmed)) {
      setInput('');
      return emails;
    }
    const next = [...emails, trimmed];
    setEmails(next);
    setInput('');
    setError(null);
    return next;
  };

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter' || e.key === ',') {
      e.preventDefault();
      commit(input);
    } else if (e.key === 'Backspace' && input === '' && emails.length > 0) {
      setEmails(emails.slice(0, -1));
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    const next = commit(input);
    if (next === null) return; // invalid pending input
    if (next.length === 0) return;

    inviteMembers.mutate(next, {
      onSuccess: () => {
        toast.success(
          next.length === 1
            ? `Invited ${next[0]}`
            : `Invited ${next.length} people`,
        );
        handleOpenChange(false);
      },
    });
  };

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Add members</DialogTitle>
          <DialogDescription>
            Enter email addresses to add people to this network.
          </DialogDescription>
        </DialogHeader>
        <form onSubmit={handleSubmit}>
          <div className="border-input focus-within:border-ring focus-within:ring-ring/50 flex flex-wrap items-center gap-1.5 rounded-md border px-2 py-1.5 transition-colors focus-within:ring-[3px]">
            {emails.map((email) => (
              <EmailChip
                key={email}
                email={email}
                onRemove={() => setEmails(emails.filter((x) => x !== email))}
              />
            ))}
            <Input
              type="email"
              value={input}
              onChange={(e) => {
                setInput(e.target.value);
                if (error) setError(null);
              }}
              onKeyDown={handleKeyDown}
              onBlur={() => commit(input)}
              placeholder={
                emails.length === 0 ? 'name@example.com' : 'Add another…'
              }
              className="h-7 min-w-[8rem] flex-1 border-0 px-1 shadow-none focus-visible:ring-0"
              autoFocus
            />
          </div>
          {error ? (
            <p className="text-destructive mt-1.5 text-xs">{error}</p>
          ) : (
            <Muted className="mt-1.5 text-xs">
              Press Enter or comma to add each email.
            </Muted>
          )}
          <DialogFooter className="mt-4">
            <Button
              type="button"
              variant="outline"
              onClick={() => handleOpenChange(false)}
            >
              Cancel
            </Button>
            <Button
              type="submit"
              disabled={
                inviteMembers.isPending ||
                (emails.length === 0 && input.trim() === '')
              }
            >
              {inviteMembers.isPending ? 'Adding…' : 'Add members'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
