import { useMemo, useState } from 'react';

import { MarkdownViewer } from '@renderer/components/chat/viewers/MarkdownViewer';
import {
  CARD_BG,
  CARD_BORDER_STYLE,
  CARD_ICON_MUTED,
  CARD_TEXT_LIGHT,
} from '@renderer/constants/cssVariables';
import { getTeamColorSet } from '@renderer/constants/teamColors';
import {
  getMessageTypeLabel,
  getStructuredMessageSummary,
  parseMessageReply,
  parseStructuredAgentMessage,
} from '@renderer/utils/agentMessageFormatting';
import { formatAgentRole } from '@renderer/utils/formatAgentRole';
import { createAgentBlockRegex } from '@shared/constants/agentBlocks';
import { Bot, ChevronRight, ListPlus, MessageSquare, Reply } from 'lucide-react';

import { ReplyQuoteBlock } from './ReplyQuoteBlock';

import type { TeamColorSet } from '@renderer/constants/teamColors';
import type { InboxMessage } from '@shared/types';

type StructuredMessage = Record<string, unknown>;

interface ActivityItemProps {
  message: InboxMessage;
  memberRole?: string;
  memberColor?: string;
  recipientColor?: string;
  onMemberNameClick?: (memberName: string) => void;
  onCreateTask?: (subject: string, description: string) => void;
  onReply?: (message: InboxMessage) => void;
}

function getStringField(obj: StructuredMessage, key: string): string | null {
  const value = obj[key];
  return typeof value === 'string' && value.trim() !== '' ? value : null;
}

function getNoiseLabel(parsed: StructuredMessage): string | null {
  const type = getStringField(parsed, 'type');

  if (type === 'idle_notification') {
    const reason = getStringField(parsed, 'idleReason');
    return reason ? `Idle (${reason})` : 'Idle';
  }

  if (type === 'shutdown_response') {
    return parsed.approve === true ? 'Shut down' : 'Rejected shutdown';
  }

  if (type === 'shutdown_request') {
    return 'Shutdown requested';
  }

  if (type === 'shutdown_approved' || type === 'teammate_terminated') {
    return type === 'shutdown_approved' ? 'Shutdown confirmed' : 'Terminated';
  }

  if (type === 'task_completed') {
    const rawTaskId = parsed.taskId;
    const taskId =
      typeof rawTaskId === 'string' || typeof rawTaskId === 'number' ? rawTaskId : null;
    return taskId !== null ? `Completed task #${taskId}` : 'Completed a task';
  }

  return null;
}

// ---------------------------------------------------------------------------
// Compact noise row (idle, shutdown, terminated) — minimal dot + name + label
// ---------------------------------------------------------------------------

const NoiseRow = ({
  name,
  label,
  colors,
}: {
  name: string;
  label: string;
  colors: TeamColorSet;
}): React.JSX.Element => (
  <div className="flex items-center gap-2 px-3 py-1" style={{ opacity: 0.45 }}>
    <span className="size-2 shrink-0 rounded-full" style={{ backgroundColor: colors.border }} />
    <span className="text-[11px]" style={{ color: CARD_ICON_MUTED }}>
      {name}
    </span>
    <span className="text-[11px]" style={{ color: CARD_ICON_MUTED }}>
      {label}
    </span>
  </div>
);

// ---------------------------------------------------------------------------
// Detect system/automated messages that should be collapsed by default.
// These are generated by teamctl.js and contain tool instructions, not
// human-written content, so showing them expanded adds visual noise.
// ---------------------------------------------------------------------------

