import {
  AppstoreOutlined,
  PlusOutlined,
  CheckOutlined,
  CopyOutlined,
  EyeOutlined,
  LeftOutlined,
  RightOutlined,
  SearchOutlined,
  SendOutlined,
  SettingOutlined,
  ThunderboltOutlined,
} from '@ant-design/icons';
import { App, Alert, Button, Dropdown, Input, Modal, Select, Tag, Typography, type MenuProps } from 'antd';
import type { ChangeEvent } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { ChatLinkCardPreview } from './mainChatPanel/ChatLinkCardPreview';
import { ChatPreviewBody, type ChatPreviewTarget } from './mainChatPanel/ChatPreviewBody';
import {
  ChatPromptCard,
  buildPromptTargetSignature,
  type PromptDraftSelection,
  type PromptSubmitPayload,
} from './mainChatPanel/ChatPromptCard';
import { extractChatMessageParts } from './mainChatPanel/messageParts';
import { extractPreviewItems, type PreviewItem } from './mainChatPanel/previewItems';
import { stripHiddenPreviewTags } from './mainChatPanel/previewMarkers';
import type { ChatMessage, ChatMessagePart } from './mainChatPanel/types';
import './systemChatStyles/MainChatPanel.conversation.css';
import './systemChatStyles/MainChatPanel.preview-runtime.css';
import './SystemChatPage.css';

const { Paragraph, Text, Title } = Typography;

type MockRequestStatus = 'completed' | 'pending';

type MockRequest = {
  requestId: string;
  createdAt: string;
  status: MockRequestStatus;
  statusLabel: string;
  statusColor: string;
  question: string;
  answer: string;
  answerParts?: ChatMessagePart[];
};

type SearchPanelMode = 'all' | 'apps';
type ExpandMode = 'latest' | 'pending' | 'all';

type SearchResult = {
  key: string;
  title: string;
  description: string;
  category: 'request' | 'response' | 'resource' | 'activity';
};

type SystemRenderedMessage = {
  visibleText: string;
  linkCardParts: Extract<ChatMessagePart, { type: 'link_card' }>[];
  promptParts: Extract<ChatMessagePart, { type: 'prompt' }>[];
  previewItems: PreviewItem[];
};

const INITIAL_REQUESTS: MockRequest[] = [
  {
    requestId: 'system-request-001',
    createdAt: '05. 25. 21:30:00',
    status: 'completed',
    statusLabel: '완료',
    statusColor: 'green',
    question: '시스템 채팅 전용 기본 화면을 공유채팅과 같은 감성으로 맞춰 주세요.',
    answer: [
      '현재 화면은 UI 전용 mock 입니다. 서버 호출 없이 공유채팅과 같은 구조를 그대로 보이도록 구성했습니다.',
      '',
      '[[link-card:시스템 채팅 화면 열기|/chat/system|열기]]',
      '',
      '[[preview:/src/app/main/SystemChatPage.tsx]]',
    ].join('\n'),
  },
  {
    requestId: 'system-request-002',
    createdAt: '05. 25. 21:31:10',
    status: 'pending',
    statusLabel: '처리중·미확인',
    statusColor: 'gold',
    question: 'Codex Live, 공유채팅과 소스를 분리한 상태에서 이후 시스템 채팅 전용 기능만 추가할 수 있게 해 주세요.',
    answer: '이 페이지는 별도 파일과 시스템 채팅 전용 CSS 레이어를 사용합니다. 렌더 표현은 Codex Live와 같은 컴포넌트를 쓰더라도 상태와 배치는 여기서만 분리합니다.',
    answerParts: [
      {
        type: 'prompt',
        title: '답변 방식 선택',
        description: '시스템 채팅 mock prompt 입니다.',
        submitLabel: 'mock 전송',
        mode: 'queue',
        freeTextLabel: '추가 요청',
        freeTextPlaceholder: '시스템 채팅에서 이어서 확인할 내용을 입력하세요.',
        options: [
          {
            value: 'brief',
            label: '짧게 정리',
            description: '핵심만 바로 답합니다.',
            preview: {
              type: 'markdown',
              title: '짧게 정리 예시',
              content: '짧은 답변 예시: 핵심만 먼저 전달하고 필요시 후속 설명을 확장합니다.',
              url: null,
              alt: null,
            },
          },
          {
            value: 'full',
            label: '상세 설명',
            description: '배경과 이유까지 함께 답합니다.',
            preview: {
              type: 'markdown',
              title: '상세 설명 예시',
              content: '상세 설명 예시: 시스템 채팅 전용 흐름의 배경과 이유까지 함께 설명합니다.',
              url: null,
              alt: null,
            },
          },
        ],
      },
    ],
  },
  {
    requestId: 'system-request-003',
    createdAt: '05. 25. 21:33:40',
    status: 'completed',
    statusLabel: '완료',
    statusColor: 'green',
    question: '시스템 채팅 검색 모달과 토큰 관리 모달 배치를 실제 화면처럼 먼저 잡아 주세요.',
    answer: [
      '검색 모달, 토큰 관리, 채팅방 설정 모달은 현재 mock 데이터로 열리며, 향후 시스템 채팅 전용 서버 연결만 붙일 수 있게 비워 두었습니다.',
      '',
      '[[link-card:토큰 관리 UI 안내|https://preview.sm-home.cloud/docs|열기]]',
      '',
      '[[preview:/src/app/main/SystemChatPage.css]]',
    ].join('\n'),
  },
  {
    requestId: 'system-request-004',
    createdAt: '05. 25. 21:35:15',
    status: 'pending',
    statusLabel: '처리중·미확인',
    statusColor: 'gold',
    question: '이전 다음 이동이 현재 보이는 필터 기준으로만 동작하게 해 주세요.',
    answer: '필터가 전체면 전체 목록 기준, 처리중·미확인이면 해당 건들만 기준, 마지막건이면 현재 선택된 1건만 보이도록 맞춥니다.',
  },
  {
    requestId: 'system-request-005',
    createdAt: '05. 25. 21:38:55',
    status: 'pending',
    statusLabel: '처리중·미확인',
    statusColor: 'gold',
    question: '웹소켓 상태는 제목 옆 점으로만 간단히 보여 주고, 현재 진행 상황 패널은 빼 주세요.',
    answer: '상태 표현은 헤더 옆 점으로 단순화하고, 별도 진행 상황 카드 없이 채팅 흐름만 보도록 구성할 수 있습니다.',
  },
];

