'use client';

import { useLocale, useTranslations } from 'next-intl';
import { ChevronRight } from 'lucide-react';
import { formatAppDateTime } from '@/lib/i18n/format';
import type { UserNotificationItem, UserNotificationType } from '@/types/notifications';

const TYPE_I18N: Record<UserNotificationType, string> = {
  CASE_SENT: 'typeCaseSent',
  CLINIC_COMMENT: 'typeClinicComment',
  LAB_COMMENT: 'typeLabComment',
  LAB_COMMENT_CLINIC: 'typeLabCommentClinic',
  CASE_IMPORTANT: 'typeCaseImportant',
  TASK_COMPLETED: 'typeTaskCompleted',
  TASK_ASSIGNED: 'typeTaskAssigned',
  CONNECTION_REQUEST: 'typeConnectionRequest',
  STAFF_INVITE: 'typeStaffInvite',
};

function destKeyFromHref(href: string): string {
  if (href.startsWith('/cases')) return 'destCases';
  if (href.startsWith('/tasks')) return 'destTasks';
  if (href.startsWith('/treatment')) return 'destTreatment';
  if (href.startsWith('/organizations')) return 'destOrganizations';
  if (href.startsWith('/staff')) return 'destStaff';
  return 'destOpen';
}

function asString(value: unknown): string | null {
  if (typeof value !== 'string') return null;
  const trimmed = value.trim();
  return trimmed.length > 0 ? trimmed : null;
}

function formatProsthesisCode(code: string): string {
  return code.replace(/_/g, ' ');
}

/** Build a single truncated context string from denormalized inbox payload. */
export function notificationContextLine(
  item: UserNotificationItem,
): string | null {
  const payload = item.payload ?? {};
  const parts: string[] = [];

  const patientName = asString(payload.patientName);
  const clinicName = asString(payload.clinicName);
  const labName = asString(payload.labName);
  const taskName = asString(payload.taskName);
  const fromOrganizationName = asString(payload.fromOrganizationName);
  const inviteeName = asString(payload.inviteeName);
  const email = asString(payload.email);
  const prosthesisTypeCode = asString(payload.prosthesisTypeCode);

  const prosthesisCodes = Array.isArray(payload.prosthesisTypeCodes)
    ? payload.prosthesisTypeCodes
        .filter((code): code is string => typeof code === 'string' && code.trim().length > 0)
        .map((code) => formatProsthesisCode(code.trim()))
    : [];

  const prosthesisLabel =
    prosthesisTypeCode != null
      ? formatProsthesisCode(prosthesisTypeCode)
      : prosthesisCodes.length > 0
        ? prosthesisCodes.slice(0, 2).join(', ')
        : null;

  switch (item.type) {
    case 'CASE_SENT':
    case 'CLINIC_COMMENT':
    case 'LAB_COMMENT':
    case 'CASE_IMPORTANT':
      if (patientName) parts.push(patientName);
      if (clinicName) parts.push(clinicName);
      if (prosthesisLabel) parts.push(prosthesisLabel);
      break;
    case 'LAB_COMMENT_CLINIC':
      if (patientName) parts.push(patientName);
      if (labName) parts.push(labName);
      if (prosthesisLabel) parts.push(prosthesisLabel);
      break;
    case 'TASK_COMPLETED':
    case 'TASK_ASSIGNED':
      if (patientName) parts.push(patientName);
      if (clinicName) parts.push(clinicName);
      else if (labName) parts.push(labName);
      if (taskName) parts.push(taskName);
      if (prosthesisLabel) parts.push(prosthesisLabel);
      break;
    case 'CONNECTION_REQUEST':
      if (fromOrganizationName) parts.push(fromOrganizationName);
      break;
    case 'STAFF_INVITE':
      if (inviteeName) parts.push(inviteeName);
      if (email) parts.push(email);
      break;
    default:
      // Fallback: show any denormalized fields even if type is unexpected.
      if (patientName) parts.push(patientName);
      if (clinicName) parts.push(clinicName);
      if (labName) parts.push(labName);
      if (taskName) parts.push(taskName);
      if (prosthesisLabel) parts.push(prosthesisLabel);
      break;
  }

  if (parts.length === 0) return null;
  return parts.join(' · ');
}

export function NotificationCard({
  item,
  onSelect,
  compact = false,
}: {
  item: UserNotificationItem;
  onSelect: (item: UserNotificationItem) => void;
  compact?: boolean;
}) {
  const t = useTranslations('notifications');
  const locale = useLocale();
  const unread = !item.readAt;
  const titleKey = TYPE_I18N[item.type] ?? 'typeUnknown';
  const destKey = destKeyFromHref(item.href);
  const context = notificationContextLine(item);

  return (
    <button
      type="button"
      onClick={() => onSelect(item)}
      className={`w-full min-h-11 text-start rounded-[var(--radius-md)] border px-3 py-2.5 sm:py-3 transition-colors ${
        unread
          ? 'border-primary/40 bg-primary/5 hover:border-primary/60'
          : 'border-border/70 bg-background-secondary/40 hover:border-border'
      }`}
    >
      <div className="flex items-start gap-2.5 sm:gap-3">
        {unread ? (
          <span className="mt-1.5 h-2 w-2 shrink-0 rounded-full bg-badge-warning-fg" aria-hidden />
        ) : (
          <span className="mt-1.5 h-2 w-2 shrink-0" aria-hidden />
        )}
        <div className="min-w-0 flex-1">
          <p
            className={`font-medium text-text-primary ${
              compact ? 'text-sm' : 'text-sm sm:text-base'
            }`}
          >
            {t(titleKey)}
          </p>
          <div
            className={`mt-0.5 flex min-w-0 items-center gap-x-2 text-text-muted ${
              compact ? 'text-[11px]' : 'text-xs sm:text-sm'
            }`}
          >
            {context ? (
              <>
                <span className="min-w-0 flex-1 truncate" title={context}>
                  {context}
                </span>
                <span className="text-border shrink-0" aria-hidden>
                  ·
                </span>
              </>
            ) : null}
            <span className="shrink-0 whitespace-nowrap">
              {formatAppDateTime(item.createdAt, locale)}
            </span>
            <span className="text-border shrink-0" aria-hidden>
              ·
            </span>
            <span className="shrink-0 whitespace-nowrap">{t(destKey)}</span>
          </div>
        </div>
        <ChevronRight
          className="mt-0.5 h-4 w-4 shrink-0 text-text-muted rtl:rotate-180"
          aria-hidden
        />
      </div>
    </button>
  );
}