const SYSTEM_MESSAGE_PATTERNS: { pattern: RegExp; label: string }[] = [
  { pattern: /^New task assigned to you:/, label: 'Task assignment' },
  { pattern: /^Task #\d+\s+approved/, label: 'Task approved' },
  { pattern: /^Task #\d+\s+needs fixes/, label: 'Review changes requested' },
];

function getSystemMessageLabel(text: string): string | null {
  for (const { pattern, label } of SYSTEM_MESSAGE_PATTERNS) {
    if (pattern.test(text)) return label;
  }
  return null;
}

/** Strip ```info_for_agent ... ``` blocks from text for UI display. */
function stripAgentBlocks(text: string): string {
  return text.replace(createAgentBlockRegex(), '').trim();
}

// ---------------------------------------------------------------------------
// Full message card — left colored border, name badge, collapsible content
// ---------------------------------------------------------------------------

export const ActivityItem = ({
  message,
  memberRole,
  memberColor,
  recipientColor,
  onMemberNameClick,
  onCreateTask,
  onReply,
}: ActivityItemProps): React.JSX.Element => {
  const colors = getTeamColorSet(memberColor ?? message.color ?? '');
  const recipientColors = message.to && recipientColor ? getTeamColorSet(recipientColor) : null;
  const formattedRole = formatAgentRole(memberRole);

  const timestamp = Number.isNaN(Date.parse(message.timestamp))
    ? message.timestamp
    : new Date(message.timestamp).toLocaleString();

  const structured = parseStructuredAgentMessage(message.text);
  const noiseLabel = structured ? getNoiseLabel(structured) : null;

  // System/automated messages start collapsed
  const systemLabel = !structured ? getSystemMessageLabel(message.text) : null;
  const [isExpanded, setIsExpanded] = useState(!systemLabel);

  // Strip agent-only blocks from displayed text
  const displayText = useMemo(
    () => (structured ? null : stripAgentBlocks(message.text)),
    [structured, message.text]
  );

  // Check if this is a reply message
  const parsedReply = useMemo(
    () => (displayText ? parseMessageReply(displayText) : null),
    [displayText]
  );

  // Noise messages: minimal inline row
  if (noiseLabel) {
    return <NoiseRow name={message.from} label={noiseLabel} colors={colors} />;
  }

  const messageType =
    structured && typeof structured.type === 'string' ? getMessageTypeLabel(structured.type) : null;
  const autoSummary = structured ? getStructuredMessageSummary(structured) : null;

  const handleCreateTask = (): void => {
    const subject = message.summary || autoSummary || `Task from ${message.from}`;
    const plainText = structured ? JSON.stringify(structured, null, 2) : message.text;
    const description = `From: ${message.from}\nAt: ${timestamp}\n\n${plainText}`.slice(0, 2000);
    onCreateTask?.(subject, description);
  };

  const summaryText = message.summary || autoSummary || '';

  return (
    <article
      className="group overflow-hidden rounded-md"
      style={{
        backgroundColor: CARD_BG,
        border: CARD_BORDER_STYLE,
        borderLeft: `3px solid ${colors.border}`,
      }}
    >
      {/* Header — clickable when system message to toggle expand */}
      <div
        className={[
          'flex items-center gap-2 px-3 py-2',
          systemLabel ? 'cursor-pointer select-none' : '',
        ].join(' ')}
        role={systemLabel ? 'button' : undefined}
        tabIndex={systemLabel ? 0 : undefined}
        onClick={systemLabel ? () => setIsExpanded((v) => !v) : undefined}
        onKeyDown={
          systemLabel
            ? (e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  setIsExpanded((v) => !v);
                }
              }
            : undefined
        }
      >
        {/* Chevron for collapsible system messages */}
        {systemLabel ? (
          <ChevronRight
            className="size-3 shrink-0 transition-transform duration-150"
            style={{
              color: CARD_ICON_MUTED,
              transform: isExpanded ? 'rotate(90deg)' : undefined,
            }}
          />
        ) : null}

        {message.source === 'lead_session' ? (
          <Bot className="size-3.5 shrink-0" style={{ color: colors.border }} />
        ) : (
          <MessageSquare className="size-3.5 shrink-0" style={{ color: colors.border }} />
        )}

        {/* Name badge — clickable to open member popup */}
        {onMemberNameClick ? (
          <button
            type="button"
            className="rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wide transition-opacity hover:opacity-90 focus:outline-none focus:ring-1 focus:ring-[var(--color-border)]"
            style={{
              backgroundColor: colors.badge,
              color: colors.text,
              border: `1px solid ${colors.border}40`,
            }}
            onClick={(e) => {
              e.stopPropagation();
              onMemberNameClick(message.from);
            }}
          >
            {message.from}
          </button>
        ) : (
          <span
            className="rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wide"
            style={{
              backgroundColor: colors.badge,
              color: colors.text,
              border: `1px solid ${colors.border}40`,
            }}
          >
            {message.from}
          </span>
        )}

        {/* Role */}
        {formattedRole ? (
          <span className="text-[10px]" style={{ color: CARD_ICON_MUTED }}>
            {formattedRole}
          </span>
        ) : null}

        {/* Message type label or system label */}
        {systemLabel ? (
          <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
            {systemLabel}
          </span>
        ) : messageType ? (
          <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
            {messageType}
          </span>
        ) : null}

        {/* Lead session marker */}
        {message.source === 'lead_session' ? (
          <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
            session
          </span>
        ) : null}

        {/* Recipient — badge like sender, clickable to open member popup */}
        {message.to && message.to !== message.from && recipientColors ? (
          <span className="text-[10px]">
            <span style={{ color: CARD_ICON_MUTED }}>&rarr; </span>
            {onMemberNameClick ? (
              <button
                type="button"
                className="rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wide transition-opacity hover:opacity-90 focus:outline-none focus:ring-1 focus:ring-[var(--color-border)]"
                style={{
                  backgroundColor: recipientColors.badge,
                  color: recipientColors.text,
                  border: `1px solid ${recipientColors.border}40`,
                }}
                onClick={(e) => {
                  e.stopPropagation();
                  onMemberNameClick(message.to!);
                }}
              >
                {message.to}
              </button>
            ) : (
              <span
                className="rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wide"
                style={{
                  backgroundColor: recipientColors.badge,
                  color: recipientColors.text,
                  border: `1px solid ${recipientColors.border}40`,
                }}
              >
                {message.to}
              </span>
            )}
          </span>
        ) : message.to && message.to !== message.from ? (
          <span className="text-[10px]">
            <span style={{ color: CARD_ICON_MUTED }}>&rarr; </span>
            {onMemberNameClick ? (
              <button
                type="button"
                className="rounded px-0.5 py-0 font-medium transition-opacity hover:opacity-90 focus:outline-none focus:ring-1 focus:ring-[var(--color-border)]"
                style={{ color: CARD_ICON_MUTED }}
                onClick={(e) => {
                  e.stopPropagation();
                  onMemberNameClick(message.to!);
                }}
              >
                {message.to}
              </button>
            ) : (
              <span style={{ color: CARD_ICON_MUTED }}>{message.to}</span>
            )}
          </span>
        ) : null}

        {/* Summary */}
        <span className="flex-1 truncate text-xs" style={{ color: CARD_TEXT_LIGHT }}>
          {summaryText}
        </span>

        {/* Timestamp + reply + create task */}
        <div className="flex shrink-0 items-center gap-1.5">
          {onReply && (
            <button
              type="button"
              className="rounded p-0.5 opacity-0 transition-opacity hover:bg-[var(--color-surface-raised)] group-hover:opacity-100"
              style={{ color: CARD_ICON_MUTED }}
              title="Reply to message"
              onClick={(e) => {
                e.stopPropagation();
                onReply(message);
              }}
            >
              <Reply size={14} />
            </button>
          )}
          {onCreateTask && (
            <button
              type="button"
              className="rounded p-0.5 opacity-0 transition-opacity hover:bg-[var(--color-surface-raised)] group-hover:opacity-100"
              style={{ color: CARD_ICON_MUTED }}
              title="Create task from message"
              onClick={(e) => {
                e.stopPropagation();
                handleCreateTask();
              }}
            >
              <ListPlus size={14} />
            </button>
          )}
          <span className="text-[10px]" style={{ color: CARD_ICON_MUTED }}>
            {timestamp}
          </span>
        </div>
      </div>

      {/* Content — collapsed for system messages, expanded for others */}
      {isExpanded ? (
        <div className="px-3 pb-3">
          {structured ? (
            <div className="space-y-2">
              {autoSummary && autoSummary !== messageType ? (
                <p className="text-xs text-[var(--color-text-secondary)]">{autoSummary}</p>
              ) : null}
              <details className="rounded border border-[var(--color-border)] bg-[var(--color-surface)]">
                <summary className="cursor-pointer px-2 py-1 text-[11px] text-[var(--color-text-muted)]">
                  Raw JSON
                </summary>
                <pre className="overflow-auto px-2 pb-2 text-[11px] leading-relaxed text-[var(--color-text-muted)]">
                  {JSON.stringify(structured, null, 2)}
                </pre>
              </details>
            </div>
          ) : parsedReply ? (
            <ReplyQuoteBlock reply={parsedReply} />
          ) : (
            <MarkdownViewer content={displayText ?? message.text} maxHeight="max-h-56" copyable />
          )}
        </div>
      ) : null}
    </article>
  );
};
