'use client';

import { Badge } from '@tale/ui/badge';
import { Button } from '@tale/ui/button';
import { DropdownMenu, type DropdownMenuGroup } from '@tale/ui/dropdown-menu';
import { HStack } from '@tale/ui/layout';
import { Text } from '@tale/ui/text';
import { Copy, History, MoreHorizontal, Pencil, Trash2 } from 'lucide-react';
import { useCallback, useMemo, useState } from 'react';

import { useTeams } from '@/app/features/settings/teams/hooks/queries';
import { useToast } from '@/app/hooks/use-toast';
import { useT } from '@/lib/i18n/client';
import { cn } from '@/lib/utils/cn';

import type { PromptTemplate } from '../hooks/queries';

interface PromptListRowProps {
  prompt: PromptTemplate;
  onUse: (prompt: PromptTemplate) => void;
  onEdit?: (prompt: PromptTemplate) => void;
  onDelete?: (prompt: PromptTemplate) => void;
  onViewHistory?: (prompt: PromptTemplate) => void;
  canModify: boolean;
  isLast: boolean;
}

export function PromptListRow({
  prompt,
  onUse,
  onEdit,
  onDelete,
  onViewHistory,
  canModify,
  isLast,
}: PromptListRowProps) {
  const { t } = useT('prompts');
  const { toast } = useToast();
  const { teams } = useTeams();
  const [menuOpen, setMenuOpen] = useState(false);

  // Surface the assigned team + tags on the row (#1475). The list query
  // returns teamId only, so resolve the name from the (shared, cached) teams
  // query; fall back to a generic "Team" label if it isn't loaded yet.
  const teamLabel =
    prompt.scope === 'team' && prompt.teamId
      ? (teams?.find((team) => team.id === prompt.teamId)?.name ??
        t('scope.team'))
      : undefined;
  const tags = prompt.tags ?? [];

  const handleUse = useCallback(() => {
    onUse(prompt);
  }, [onUse, prompt]);

  const handleCopy = useCallback(async () => {
    try {
      await navigator.clipboard.writeText(prompt.content);
      toast({ title: t('actions.copied'), variant: 'success' });
    } catch (err) {
      console.warn('[prompt-list-row] clipboard write failed', err);
      toast({ title: t('actions.copyFailed'), variant: 'destructive' });
    }
  }, [prompt.content, toast, t]);

  const menuItems: DropdownMenuGroup[] = useMemo(() => {
    const group: DropdownMenuGroup = [
      {
        type: 'item',
        label: t('actions.copy'),
        icon: Copy,
        onClick: () => {
          void handleCopy();
        },
      },
    ];
    if (onEdit) {
      group.push({
        type: 'item',
        label: t('actions.edit'),
        icon: Pencil,
        onClick: () => onEdit(prompt),
      });
    }
    if (onViewHistory) {
      const hasHistory = (prompt.version ?? 0) > 1;
      group.push({
        type: 'item',
        label: hasHistory
          ? t('actions.viewHistory')
          : t('actions.viewHistoryDisabled'),
        icon: History,
        onClick: hasHistory ? () => onViewHistory(prompt) : undefined,
        disabled: !hasHistory,
      });
    }
    if (onDelete) {
      group.push({
        type: 'item',
        label: t('actions.delete'),
        icon: Trash2,
        onClick: () => onDelete(prompt),
        destructive: true,
      });
    }
    return [group];
  }, [handleCopy, onEdit, onDelete, onViewHistory, prompt, t]);

  return (
    <div
      role="listitem"
      className={cn(
        'group hover:bg-accent/50 flex w-full items-center gap-3 p-3 transition-colors',
        !isLast && 'border-border border-b',
      )}
    >
      <button
        type="button"
        onClick={handleUse}
        className="focus-visible:ring-ring min-w-0 flex-1 cursor-pointer rounded-sm text-left focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none"
      >
        {/* HTML5: <button> permits phrasing content only, so this is a <span>
            (not HStack/<div>). Layout-equivalent via flex utilities. */}
        <span className="flex min-w-0 items-center gap-2">
          <Text as="span" className="truncate text-sm font-medium">
            {prompt.title}
          </Text>
          {prompt.version !== undefined && prompt.version > 1 && (
            <Badge
              variant="outline"
              className="shrink-0 px-1.5 py-0 text-[10px] font-normal"
              aria-label={t('version.badge', {
                version: String(prompt.version),
              })}
            >
              v{prompt.version}
            </Badge>
          )}
        </span>
        <Text
          as="span"
          variant="muted"
          className="mt-0.5 line-clamp-1 block text-xs"
        >
          {prompt.content}
        </Text>
        {(teamLabel || tags.length > 0) && (
          <span className="mt-1 flex flex-wrap items-center gap-1">
            {teamLabel && (
              <Badge
                variant="blue"
                className="px-1.5 py-0 text-[10px] font-normal"
              >
                {teamLabel}
              </Badge>
            )}
            {tags.slice(0, 4).map((tag) => (
              <Badge
                key={tag}
                variant="outline"
                className="px-1.5 py-0 text-[10px] font-normal"
              >
                {tag}
              </Badge>
            ))}
            {tags.length > 4 && (
              <Text as="span" variant="muted" className="text-[10px]">
                +{tags.length - 4}
              </Text>
            )}
          </span>
        )}
      </button>

      <HStack
        gap={1}
        className={cn(
          'shrink-0 transition-opacity',
          // Hover-reveal for mouse users; always-visible for touch (coarse
          // pointers) and keyboard-focus-within so the menu isn't reachable
          // only by hover.
          menuOpen
            ? 'opacity-100'
            : 'opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 pointer-coarse:opacity-100',
        )}
      >
        {canModify && (
          <DropdownMenu
            trigger={
              <Button
                variant="ghost"
                size="icon"
                className="size-11"
                aria-label={t('actions.more')}
              >
                <MoreHorizontal className="size-4" />
              </Button>
            }
            items={menuItems}
            align="end"
            open={menuOpen}
            onOpenChange={setMenuOpen}
          />
        )}
      </HStack>
    </div>
  );
}