const SEARCH_RESULTS: SearchResult[] = [
  {
    key: 'request-001',
    title: '질문 / 시스템 채팅 전용 기본 화면',
    description: '공유채팅과 같은 레이아웃으로 구성된 mock 질문 카드입니다.',
    category: 'request',
  },
  {
    key: 'response-001',
    title: '답변 / UI 전용 mock 상태',
    description: '서버 호출 없이 동작하는 현재 화면 설명입니다.',
    category: 'response',
  },
  {
    key: 'resource-001',
    title: '리소스 / 시스템 채팅 전용 스타일 복사본',
    description: '공유채팅과 분리된 전용 CSS 파일을 사용합니다.',
    category: 'resource',
  },
  {
    key: 'activity-001',
    title: '활동 / 필터와 이전 다음 mock 흐름',
    description: '마지막건, 처리중·미확인, 전체 필터에 따라 보이는 흐름이 달라집니다.',
    category: 'activity',
  },
];

function dedupePromptParts(parts: Extract<ChatMessagePart, { type: 'prompt' }>[]) {
  const promptByKey = new Map<string, Extract<ChatMessagePart, { type: 'prompt' }>>();

  parts.forEach((part) => {
    const key = `${part.title}:${buildPromptTargetSignature(part)}`;
    if (!promptByKey.has(key)) {
      promptByKey.set(key, part);
    }
  });

  return [...promptByKey.values()];
}

function dedupeLinkCardParts(parts: Extract<ChatMessagePart, { type: 'link_card' }>[]) {
  const linkCardByKey = new Map<string, Extract<ChatMessagePart, { type: 'link_card' }>>();

  parts.forEach((part) => {
    const key = `${part.title}:${part.url}:${part.actionLabel ?? ''}`;
    if (!linkCardByKey.has(key)) {
      linkCardByKey.set(key, part);
    }
  });

  return [...linkCardByKey.values()];
}

function extractSystemMessageRenderPayload(message: ChatMessage): SystemRenderedMessage {
  const extracted = extractChatMessageParts(message.text);
  const structuredParts = Array.isArray(message.parts) ? message.parts : [];
  const visibleText = stripHiddenPreviewTags(extracted.strippedText || message.text).trim();
  const promptParts = dedupePromptParts([
    ...structuredParts.filter((part): part is Extract<ChatMessagePart, { type: 'prompt' }> => part.type === 'prompt'),
    ...extracted.parts.filter((part): part is Extract<ChatMessagePart, { type: 'prompt' }> => part.type === 'prompt'),
  ]);
  const linkCardParts = dedupeLinkCardParts([
    ...structuredParts.filter((part): part is Extract<ChatMessagePart, { type: 'link_card' }> => part.type === 'link_card'),
    ...extracted.parts.filter((part): part is Extract<ChatMessagePart, { type: 'link_card' }> => part.type === 'link_card'),
  ]);

  return {
    visibleText,
    linkCardParts,
    promptParts,
    previewItems: extractPreviewItems([message]),
  };
}

function buildSystemPromptSelectionKey(messageId: number, promptIndex: number, target: Extract<ChatMessagePart, { type: 'prompt' }>) {
  return `${messageId}:${promptIndex}:${target.title}:${buildPromptTargetSignature(target)}`;
}

