// components/record-tag-selector.tsx
"use client";

import * as React from "react";
import { X, Check, ChevronsUpDown, Tag, Loader2 } from "lucide-react";
import { useTranslation } from "react-i18next";
import { useRecordTags } from "@/user-management/hooks/useRecordTags";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/shared/common/ui/popover";
import { cn } from "@/shared/lib/utils";
import { Button } from "@/shared/common/ui/button";
import { Badge } from "@/shared/common/ui/badge";
import { useLocalizedName } from "@/shared/common/localizedName";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/shared/common/ui/command";

// ─── Types ─────────────────────────────────────────────

export interface TagSelectorProps {
  /** Unit ID to fetch tags from */
  unitId: string;
  /** Currently selected tag IDs */
  selectedTagIds: string[];
  /** Callback when selection changes */
  onChange: (tagIds: string[]) => void;
  /** Placeholder text */
  placeholder?: string;
  /** Allow multiple selection */
  multiple?: boolean;
  /** Disable the selector */
  disabled?: boolean;
  /** Custom className */
  className?: string;
  /** Maximum number of tags to show before collapsing */
  maxDisplayTags?: number;
  /** Optional error state */
  error?: string;
}

// ─── Component ─────────────────────────────────────────

export function RecordTagSelector({
  unitId,
  selectedTagIds,
  onChange,
  placeholder = "Select tags...",
  multiple = true,
  disabled = false,
  className,
  maxDisplayTags = 3,
  error,
}: TagSelectorProps) {
  const { t } = useTranslation();
  const [open, setOpen] = React.useState(false);
  const localizedName = useLocalizedName();
  const { recordTagsList, isLoadingRecordTagsList, isErrorRecordTagsList } =
    useRecordTags({ unitId });

  const tags = recordTagsList?.items ?? [];
  const selectedTags = tags.filter((tag) => selectedTagIds.includes(tag.id));

  // Toggle tag selection
  const toggleTag = React.useCallback(
    (tagId: string) => {
      if (multiple) {
        onChange(
          selectedTagIds.includes(tagId)
            ? selectedTagIds.filter((id) => id !== tagId)
            : [...selectedTagIds, tagId],
        );
      } else {
        onChange(selectedTagIds.includes(tagId) ? [] : [tagId]);
        setOpen(false);
      }
    },
    [multiple, onChange, selectedTagIds],
  );

  // Remove a specific tag
  const removeTag = React.useCallback(
    (e: React.MouseEvent, tagId: string) => {
      e.stopPropagation();
      onChange(selectedTagIds.filter((id) => id !== tagId));
    },
    [onChange, selectedTagIds],
  );

  // Clear all selections
  const clearAll = React.useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();
      onChange([]);
    },
    [onChange],
  );

  return (
    <div className={cn("flex flex-col gap-1.5", className)}>
      <Popover open={open} onOpenChange={setOpen}>
        <PopoverTrigger asChild>
          <Button
            variant="outline"
            role="combobox"
            aria-expanded={open}
            disabled={disabled || isLoadingRecordTagsList}
            className={cn(
              "w-full justify-between min-h-[40px] h-auto px-3 py-2",
              !multiple && selectedTags.length > 0 && "justify-start gap-2",
              error && "border-destructive ring-destructive",
              "hover:bg-accent",
            )}
          >
            {isLoadingRecordTagsList ? (
              <div className="flex items-center gap-2 text-muted-foreground">
                <Loader2 className="h-4 w-4 animate-spin" />
                <span className="text-sm">{t("common.loading")}</span>
              </div>
            ) : selectedTags.length === 0 ? (
              <span className="text-muted-foreground text-sm">
                {placeholder}
              </span>
            ) : multiple ? (
              <div className="flex flex-wrap items-center gap-1.5 flex-1">
                {selectedTags.slice(0, maxDisplayTags).map((tag: any) => (
                  <Badge
                    key={tag.id}
                    variant="secondary"
                    className="gap-1 px-2 py-0.5 text-xs font-medium cursor-default"
                    style={{
                      backgroundColor: tag.color ? `${tag.color}20` : undefined,
                      color: tag.color,
                      borderColor: tag.color,
                    }}
                  >
                    {tag.name}
                    <X
                      className="h-3 w-3 cursor-pointer hover:text-destructive"
                      onClick={(e) => removeTag(e, tag.id)}
                    />
                  </Badge>
                ))}
                {selectedTags.length > maxDisplayTags && (
                  <Badge variant="secondary" className="text-xs">
                    +{selectedTags.length - maxDisplayTags}
                  </Badge>
                )}
              </div>
            ) : (
              <div className="flex items-center gap-2 flex-1">
                <span className="text-sm">
                  {localizedName(selectedTags[0].name)}
                </span>
              </div>
            )}

            <div className="flex items-center gap-1 shrink-0 ml-2">
              {selectedTags.length > 0 && !disabled && (
                <X
                  className="h-4 w-4 text-muted-foreground hover:text-foreground cursor-pointer"
                  onClick={clearAll}
                />
              )}
              <ChevronsUpDown className="h-4 w-4 text-muted-foreground shrink-0" />
            </div>
          </Button>
        </PopoverTrigger>

        <PopoverContent
          className="w-[--radix-popover-trigger-width] p-0"
          align="start"
        >
          <Command>
            <CommandInput
              placeholder={t("common.search") || "Search tags..."}
            />
            <CommandList>
              <CommandEmpty>
                {isErrorRecordTagsList ? (
                  <div className="py-6 text-center text-sm text-destructive">
                    {t("common.errorLoading")}
                  </div>
                ) : (
                  t("common.noResults") || "No tags found."
                )}
              </CommandEmpty>

              <CommandGroup>
                {tags.map((tag) => {
                  const isSelected = selectedTagIds.includes(tag.id);
                  return (
                    <CommandItem
                      key={tag.id}
                      value={tag.id}
                      onSelect={() => toggleTag(tag.id)}
                      className="cursor-pointer"
                    >
                      <div className="flex items-center gap-3 flex-1">
                        <div
                          className={cn(
                            "flex h-4 w-4 items-center justify-center rounded-sm border border-primary",
                            isSelected
                              ? "bg-primary text-primary-foreground"
                              : "opacity-50",
                          )}
                        >
                          {isSelected && <Check className="h-3 w-3" />}
                        </div>

                        <span className="flex-1 text-sm">
                          {localizedName(tag.name)}
                        </span>
                      </div>
                    </CommandItem>
                  );
                })}
              </CommandGroup>
            </CommandList>
          </Command>
        </PopoverContent>
      </Popover>

      {error && <p className="text-xs text-destructive">{error}</p>}
    </div>
  );
}

