// @design-system: domain/support/SupportThread

/**
 * SupportThread — chronological message list for a ticket or case.
 *
 * Visibility filtering:
 *   - viewerRole='customer' → sees 'public' messages only
 *   - viewerRole='vendor'   → sees 'public' + 'vendor_internal'
 *   - viewerRole='admin'    → sees all
 *
 * Deleted messages are hidden entirely.
 * Author labels are i18n'd via the support.ticket namespace.
 * Attachments per-message rendered via AttachmentGallery.
 *
 * @example
 * <SupportThread messages={messages} attachments={attachments} viewerRole="customer" />
 */

'use client';

import { useMemo } from 'react';
import { cn } from '@/lib/cn';
import { useT } from '@/lib/i18n/react';
import { AttachmentGallery } from '@/components/ui/domain/support/AttachmentGallery';
import type { SupportMessageView, SupportAttachmentView, ViewerRole } from '@/server/support/types';

export interface SupportThreadProps {
  messages: SupportMessageView[];
  attachments: SupportAttachmentView[];
  viewerRole: ViewerRole;
  className?: string;
}

function isVisible(msg: SupportMessageView, viewerRole: ViewerRole): boolean {
  if (msg.deletedAt) return false;
  if (viewerRole === 'admin') return true;
  if (viewerRole === 'vendor') return msg.visibility !== 'site_internal';
  return msg.visibility === 'public';
}

const AUTHOR_KEY_MAP: Record<SupportMessageView['authorType'], string> = {
  customer: 'ticket.author_customer',
  vendor: 'ticket.author_vendor',
  ai: 'ticket.author_ai',
  human_agent: 'ticket.author_human_agent',
  system: 'ticket.author_system',
  admin: 'ticket.author_admin',
};

export function SupportThread({
  messages,
  attachments,
  viewerRole,
  className,
}: SupportThreadProps) {
  const t = useT('support');
  const tkt = t('ticket') as unknown as Record<string, string>;

  const visible = useMemo(
    () => messages.filter((m) => isVisible(m, viewerRole)),
    [messages, viewerRole],
  );

  if (visible.length === 0) {
    return (
      <div className={cn('text-text-secondary py-8 text-center text-sm', className)}>
        {tkt.thread_empty}
      </div>
    );
  }

  return (
    <ol
      className={cn('flex flex-col gap-4', className)}
      aria-label={tkt.thread_label}
      aria-live="polite"
      aria-relevant="additions"
    >
      {visible.map((msg) => {
        const msgAttachments = attachments.filter((a) => a.messageId === msg.id);
        const authorKey = AUTHOR_KEY_MAP[msg.authorType];
        const isOwn = msg.authorType === 'customer' && viewerRole === 'customer';

        return (
          <li
            key={msg.id}
            className={cn(
              'flex flex-col gap-1 rounded-lg p-3',
              isOwn
                ? 'bg-brand-primary-50 ms-8'
                : msg.authorType === 'system'
                  ? 'border-border text-text-secondary border bg-neutral-50 text-sm'
                  : 'border-border me-8 border bg-surface-base',
            )}
          >
            <div className="flex items-center justify-between gap-2">
              <span className="text-text-secondary text-xs font-medium">
                {tkt[authorKey.replace('ticket.', '')] ?? msg.authorType}
              </span>
              <time
                dateTime={msg.createdAt}
                className="text-text-secondary text-xs"
                suppressHydrationWarning
              >
                {new Date(msg.createdAt).toLocaleTimeString([], {
                  hour: '2-digit',
                  minute: '2-digit',
                })}
              </time>
            </div>
            <p className="text-text-primary text-sm break-words whitespace-pre-wrap">
              <span data-display-name>{msg.body}</span>
            </p>
            {msgAttachments.length > 0 && (
              <AttachmentGallery
                attachments={msgAttachments}
                viewerRole={viewerRole}
                className="mt-2"
              />
            )}
          </li>
        );
      })}
    </ol>
  );
}