function SystemChatPreviewCard({ item }: { item: PreviewItem }) {
  const [isPreviewOpen, setIsPreviewOpen] = useState(false);
  const [previewText, setPreviewText] = useState('');
  const [previewError, setPreviewError] = useState('');
  const [previewContentType, setPreviewContentType] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const target = useMemo<ChatPreviewTarget>(
    () => ({
      label: item.label,
      url: item.url,
      kind: item.kind,
    }),
    [item.kind, item.label, item.url],
  );

  useEffect(() => {
    if (!isPreviewOpen) {
      return undefined;
    }

    if (item.kind === 'image' || item.kind === 'video' || item.kind === 'pdf' || item.kind === 'file') {
      setPreviewText('');
      setPreviewError('');
      setPreviewContentType('');
      setIsLoading(false);
      return undefined;
    }

    const controller = new AbortController();
    setIsLoading(true);
    setPreviewError('');

    fetch(item.url, {
      cache: 'no-store',
      credentials: 'include',
      signal: controller.signal,
    })
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`${response.status} ${response.statusText}`.trim());
        }

        setPreviewContentType(response.headers.get('content-type') ?? '');
        const text = await response.text();
        setPreviewText(text);
      })
      .catch((error: unknown) => {
        if (controller.signal.aborted) {
          return;
        }

        setPreviewText('');
        setPreviewContentType('');
        setPreviewError(error instanceof Error ? error.message : 'preview를 불러오지 못했습니다.');
      })
      .finally(() => {
        if (!controller.signal.aborted) {
          setIsLoading(false);
        }
      });

    return () => controller.abort();
  }, [isPreviewOpen, item.kind, item.url]);

  return (
    <section className="system-chat-page__preview-card app-chat-preview-card">
      <div className="app-chat-preview-card__header">
        <div className="app-chat-preview-card__meta">
          <div className="app-chat-preview-card__titles">
            <span className="app-chat-preview-card__label">{item.label}</span>
            <span className="app-chat-preview-card__kind">{item.kind} preview</span>
          </div>
        </div>
        <div className="app-chat-preview-card__actions">
          <Button
            type="text"
            size="small"
            className="app-chat-preview-card__open-link"
            icon={<EyeOutlined />}
            aria-label={isPreviewOpen ? `${item.label} 접기` : `${item.label} 미리보기`}
            onClick={() => setIsPreviewOpen((current) => !current)}
          />
        </div>
      </div>
      {isPreviewOpen ? (
        <div className="app-chat-preview-card__body system-chat-page__preview-card-body">
          <ChatPreviewBody
            target={target}
            previewText={previewText}
            isPreviewLoading={isLoading}
            previewError={previewError}
            previewContentType={previewContentType || undefined}
            renderHtmlAsFrame
            maxMarkdownBlocks={5}
          />
        </div>
      ) : null}
    </section>
  );
}

function SystemChatMessageArtifacts({
  message,
  promptDraftSelections,
  promptSubmittedSelections,
  onPromptSelectionChange,
  onPromptSubmitted,
  onPromptSubmit,
}: {
  message: ChatMessage;
  promptDraftSelections: Record<string, PromptDraftSelection | null>;
  promptSubmittedSelections: Record<string, PromptDraftSelection | null>;
  onPromptSelectionChange: (key: string, selection: PromptDraftSelection | null) => void;
  onPromptSubmitted: (key: string, selection: PromptDraftSelection) => void;
  onPromptSubmit: (key: string, payload: PromptSubmitPayload) => Promise<boolean>;
}) {
  const { linkCardParts, promptParts, previewItems } = useMemo(
    () => extractSystemMessageRenderPayload(message),
    [message],
  );

  if (linkCardParts.length === 0 && promptParts.length === 0 && previewItems.length === 0) {
    return null;
  }

  return (
    <div className="system-chat-page__artifact-stack">
      {linkCardParts.length > 0 ? (
        <div className="system-chat-page__artifact-list">
          {linkCardParts.map((target) => (
            <ChatLinkCardPreview key={`${target.title}:${target.url}`} target={target} />
          ))}
        </div>
      ) : null}
      {promptParts.length > 0 ? (
        <div className="system-chat-page__artifact-list">
          {promptParts.map((target, promptIndex) => {
            const selectionKey = buildSystemPromptSelectionKey(message.id, promptIndex, target);
            return (
              <ChatPromptCard
                key={selectionKey}
                target={target}
                draftSelection={promptDraftSelections[selectionKey] ?? null}
                submittedSelection={promptSubmittedSelections[selectionKey] ?? null}
                onSelectionChange={(selection) => onPromptSelectionChange(selectionKey, selection)}
                onSubmitted={(selection) => onPromptSubmitted(selectionKey, selection)}
                onSubmit={(payload) => onPromptSubmit(selectionKey, payload)}
              />
            );
          })}
        </div>
      ) : null}
      {previewItems.length > 0 ? (
        <div className="system-chat-page__artifact-list">
          {previewItems.map((item) => (
            <SystemChatPreviewCard key={item.id} item={item} />
          ))}
        </div>
      ) : null}
    </div>
  );
}