// ─── Single Select Variant ─────────────────────────────

export function RecordTagSelectorSingle(
  props: Omit<TagSelectorProps, "multiple" | "maxDisplayTags">,
) {
  return <RecordTagSelector {...props} multiple={false} />;
}

// ─── Display Only (Read) Component ─────────────────────

export interface TagListProps {
  tagIds: string[];
  unitId: string;
  className?: string;
  size?: "sm" | "md" | "lg";
}

export function RecordTagList({
  tagIds,
  unitId,
  className,
  size = "md",
}: TagListProps) {
  const localizedName = useLocalizedName();
  const { recordTagsList, isLoadingRecordTagsList } = useRecordTags({ unitId });
  const tags = recordTagsList?.items ?? [];
  const selectedTags = tags.filter((tag) => tagIds.includes(tag.id));

  const sizeClasses = {
    sm: "text-[10px] px-1.5 py-0",
    md: "text-xs px-2 py-0.5",
    lg: "text-sm px-2.5 py-1",
  };

  if (isLoadingRecordTagsList) {
    return <Loader2 className="h-3 w-3 animate-spin text-muted-foreground" />;
  }

  if (selectedTags.length === 0) {
    return <span className="text-xs text-muted-foreground">—</span>;
  }

  return (
    <div className={cn("flex flex-wrap gap-1.5", className)}>
      {selectedTags.map((tag) => (
        <Badge
          key={tag.id}
          variant="outline"
          className={cn("font-medium gap-1.5", sizeClasses[size])}
        >
          <span className="h-1.5 w-1.5 rounded-full" />
          {localizedName(tag.name)}
        </Badge>
      ))}
    </div>
  );
}

// ─── Create Tag Dialog Integration ─────────────────────

export interface TagSelectorWithCreateProps extends TagSelectorProps {
  onCreateTag?: (name: string) => void;
  isCreatingTag?: boolean;
}

export function RecordTagSelectorWithCreate({
  onCreateTag,
  isCreatingTag,
  ...props
}: TagSelectorWithCreateProps) {
  const { t } = useTranslation();
  const [newTagName, setNewTagName] = React.useState("");

  const handleCreate = React.useCallback(() => {
    if (newTagName.trim() && onCreateTag) {
      onCreateTag(newTagName.trim());
      setNewTagName("");
    }
  }, [newTagName, onCreateTag]);

  return (
    <div className="space-y-2">
      <RecordTagSelector {...props} />

      {onCreateTag && (
        <div className="flex items-center gap-2">
          <div className="relative flex-1">
            <Tag className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
            <input
              type="text"
              value={newTagName}
              onChange={(e) => setNewTagName(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && handleCreate()}
              placeholder={t("tags.createPlaceholder") || "Create new tag..."}
              className="w-full h-8 pl-8 pr-3 text-xs rounded-md border border-input bg-background 
                         focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-1"
            />
          </div>
          <Button
            size="sm"
            variant="secondary"
            className="h-8 px-3 text-xs"
            onClick={handleCreate}
            disabled={!newTagName.trim() || isCreatingTag}
          >
            {isCreatingTag ? (
              <Loader2 className="h-3 w-3 animate-spin" />
            ) : (
              t("common.create") || "Create"
            )}
          </Button>
        </div>
      )}
    </div>
  );
}
