'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus, X, Check } from 'lucide-react';

import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { cn } from '@/lib/utils';

interface Tag {
  id: string;
  name: string;
  color: string;
}

export interface InlineTagEditorProps {
  /** PUT endpoint for replacing the entity's tag list - body shape `{ tagIds: string[] }`. */
  endpoint: string;
  currentTags: Tag[];
  /** TanStack Query key to invalidate after a successful change. */
  invalidateKey: readonly unknown[];
  /** Hide the "+ Add tag" button (read-only mode). */
  readOnly?: boolean;
}

export function InlineTagEditor({
  endpoint,
  currentTags,
  invalidateKey,
  readOnly,
}: InlineTagEditorProps) {
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);

  const { data: allTags } = useQuery<{ data: Tag[] }>({
    queryKey: ['tags'],
    queryFn: () => apiFetch('/api/v1/tags'),
    staleTime: 60_000,
    enabled: open,
  });

  const setTags = useMutation({
    mutationFn: (tagIds: string[]) => apiFetch(endpoint, { method: 'PUT', body: { tagIds } }),
    onSuccess: () => qc.invalidateQueries({ queryKey: invalidateKey }),
    onError: (err) => toastError(err),
  });

  function toggleTag(tagId: string) {
    const has = currentTags.some((t) => t.id === tagId);
    const nextIds = has
      ? currentTags.filter((t) => t.id !== tagId).map((t) => t.id)
      : [...currentTags.map((t) => t.id), tagId];
    setTags.mutate(nextIds);
  }

  function removeTag(tagId: string) {
    setTags.mutate(currentTags.filter((t) => t.id !== tagId).map((t) => t.id));
  }

  return (
    <div className="flex flex-wrap items-center gap-1.5">
      {currentTags.map((t) => (
        <span
          key={t.id}
          className="group inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium"
          style={{ backgroundColor: `${t.color}20`, color: t.color }}
        >
          {t.name}
          {!readOnly && (
            <button
              type="button"
              onClick={() => removeTag(t.id)}
              className="opacity-0 group-hover:opacity-100 transition-opacity hover:opacity-100"
              aria-label={`Remove tag ${t.name}`}
            >
              <X className="h-3 w-3" />
            </button>
          )}
        </span>
      ))}

      {!readOnly && (
        <Popover open={open} onOpenChange={setOpen}>
          <PopoverTrigger asChild>
            <Button
              type="button"
              size="sm"
              variant="ghost"
              className="h-6 px-2 text-xs text-muted-foreground hover:text-foreground"
            >
              <Plus className="h-3 w-3 mr-1" aria-hidden />
              {currentTags.length === 0 ? 'Add tag' : 'Add'}
            </Button>
          </PopoverTrigger>
          <PopoverContent className="w-64 p-0" align="start">
            <div className="max-h-64 overflow-y-auto py-1">
              {!allTags && <div className="px-3 py-2 text-xs text-muted-foreground">Loading…</div>}
              {allTags?.data.length === 0 && (
                <div className="px-3 py-2 text-xs text-muted-foreground">
                  No tags defined yet. Create some in Admin → Tags.
                </div>
              )}
              {allTags?.data.map((t) => {
                const checked = currentTags.some((c) => c.id === t.id);
                return (
                  <button
                    key={t.id}
                    type="button"
                    onClick={() => toggleTag(t.id)}
                    className={cn(
                      'flex items-center gap-2 w-full px-3 py-1.5 text-sm text-left hover:bg-muted/60',
                    )}
                  >
                    <span
                      className="inline-block w-2.5 h-2.5 rounded-full shrink-0"
                      style={{ backgroundColor: t.color }}
                    />
                    <span className="flex-1 truncate">{t.name}</span>
                    {checked && <Check className="h-3.5 w-3.5 text-primary" aria-hidden />}
                  </button>
                );
              })}
            </div>
          </PopoverContent>
        </Popover>
      )}
    </div>
  );
}