function SystemChatRequestCard({
  request,
  isReplyActive,
  promptDraftSelections,
  promptSubmittedSelections,
  onReplyToggle,
  onComplete,
  onPromptSelectionChange,
  onPromptSubmitted,
  onPromptSubmit,
}: {
  request: MockRequest;
  isReplyActive: boolean;
  promptDraftSelections: Record<string, PromptDraftSelection | null>;
  promptSubmittedSelections: Record<string, PromptDraftSelection | null>;
  onReplyToggle: (requestId: string) => void;
  onComplete: (requestId: string) => void;
  onPromptSelectionChange: (key: string, selection: PromptDraftSelection | null) => void;
  onPromptSubmitted: (key: string, selection: PromptDraftSelection) => void;
  onPromptSubmit: (key: string, payload: PromptSubmitPayload) => Promise<boolean>;
}) {
  const isCompleted = request.status === 'completed';
  const questionMessage = useMemo<ChatMessage>(
    () => ({
      id: Number(`${request.requestId.replace(/\D+/g, '') || '0'}1`),
      author: 'user',
      text: request.question,
      timestamp: request.createdAt,
    }),
    [request.createdAt, request.question, request.requestId],
  );
  const answerMessage = useMemo<ChatMessage>(
    () => ({
      id: Number(`${request.requestId.replace(/\D+/g, '') || '0'}2`),
      author: 'codex',
      text: request.answer,
      timestamp: request.createdAt,
      clientRequestId: request.requestId,
      parts: request.answerParts,
    }),
    [request.answer, request.answerParts, request.createdAt, request.requestId],
  );

  return (
    <section id={`system-chat-request-${request.requestId}`} className="chat-share-page__request-block">
      <span className="chat-share-page__message-time">{request.createdAt}</span>
      <div className="chat-share-page__message-tone chat-share-page__message-tone--question">
        <span className="chat-share-page__message-tone-label">질문</span>
        <Paragraph className="chat-share-page__message-body system-chat-page__message-text" style={{ marginBottom: 0 }}>
          {extractSystemMessageRenderPayload(questionMessage).visibleText}
        </Paragraph>
      </div>
      <SystemChatMessageArtifacts
        message={questionMessage}
        promptDraftSelections={promptDraftSelections}
        promptSubmittedSelections={promptSubmittedSelections}
        onPromptSelectionChange={onPromptSelectionChange}
        onPromptSubmitted={onPromptSubmitted}
        onPromptSubmit={onPromptSubmit}
      />
      <div className="chat-share-page__message-divider" aria-hidden="true" />
      <div className="chat-share-page__message-headline chat-share-page__message-headline--inline">
        {!isCompleted ? (
          <Button
            type="text"
            size="small"
            className="chat-share-page__prompt-complete-button"
            icon={<CheckOutlined />}
            onClick={() => onComplete(request.requestId)}
          >
            완료 처리
          </Button>
        ) : null}
        <Button
          type="text"
          size="small"
          className={`chat-share-page__prompt-complete-button chat-share-page__response-reply-button${isReplyActive ? ' chat-share-page__response-reply-button--active' : ''}`}
          icon={<SendOutlined />}
          onClick={() => onReplyToggle(request.requestId)}
        >
          {isReplyActive ? '답변 참조 중' : '답변하기'}
        </Button>
      </div>
      <div className="chat-share-page__message-tone chat-share-page__message-tone--answer">
        <span className="chat-share-page__message-tone-label">답변</span>
        <Paragraph className="chat-share-page__message-body system-chat-page__message-text" style={{ marginBottom: 0 }}>
          {extractSystemMessageRenderPayload(answerMessage).visibleText}
        </Paragraph>
      </div>
      <SystemChatMessageArtifacts
        message={answerMessage}
        promptDraftSelections={promptDraftSelections}
        promptSubmittedSelections={promptSubmittedSelections}
        onPromptSelectionChange={onPromptSelectionChange}
        onPromptSubmitted={onPromptSubmitted}
        onPromptSubmit={onPromptSubmit}
      />
    </section>
  );
}

export function SystemChatPage() {
  const { message } = App.useApp();
  const [requests, setRequests] = useState<MockRequest[]>(INITIAL_REQUESTS);
  const [draftText, setDraftText] = useState('');
  const [replyReferenceRequestId, setReplyReferenceRequestId] = useState<string | null>('system-request-002');
  const [promptDraftSelections, setPromptDraftSelections] = useState<Record<string, PromptDraftSelection | null>>({});
  const [promptSubmittedSelections, setPromptSubmittedSelections] = useState<Record<string, PromptDraftSelection | null>>({});
  const [isSearchOpen, setIsSearchOpen] = useState(false);
  const [isTokenUsageOpen, setIsTokenUsageOpen] = useState(false);
  const [isRoomSettingsOpen, setIsRoomSettingsOpen] = useState(false);
  const [searchKeyword, setSearchKeyword] = useState('');
  const [searchPanelMode, setSearchPanelMode] = useState<SearchPanelMode>('all');
  const [expandMode, setExpandMode] = useState<ExpandMode>('pending');
  const [selectedRequestId, setSelectedRequestId] = useState('system-request-002');
  const [selectedAppEnvironment, setSelectedAppEnvironment] = useState<'preview' | 'test' | 'prod'>('preview');
  const [editingRoomChatTypeId, setEditingRoomChatTypeId] = useState('system-chat');
  const [editingRoomUseAccessPin, setEditingRoomUseAccessPin] = useState(true);
  const [editingRoomAccessPin, setEditingRoomAccessPin] = useState('1234');
  const [editingRoomAccessPinPromptTtl, setEditingRoomAccessPinPromptTtl] = useState('30');
  const attachInputRef = useRef<HTMLInputElement | null>(null);

  const filteredSearchResults = useMemo(() => {
    const normalizedKeyword = searchKeyword.trim().toLowerCase();
    if (!normalizedKeyword) {
      return SEARCH_RESULTS;
    }

    return SEARCH_RESULTS.filter((item) => `${item.title} ${item.description} ${item.category}`.toLowerCase().includes(normalizedKeyword));
  }, [searchKeyword]);

  const pendingRequests = useMemo(() => requests.filter((request) => request.status === 'pending'), [requests]);
  const navigationRequests = useMemo(() => (expandMode === 'pending' ? pendingRequests : requests), [expandMode, pendingRequests, requests]);

  useEffect(() => {
    if (navigationRequests.length === 0) {
      return;
    }
    if (!navigationRequests.some((request) => request.requestId === selectedRequestId)) {
      setSelectedRequestId(navigationRequests[0].requestId);
    }
  }, [navigationRequests, selectedRequestId]);

  const selectedRequest = useMemo(
    () => navigationRequests.find((request) => request.requestId === selectedRequestId) ?? navigationRequests[0] ?? requests[0],
    [navigationRequests, requests, selectedRequestId],
  );

  const displayedRequests = useMemo(() => {
    if (expandMode === 'latest') {
      return selectedRequest ? [selectedRequest] : [];
    }
    return navigationRequests;
  }, [expandMode, navigationRequests, selectedRequest]);

  const selectedRequestIndex = useMemo(
    () => navigationRequests.findIndex((request) => request.requestId === selectedRequest?.requestId),
    [navigationRequests, selectedRequest],
  );

  const canMoveToPreviousRequest = expandMode === 'latest' && selectedRequestIndex > 0;
  const canMoveToNextRequest = expandMode === 'latest' && selectedRequestIndex >= 0 && selectedRequestIndex < navigationRequests.length - 1;
  const hiddenPreviousCount = expandMode === 'latest' && selectedRequestIndex > 0 ? selectedRequestIndex : 0;
  const hiddenNextCount = expandMode === 'latest' && selectedRequestIndex >= 0 ? Math.max(0, navigationRequests.length - selectedRequestIndex - 1) : 0;
  const pendingCount = pendingRequests.length;
  const aggregateStatusTag = pendingCount > 0 ? { color: 'gold', label: '처리중·미확인' } : { color: 'green', label: '완료' };
  const headerSummaryLabel = `입력 대기 · 처리 건수 ${requests.length}건 · 미확인 ${pendingCount}건`;

  const shareHeaderSettingsItems = useMemo<MenuProps['items']>(
    () => [
      { key: 'conversation-summary', label: '현재 시스템 채팅방' },
      { key: 'conversation-search', label: '통합검색' },
      { key: 'conversation-refresh', label: '화면 새로고침' },
      { key: 'conversation-apps', label: 'Apps' },
      { type: 'divider' },
      { key: 'conversation-filter-title', label: '콘텐츠 필터', disabled: true },
      { key: 'conversation-filter-latest', label: '마지막건' },
      { key: 'conversation-filter-pending', label: '처리중·미확인' },
      { key: 'conversation-filter-all', label: '전체' },
      { type: 'divider' },
      { key: 'conversation-token-usage', label: '토큰 관리' },
      { key: 'conversation-room-settings', label: '채팅방 설정' },
      { key: 'conversation-clear', label: '채팅방 비우기' },
    ],
    [],
  );

  const handleHeaderMenuClick = ({ key }: { key: string }) => {
    if (key === 'conversation-search') {
      setIsSearchOpen(true);
      setSearchPanelMode('all');
      return;
    }
    if (key === 'conversation-apps') {
      setIsSearchOpen(true);
      setSearchPanelMode('apps');
      return;
    }
    if (key === 'conversation-filter-latest') {
      setExpandMode('latest');
      return;
    }
    if (key === 'conversation-filter-pending') {
      setExpandMode('pending');
      return;
    }
    if (key === 'conversation-filter-all') {
      setExpandMode('all');
      return;
    }
    if (key === 'conversation-token-usage') {
      setIsTokenUsageOpen(true);
      return;
    }
    if (key === 'conversation-room-settings') {
      setIsRoomSettingsOpen(true);
      return;
    }
    message.info('시스템 채팅 UI mock 화면입니다.');
  };

  const handleSend = () => {
    message.info('시스템 채팅 UI mock 화면입니다. 현재는 서버 호출 없이 형태만 제공합니다.');
  };

  const handleOpenAttachPicker = () => {
    attachInputRef.current?.click();
  };

  const handleAttachSelection = (event: ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files ?? []);
    if (files.length > 0) {
      message.info('파일 또는 사진 ' + String(files.length) + '건 선택 mock 상태입니다.');
    }
    event.target.value = '';
  };

  const handleMoveRequest = (direction: -1 | 1) => {
    const nextIndex = selectedRequestIndex + direction;
    const nextRequest = navigationRequests[nextIndex];
    if (nextRequest) {
      setSelectedRequestId(nextRequest.requestId);
    }
  };

  const handleCompleteRequest = (requestId: string) => {
    setRequests((current) =>
      current.map((request) =>
        request.requestId === requestId
          ? {
              ...request,
              status: 'completed',
              statusLabel: '완료',
              statusColor: 'green',
            }
          : request,
      ),
    );
    message.success('완료 처리 mock 상태를 반영했습니다.');
  };

  const handleReplyToggle = (requestId: string) => {
    setReplyReferenceRequestId((current) => (current === requestId ? null : requestId));
  };

  const handlePromptSelectionChange = (key: string, selection: PromptDraftSelection | null) => {
    setPromptDraftSelections((current) => ({
      ...current,
      [key]: selection,
    }));
  };

  const handlePromptSubmitted = (key: string, selection: PromptDraftSelection) => {
    setPromptSubmittedSelections((current) => ({
      ...current,
      [key]: selection,
    }));
  };

  const handlePromptSubmit = async (key: string, payload: PromptSubmitPayload) => {
    setPromptSubmittedSelections((current) => ({
      ...current,
      [key]: payload.selection,
    }));
    message.success(`${payload.promptTitle} mock 선택을 반영했습니다.`);
    return true;
  };

  return (
    <div className="chat-share-page system-chat-page">
      <div className="chat-share-page__shell">
        <div className="chat-share-page__prompt-layout">
          <section className="chat-share-page__panel chat-share-page__conversation-panel">
            <div className="chat-share-page__section-head">
              <div className="chat-share-page__section-copy">
                <div className="chat-share-page__section-title-row">
                  <div className="system-chat-page__title-status">
                    <Title level={5}>채팅</Title>
                    <span className="system-chat-page__ws-indicator system-chat-page__ws-indicator--connected" aria-label="웹소켓 연결 정상" title="웹소켓 연결 정상" />
                  </div>
                  <Tag color={aggregateStatusTag.color}>{aggregateStatusTag.label}</Tag>
                  <Text type="secondary" className="chat-share-page__header-summary">{headerSummaryLabel}</Text>
                </div>
              </div>
              <div className="chat-share-page__section-actions">
                <div className="chat-share-page__request-nav" aria-label="요청 이동">
                  <Button type="text" size="small" className="chat-share-page__section-action" icon={<LeftOutlined />} disabled={!canMoveToPreviousRequest} onClick={() => handleMoveRequest(-1)}>
                    이전
                  </Button>
                  <Button type="text" size="small" className="chat-share-page__section-action" icon={<RightOutlined />} iconPosition="end" disabled={!canMoveToNextRequest} onClick={() => handleMoveRequest(1)}>
                    다음
                  </Button>
                </div>
                <Dropdown
                  trigger={['click']}
                  menu={{ items: shareHeaderSettingsItems, className: 'chat-share-page__settings-menu', onClick: handleHeaderMenuClick }}
                  placement="bottomRight"
                >
                  <Button type="text" size="small" className="chat-share-page__section-action chat-share-page__section-action--tool system-chat-page__icon-tool-button" aria-label="채팅 설정" title="채팅 설정" icon={<SettingOutlined />} />
                </Dropdown>
              </div>
            </div>

            <div className="chat-share-page__message-list">
              {hiddenPreviousCount > 0 ? (
                <div className="system-chat-page__omitted-divider" aria-label={'이전 요청 ' + String(hiddenPreviousCount) + '건 생략'}>
                  <span className="system-chat-page__omitted-divider-line" aria-hidden="true" />
                  <span className="system-chat-page__omitted-divider-text">이전 요청 {hiddenPreviousCount}건 생략</span>
                  <span className="system-chat-page__omitted-divider-line" aria-hidden="true" />
                </div>
              ) : null}

              {displayedRequests.map((request) => (
                <SystemChatRequestCard
                  key={request.requestId}
                  request={request}
                  isReplyActive={replyReferenceRequestId === request.requestId}
                  promptDraftSelections={promptDraftSelections}
                  promptSubmittedSelections={promptSubmittedSelections}
                  onReplyToggle={handleReplyToggle}
                  onComplete={handleCompleteRequest}
                  onPromptSelectionChange={handlePromptSelectionChange}
                  onPromptSubmitted={handlePromptSubmitted}
                  onPromptSubmit={handlePromptSubmit}
                />
              ))}

              {hiddenNextCount > 0 ? (
                <div className="system-chat-page__omitted-divider" aria-label={'다음 요청 ' + String(hiddenNextCount) + '건 생략'}>
                  <span className="system-chat-page__omitted-divider-line" aria-hidden="true" />
                  <span className="system-chat-page__omitted-divider-text">다음 요청 {hiddenNextCount}건 생략</span>
                  <span className="system-chat-page__omitted-divider-line" aria-hidden="true" />
                </div>
              ) : null}
            </div>
          </section>

          <section className="chat-share-page__panel chat-share-page__composer-panel">
            <div className="chat-share-page__composer-shell app-chat-panel__composer">
              <input ref={attachInputRef} className="chat-share-page__composer-file-input app-chat-panel__composer-file-input" type="file" multiple accept="image/*,.pdf,.txt,.md,.csv,.json,.zip,.heic,.heif" onChange={handleAttachSelection} style={{ display: 'none' }} />
              <div className="chat-share-page__composer-topline">
                <div className="app-chat-panel__composer-utility-buttons">
                  <Button className="system-chat-page__composer-icon-button system-chat-page__composer-attach-button" icon={<PlusOutlined />} aria-label="파일" title="파일" onClick={handleOpenAttachPicker} />
                </div>
                <div className="app-chat-panel__composer-type chat-share-page__composer-type-readonly">
                  <Select value="시스템 채팅" aria-label="현재 채팅유형" options={[{ value: '시스템 채팅', label: '시스템 채팅' }]} disabled />
                </div>
                <div className="app-chat-panel__composer-actions chat-share-page__composer-topline-actions">
                  <div className="app-chat-panel__composer-action-buttons system-chat-page__composer-action-buttons">
                    <Button className="system-chat-page__composer-icon-button system-chat-page__composer-icon-button--instant" icon={<ThunderboltOutlined />} aria-label="즉시전송" title="즉시전송" onClick={handleSend} />
                    <Button type="primary" className="system-chat-page__composer-icon-button system-chat-page__composer-icon-button--send" icon={<SendOutlined />} aria-label="답변 전송" title="답변 전송" onClick={handleSend} />
                  </div>
                </div>
              </div>
              {replyReferenceRequestId ? (
                <div className="chat-share-page__reply-reference system-chat-page__reply-reference">
                  <div className="chat-share-page__reply-reference-copy">
                    <span className="chat-share-page__reply-reference-label">답변 참조 중</span>
                    <span className="chat-share-page__reply-reference-text">{requests.find((request) => request.requestId === replyReferenceRequestId)?.question ?? '선택된 요청'}</span>
                  </div>
                  <Button type="text" size="small" className="chat-share-page__reply-reference-clear" onClick={() => setReplyReferenceRequestId(null)}>해제</Button>
                </div>
              ) : null}
              <div className="chat-share-page__composer-entry-row">
                <div className="app-chat-panel__composer-input-shell chat-share-page__composer-input-shell">
                  <Input.TextArea value={draftText} onChange={(event) => setDraftText(event.target.value)} placeholder="시스템 채팅에 보낼 내용을 입력하세요. 현재는 UI 형태만 제공됩니다." rows={6} maxLength={20000} autoSize={{ minRows: 6, maxRows: 10 }} />
                </div>
              </div>
            </div>
          </section>
        </div>
      </div>

      <Modal open={isTokenUsageOpen} footer={null} title="토큰 관리" className="chat-share-page__token-usage-modal" onCancel={() => setIsTokenUsageOpen(false)}>
        <div className="chat-share-page__token-usage-modal-body">
          <div className="chat-share-page__token-usage-select-row">
            <Text type="secondary">적용 토큰 설정</Text>
            <Text strong>시스템 채팅 UI 전용 mock-admin</Text>
          </div>
          <div className="chat-share-page__token-usage-overview-card" aria-label="토큰 집계 요약">
            <div className="chat-share-page__token-usage-overview-head">
              <div>
                <div className="chat-share-page__token-usage-overview-label">지금 사용 가능</div>
                <div className="chat-share-page__token-usage-overview-value">100,000</div>
              </div>
              <Tag color="gold">5시간 기준 12%</Tag>
            </div>
            <div className="chat-share-page__token-usage-meter-card">
              <div className="chat-share-page__token-usage-meter-track chat-share-page__token-usage-meter-track--merged" aria-hidden="true">
                <span className="chat-share-page__token-usage-meter-fill chat-share-page__token-usage-meter-fill--overall" style={{ width: '12%' }} />
              </div>
              <div className="chat-share-page__token-usage-meter-legend">
                <div className="chat-share-page__token-usage-meter-row">
                  <span className="chat-share-page__token-usage-meter-dot chat-share-page__token-usage-meter-fill--overall" aria-hidden="true" />
                  <span className="chat-share-page__token-usage-meter-label">전체 사용량</span>
                  <span className="chat-share-page__token-usage-meter-value">12,000 / 100,000</span>
                </div>
              </div>
            </div>
            <div className="chat-share-page__token-usage-summary-copy">현재 시스템 채팅은 UI mock 상태이므로 수치는 예시입니다.</div>
          </div>
          <div className="chat-share-page__token-usage-select-row">
            <Text type="secondary">현재 공유 토큰</Text>
            <div className="chat-share-page__token-usage-share-url-row">
              <Paragraph className="chat-share-page__token-usage-share-url" style={{ maxWidth: '100%', marginBottom: 0 }}>
                https://preview.sm-home.cloud/chat/system
              </Paragraph>
              <Button type="text" size="small" className="chat-share-page__token-usage-copy-button" icon={<CopyOutlined />} onClick={() => message.success('예시 URL을 복사했습니다.')} />
            </div>
            <div className="chat-share-page__token-usage-token-meta">
              <Text type="secondary">UI mock 상태 · 만료 없음</Text>
            </div>
          </div>
        </div>
      </Modal>

      <Modal
        open={isRoomSettingsOpen}
        title="시스템 채팅 설정"
        okText="저장"
        cancelText="취소"
        onCancel={() => setIsRoomSettingsOpen(false)}
        onOk={() => {
          message.success('시스템 채팅 UI 설정을 저장한 것처럼 표시합니다. 현재는 mock 상태입니다.');
          setIsRoomSettingsOpen(false);
        }}
      >
        <div className="chat-share-page__token-usage-modal">
          <Alert showIcon type="info" message="현재 화면은 서버 연결 없는 UI 전용 시스템 채팅입니다." />
          <div className="chat-share-page__token-usage-panel">
            <Text strong>채팅유형</Text>
            <Select value={editingRoomChatTypeId} onChange={setEditingRoomChatTypeId} options={[{ value: 'system-chat', label: '시스템 채팅' }]} />
          </div>
          <div className="chat-share-page__token-usage-panel">
            <Text strong>방 전용 문맥 제목</Text>
            <Input value="시스템 채팅 기본 규칙" readOnly />
          </div>
          <div className="chat-share-page__token-usage-panel">
            <Text strong>방 전용 문맥 본문</Text>
            <Input.TextArea rows={8} value="이 화면은 공유채팅과 동일한 구조의 UI mock이며, 향후 시스템 채팅 전용 기능을 여기에만 추가합니다." readOnly />
          </div>
          <div className="chat-share-page__token-usage-panel">
            <Text strong>공유 비밀번호</Text>
            <label style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
              <input type="checkbox" checked={editingRoomUseAccessPin} onChange={(event) => setEditingRoomUseAccessPin(event.target.checked)} />
              <span>숫자 4자리 비밀번호 요구</span>
            </label>
            <Input.Password value={editingRoomAccessPin} maxLength={4} onChange={(event) => setEditingRoomAccessPin(event.target.value)} placeholder="숫자 4자리" />
            <Text strong style={{ marginTop: 12 }}>비밀번호 유지시간</Text>
            <Select value={editingRoomAccessPinPromptTtl} onChange={setEditingRoomAccessPinPromptTtl} options={[{ value: 'always', label: '매번 묻기' }, { value: '30', label: '30분 유지' }, { value: '60', label: '1시간 유지' }]} />
          </div>
        </div>
      </Modal>

      <Modal open={isSearchOpen} footer={null} title={searchPanelMode === 'apps' ? '시스템 채팅 Apps' : '시스템 채팅 통합검색'} className="chat-share-page__search-modal" onCancel={() => setIsSearchOpen(false)}>
        <div className="chat-share-page__search-modal-body">
          <Input autoFocus allowClear size="large" prefix={<SearchOutlined />} placeholder={searchPanelMode === 'apps' ? '허용된 Apps 검색' : '질문, 답변, 리소스, 활동 로그 검색'} value={searchKeyword} onChange={(event) => setSearchKeyword(event.target.value)} />
          <div className="chat-share-page__search-summary">
            <Text type="secondary">{searchKeyword.trim() ? `검색 결과 ${filteredSearchResults.length}건` : searchPanelMode === 'apps' ? '시스템 채팅에서 허용할 앱 예시를 보여줍니다.' : '질문, 답변, 리소스, 활동 로그 mock 데이터를 함께 찾습니다.'}</Text>
          </div>
          {searchPanelMode === 'apps' ? (
            <div className="chat-share-page__search-app-environment">
              <Text type="secondary">실행 환경</Text>
              <Select value={selectedAppEnvironment} options={[{ value: 'preview', label: 'preview' }, { value: 'test', label: 'test' }, { value: 'prod', label: 'prod' }]} onChange={setSelectedAppEnvironment} />
            </div>
          ) : null}
          <div className="chat-share-page__search-results">
            {filteredSearchResults.length > 0 ? (
              filteredSearchResults.map((result) => (
                <div key={result.key} className="chat-share-page__search-result">
                  <button type="button" className="chat-share-page__search-result-main" onClick={() => message.info(`${result.title} 항목은 UI mock 데이터입니다.`)}>
                    <span className="chat-share-page__search-result-title">{result.title}</span>
                    <span className="chat-share-page__search-result-description">{result.description}</span>
                  </button>
                  {searchPanelMode === 'apps' ? (
                    <div className="chat-share-page__search-result-action-group">
                      <Tag bordered={false} className="chat-share-page__search-result-tag">지원 {selectedAppEnvironment}</Tag>
                      <Button type="text" size="small" className="chat-share-page__search-result-action chat-share-page__search-result-action--environment" icon={<AppstoreOutlined />} onClick={() => message.info('앱 실행은 연결되지 않았습니다.')}>앱 실행</Button>
                    </div>
                  ) : null}
                </div>
              ))
            ) : (
              <div className="chat-share-page__search-empty">
                <Text type="secondary">검색 결과가 없습니다.</Text>
              </div>
            )}
          </div>
        </div>
      </Modal>
    </div>
  );
}
