import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  ArrowsAltOutlined,
  DeleteOutlined,
  EditOutlined,
  SaveOutlined,
  PlusOutlined,
  ReloadOutlined,
  ShrinkOutlined,
  UnorderedListOutlined,
} from '@ant-design/icons';
import {
  Alert,
  Button,
  Card,
  Checkbox,
  Empty,
  Form,
  Input,
  List,
  Segmented,
  Space,
  Switch,
  Tag,
  Tooltip,
  Typography,
  Modal,
  Select,
} from 'antd';
import { useEffect, useMemo, useRef, useState } from 'react';
import { MarkdownPreviewContent } from '../../components/markdownPreview';
import {
  canUseChatType,
  CHAT_PERMISSION_ROLE_LABELS,
  createDefaultChatTypeExecutionPolicy,
  deleteChatType,
  resolveCurrentChatPermissionRoles,
  upsertChatType,
  useChatTypeRegistry,
  type ChatPermissionRole,
  type ChatTypeExecutionMode,
  type ChatTypeExecutionPolicy,
  type ChatTypeRecord,
} from './chatTypeAccess';
import {
  resolveChatTypeDefaultContextIds,
  upsertChatTypeDefaultContextSelection,
  useChatContextSettingsRegistry,
} from './chatContextSettingsAccess';
import { confirmWithKeyboard } from './modalKeyboard';
import { useTokenAccess } from './tokenAccess';
import './ChatTypeManagementPage.css';

const { Text, Title } = Typography;

type ChatTypeFormValue = {
  id?: string;
  name: string;
  sortOrder: number;
  description: string;
  executionPolicy: ChatTypeExecutionPolicy;
  permissions: ChatPermissionRole[];
  enabled: boolean;
};

const EMPTY_FORM_VALUE: ChatTypeFormValue = {
  name: '',
  sortOrder: 1,
  description: '',
  executionPolicy: createDefaultChatTypeExecutionPolicy(),
  permissions: ['token-user'],
  enabled: true,
};

function toFormValue(chatType: ChatTypeRecord | null): ChatTypeFormValue {
  if (!chatType) {
    return EMPTY_FORM_VALUE;
  }

  return {
    id: chatType.id,
    name: chatType.name,
    sortOrder: chatType.sortOrder,
    description: chatType.description,
    executionPolicy: chatType.executionPolicy,
    permissions: chatType.permissions,
    enabled: chatType.enabled,
  };
}

function resolveExecutionPolicyModeLabel(mode: ChatTypeExecutionMode) {
  if (mode === 'summary-free-talking') {
    return '회의 기록자 + 프리토킹';
  }

  if (mode === 'dispatcher-workers') {
    return '중계 지시자 + 실작업자';
  }

  return '직접 구성';
}

export function ChatTypeManagementPage() {
  const { hasAccess } = useTokenAccess();
  const { chatTypes, setChatTypes, setChatTypesLocal, isLoading, errorMessage, reload } = useChatTypeRegistry();
  const {
    defaultContexts,
    chatTypeDefaults,
    roomContexts,
    errorMessage: contextSettingsErrorMessage,
    setStore,
  } = useChatContextSettingsRegistry();
  const [selectedChatTypeId, setSelectedChatTypeId] = useState<string | null>(chatTypes[0]?.id ?? null);
  const [isMobileViewport, setIsMobileViewport] = useState(false);
  const [mobileView, setMobileView] = useState<'default-contexts' | 'edit' | 'preview'>('edit');
  const [detailMode, setDetailMode] = useState<'list' | 'detail'>('list');
  const [maximizedPane, setMaximizedPane] = useState<'none' | 'edit' | 'preview'>('none');
  const [isCreating, setIsCreating] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [isReloading, setIsReloading] = useState(false);
  const [saveErrorMessage, setSaveErrorMessage] = useState('');
  const [selectedDefaultContextIds, setSelectedDefaultContextIds] = useState<string[]>([]);
  const [form] = Form.useForm<ChatTypeFormValue>();
  const [modalApi, modalContextHolder] = Modal.useModal();
  const lastHydratedFormKeyRef = useRef('');
  const userRoles = useMemo(() => resolveCurrentChatPermissionRoles(hasAccess), [hasAccess]);
  const isPaneMaximized = maximizedPane !== 'none';
  const builtInChatTypes: ChatTypeRecord[] = [];
  const customChatTypes = chatTypes;
  const nextNewSortOrder = useMemo(
    () => Math.max(0, ...customChatTypes.map((item) => item.sortOrder || 0)) + 1,
    [customChatTypes],
  );

  const selectedChatType = useMemo(
    () => customChatTypes.find((item) => item.id === selectedChatTypeId) ?? null,
    [customChatTypes, selectedChatTypeId],
  );

  useEffect(() => {
    if (selectedChatTypeId && customChatTypes.some((item) => item.id === selectedChatTypeId)) {
      return;
    }

    setSelectedChatTypeId(customChatTypes[0]?.id ?? null);
  }, [customChatTypes, selectedChatTypeId]);

  useEffect(() => {
    if (detailMode !== 'detail') {
      lastHydratedFormKeyRef.current = '';
      return;
    }

    const nextFormKey = isCreating ? '__create__' : selectedChatType?.id ?? '__empty__';

    if (lastHydratedFormKeyRef.current === nextFormKey) {
      return;
    }

    lastHydratedFormKeyRef.current = nextFormKey;
    form.resetFields();
    form.setFieldsValue(toFormValue(isCreating ? null : selectedChatType));
    setSelectedDefaultContextIds(
      isCreating
        ? []
        : resolveChatTypeDefaultContextIds(chatTypeDefaults, selectedChatType?.id).filter((contextId) =>
            defaultContexts.some((context) => context.id === contextId && context.enabled),
          ),
    );
  }, [chatTypeDefaults, defaultContexts, detailMode, form, isCreating, selectedChatType?.id]);

  useEffect(() => {
    if (detailMode !== 'detail') {
      return;
    }

    if (isCreating || selectedChatType) {
      return;
    }

    setDetailMode('list');
  }, [detailMode, isCreating, selectedChatType]);

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }

    const mediaQuery = window.matchMedia('(max-width: 960px)');
    const update = () => {
      setIsMobileViewport(mediaQuery.matches);
      if (!mediaQuery.matches) {
        setMobileView('edit');
      }
    };

    update();
    mediaQuery.addEventListener('change', update);

    return () => {
      mediaQuery.removeEventListener('change', update);
    };
  }, []);

  useEffect(() => {
    if (typeof document === 'undefined' || !isMobileViewport) {
      return;
    }

    const { body, documentElement } = document;
    const previousBodyOverflow = body.style.overflow;
    const previousHtmlOverflow = documentElement.style.overflow;

    body.style.overflow = 'hidden';
    documentElement.style.overflow = 'hidden';

    return () => {
      body.style.overflow = previousBodyOverflow;
      documentElement.style.overflow = previousHtmlOverflow;
    };
  }, [isMobileViewport]);

  const openCreateForm = () => {
    setIsCreating(true);
    setSelectedChatTypeId(null);
    setDetailMode('detail');
    setMaximizedPane('none');
    form.resetFields();
    form.setFieldsValue({
      ...EMPTY_FORM_VALUE,
      sortOrder: nextNewSortOrder,
    });
    setSelectedDefaultContextIds([]);
  };

  const openDetail = (chatTypeId: string) => {
    setIsCreating(false);
    setSelectedChatTypeId(chatTypeId);
    setDetailMode('detail');
    setMaximizedPane('none');
  };

  const closeDetail = () => {
    setIsCreating(false);
    setDetailMode('list');
    setMaximizedPane('none');
  };

  const handleDelete = async () => {
    if (!selectedChatType) {
      return;
    }

    const confirmed = await confirmWithKeyboard(modalApi, {
      title: `"${selectedChatType.name}" 요청 유형을 삭제할까요?`,
      okText: '삭제',
      cancelText: '취소',
      okButtonProps: { danger: true },
    });

    if (!confirmed) {
      return;
    }

    const nextChatTypes = deleteChatType(chatTypes, selectedChatType.id);
    setIsSaving(true);
    setSaveErrorMessage('');

    try {
      const savedSnapshot = await setChatTypes(nextChatTypes);
      setSelectedChatTypeId(savedSnapshot.chatTypes[0]?.id ?? null);
      setIsCreating(false);
      setDetailMode('list');
      form.resetFields();
      form.setFieldsValue({
        ...EMPTY_FORM_VALUE,
        sortOrder: nextNewSortOrder,
      });
    } catch (error) {
      setSaveErrorMessage(error instanceof Error ? error.message : '채팅유형 삭제에 실패했습니다.');
    } finally {
      setIsSaving(false);
    }
  };

  const handleReload = async () => {
    setIsReloading(true);
    setSaveErrorMessage('');

    try {
      await reload();
    } catch (error) {
      setSaveErrorMessage(error instanceof Error ? error.message : '채팅유형 재조회에 실패했습니다.');
    } finally {
      setIsReloading(false);
    }
  };

  const moveChatTypeInList = async (chatTypeId: string, direction: 'up' | 'down') => {
    const currentIndex = customChatTypes.findIndex((item) => item.id === chatTypeId);

    if (currentIndex < 0) {
      return;
    }

    const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1;

    if (targetIndex < 0 || targetIndex >= customChatTypes.length) {
      return;
    }

    const reorderedChatTypes = [...customChatTypes];
    const [movedItem] = reorderedChatTypes.splice(currentIndex, 1);

    reorderedChatTypes.splice(targetIndex, 0, movedItem);

    const nextChatTypes = reorderedChatTypes.map((item, index) => ({
      ...item,
      sortOrder: index + 1,
    }));

    setIsSaving(true);
    setSaveErrorMessage('');
    setChatTypesLocal(nextChatTypes);

    try {
      const savedSnapshot = await setChatTypes(nextChatTypes);
      setSelectedChatTypeId((currentSelectedId) => {
        if (currentSelectedId && savedSnapshot.chatTypes.some((item) => item.id === currentSelectedId)) {
          return currentSelectedId;
        }

        return chatTypeId;
      });
    } catch (error) {
      setChatTypesLocal(customChatTypes);
      setSaveErrorMessage(error instanceof Error ? error.message : '채팅유형 순서 변경에 실패했습니다.');
    } finally {
      setIsSaving(false);
    }
  };

  const detailHeaderActions = (
    <Space size={6} className="chat-type-management-page__header-actions" wrap>
      <Tooltip title={isCreating ? '저장' : '수정 저장'}>
        <Button
          type="primary"
          shape="circle"
          icon={<SaveOutlined />}
          loading={isSaving}
          aria-label={isCreating ? '저장' : '수정 저장'}
          onClick={() => {
            void form.submit();
          }}
        />
      </Tooltip>
      <Tooltip title="새 입력">
        <Button
          shape="circle"
          icon={<PlusOutlined />}
          disabled={isSaving}
          aria-label="새 입력"
          onClick={openCreateForm}
        />
      </Tooltip>
      {!isCreating && selectedChatType ? (
        <Tooltip title="삭제">
          <Button
            danger
            shape="circle"
            icon={<DeleteOutlined />}
            loading={isSaving}
            aria-label="삭제"
            onClick={() => void handleDelete()}
          />
        </Tooltip>
      ) : null}
      <Tooltip title="목록 가기">
        <Button
          shape="circle"
          icon={<UnorderedListOutlined />}
          aria-label="목록 가기"
          onClick={closeDetail}
        />
      </Tooltip>
    </Space>
  );

  if (!hasAccess) {
    return (
      <>
        {modalContextHolder}
        <Card title="채팅유형 관리" className="chat-type-management-page">
          <Alert
            showIcon
            type="warning"
            message="관리 페이지는 토큰 등록 사용자만 사용할 수 있습니다."
            description="설정 > 토큰 관리에서 권한 토큰을 등록한 뒤 채팅유형과 권한을 관리하세요."
          />
        </Card>
      </>
    );
  }

  return (
    <div
      className={`chat-type-management-page${detailMode === 'detail' ? ' chat-type-management-page--detail' : ''}${
        isPaneMaximized ? ' chat-type-management-page--pane-maximized' : ''
      }${isMobileViewport ? ` chat-type-management-page--mobile-view-${mobileView}` : ''}`}
    >
      {modalContextHolder}
      {detailMode === 'list' ? (
      <Card
          title="채팅유형 관리"
          className="chat-type-management-page__card"
          extra={!isMobileViewport ? (
            <Space size={8} wrap>
              <Button icon={<ReloadOutlined />} onClick={() => void handleReload()} loading={isReloading}>
                재조회
              </Button>
              <Button icon={<PlusOutlined />} onClick={openCreateForm}>
                신규 채팅유형
              </Button>
            </Space>
          ) : null}
        >
          <div className="chat-type-management-page__list">
            {errorMessage ? <Alert showIcon type="error" message={errorMessage} /> : null}
            {contextSettingsErrorMessage ? <Alert showIcon type="error" message={contextSettingsErrorMessage} /> : null}
            {saveErrorMessage ? <Alert showIcon type="error" message={saveErrorMessage} /> : null}
            <div className="chat-type-management-page__list-header">
              <Title level={5}>사용자 채팅유형</Title>
              <Text type="secondary">{isLoading ? '불러오는 중' : `${customChatTypes.length}건`}</Text>
            </div>
            {isMobileViewport ? (
              <Space size={8} wrap className="chat-type-management-page__list-actions">
                <Button icon={<ReloadOutlined />} onClick={() => void handleReload()} loading={isReloading}>
                  재조회
                </Button>
                <Button icon={<PlusOutlined />} onClick={openCreateForm}>
                  신규 채팅유형
                </Button>
              </Space>
            ) : null}

            <div className="chat-type-management-page__list-scroll">
              {builtInChatTypes.length > 0 ? (
                <>
                  <Alert
                    showIcon
                    type="info"
                    message="내장 기본 채팅유형은 코드 기준 고정값입니다."
                    description="이 목록은 참조용이며 여기서 수정·삭제되지 않습니다. 추가/삭제 가능한 대상은 아래 사용자 채팅유형입니다."
                  />
                  <List
                    dataSource={builtInChatTypes}
                    renderItem={(item) => {
                      const isCurrentUserAllowed = canUseChatType(item, userRoles);

                      return (
                        <List.Item className="chat-type-management-page__item">
                          <div className="chat-type-management-page__item-main">
                            <Space size={[8, 8]} wrap>
                              <Text strong>{item.name}</Text>
                              <Tag color="gold">내장 기본유형</Tag>
                              <Tag color={item.enabled ? 'green' : 'default'}>{item.enabled ? '사용' : '중지'}</Tag>
                              <Tag color={isCurrentUserAllowed ? 'blue' : 'default'}>
                                {isCurrentUserAllowed ? '현재 사용자 사용 가능' : '현재 사용자 사용 불가'}
                              </Tag>
                            </Space>
                            <div className="chat-type-management-page__item-description">
                              {item.description ? (
                                <MarkdownPreviewContent content={item.description} maxBlocks={3} />
                              ) : (
                                '기본 문맥 설명 없음'
                              )}
                            </div>
                          </div>
                        </List.Item>
                      );
                    }}
                  />
                </>
              ) : null}

              {customChatTypes.length > 0 ? (
                <List
                  dataSource={customChatTypes}
                  renderItem={(item) => {
                    const isCurrentUserAllowed = canUseChatType(item, userRoles);
                    const linkedDefaultContexts = resolveChatTypeDefaultContextIds(chatTypeDefaults, item.id)
                      .map((contextId) => defaultContexts.find((context) => context.id === contextId))
                      .filter((context): context is NonNullable<typeof context> => Boolean(context));
                    const itemIndex = customChatTypes.findIndex((chatType) => chatType.id === item.id);
                    const canMoveUp = itemIndex > 0;
                    const canMoveDown = itemIndex >= 0 && itemIndex < customChatTypes.length - 1;
                    const itemClassName =
                      item.id === selectedChatTypeId
                        ? 'chat-type-management-page__item chat-type-management-page__item--active'
                        : 'chat-type-management-page__item';

                    return (
                      <List.Item className={itemClassName}>
                        <div className="chat-type-management-page__item-main">
                          <Space size={[8, 8]} wrap>
                            <Text strong>{item.name}</Text>
                            <Tag color="cyan">정렬 {item.sortOrder}</Tag>
                            <Tag color={item.enabled ? 'green' : 'default'}>{item.enabled ? '사용' : '중지'}</Tag>
                            <Tag color={isCurrentUserAllowed ? 'blue' : 'default'}>
                              {isCurrentUserAllowed ? '현재 사용자 사용 가능' : '현재 사용자 사용 불가'}
                            </Tag>
                          </Space>
                          <div className="chat-type-management-page__item-description">
                            {item.description ? (
                              <MarkdownPreviewContent content={item.description} maxBlocks={3} />
                            ) : (
                              '기본 문맥 설명 없음'
                            )}
                          </div>
                          <Space size={[6, 6]} wrap>
                            {item.permissions.map((permission) => (
                              <Tag key={`${item.id}-${permission}`}>{CHAT_PERMISSION_ROLE_LABELS[permission]}</Tag>
                            ))}
                            <Tag color="purple">{resolveExecutionPolicyModeLabel(item.executionPolicy.mode)}</Tag>
                            {linkedDefaultContexts.map((context) => (
                              <Tag key={`${item.id}-${context.id}`} color="gold">
                                {context.title}
                              </Tag>
                            ))}
                          </Space>
                          <div className="chat-type-management-page__item-actions">
                            <Button
                              icon={<ArrowUpOutlined />}
                              disabled={isSaving || !canMoveUp}
                              onClick={(event) => {
                                event.stopPropagation();
                                void moveChatTypeInList(item.id, 'up');
                              }}
                            >
                              위로 이동
                            </Button>
                            <Button
                              icon={<ArrowDownOutlined />}
                              disabled={isSaving || !canMoveDown}
                              onClick={(event) => {
                                event.stopPropagation();
                                void moveChatTypeInList(item.id, 'down');
                              }}
                            >
                              아래로 이동
                            </Button>
                            <Button
                              type="default"
                              icon={<EditOutlined />}
                              disabled={isSaving}
                              onClick={(event) => {
                                event.stopPropagation();
                                openDetail(item.id);
                              }}
                            >
                              상세 보기
                            </Button>
                          </div>
                        </div>
                      </List.Item>
                    );
                  }}
                />
              ) : (
                <Empty description="등록된 사용자 채팅유형이 없습니다." />
              )}
            </div>
          </div>
        </Card>
      ) : (
        <Card
          title={isCreating ? '채팅유형 등록' : '채팅유형 상세'}
          className={`chat-type-management-page__card${isPaneMaximized ? ' chat-type-management-page__card--pane-maximized' : ''}`}
          extra={detailHeaderActions}
        >
          <div className="chat-type-management-page__editor">
            {errorMessage ? <Alert showIcon type="error" message={errorMessage} /> : null}
            {contextSettingsErrorMessage ? <Alert showIcon type="error" message={contextSettingsErrorMessage} /> : null}
            {saveErrorMessage ? <Alert showIcon type="error" message={saveErrorMessage} /> : null}

            <Form
              className="chat-type-management-page__editor-form"
              layout="vertical"
              form={form}
              initialValues={EMPTY_FORM_VALUE}
              onFinish={async (values) => {
                const nextChatTypes = upsertChatType(chatTypes, values);
                setIsSaving(true);
                setSaveErrorMessage('');

                try {
                  const savedSnapshot = await setChatTypes(nextChatTypes);
                  const savedChatType = savedSnapshot.chatTypes.find(
                    (item) => item.id === values.id || item.name === values.name,
                  );
                  const nextChatTypeDefaults = savedChatType
                    ? upsertChatTypeDefaultContextSelection(chatTypeDefaults, savedChatType.id, selectedDefaultContextIds)
                    : chatTypeDefaults;
                  await setStore({
                    defaultContexts,
                    chatTypeDefaults: nextChatTypeDefaults,
                    roomContexts,
                  });
                  setIsCreating(false);
                  setSelectedChatTypeId(savedChatType?.id ?? null);
                  setDetailMode('detail');
                } catch (error) {
                  setSaveErrorMessage(error instanceof Error ? error.message : '채팅유형 저장에 실패했습니다.');
                } finally {
                  setIsSaving(false);
                }
              }}
            >
              <Form.Item name="id" hidden>
                <Input />
              </Form.Item>
              <Form.Item name="sortOrder" hidden>
                <Input />
              </Form.Item>
              <div className="chat-type-management-page__editor-scroll">
                <div className={`chat-type-management-page__meta-grid${isPaneMaximized ? ' chat-type-management-page__meta-grid--hidden' : ''}`}>
                  <Form.Item
                    className="chat-type-management-page__meta-item chat-type-management-page__meta-item--name"
                    label="컨텍스트명"
                    name="name"
                    rules={[{ required: true, message: '채팅유형명을 입력하세요.' }]}
                  >
                    <Input placeholder="예: 운영 문의 전용" />
                  </Form.Item>
                  <Form.Item
                    className="chat-type-management-page__meta-item chat-type-management-page__meta-item--permissions"
                    label="사용 권한"
                    name="permissions"
                  >
                    <Checkbox.Group
                      options={[
                        { label: CHAT_PERMISSION_ROLE_LABELS['token-user'], value: 'token-user' },
                        { label: CHAT_PERMISSION_ROLE_LABELS.guest, value: 'guest' },
                      ]}
                    />
                  </Form.Item>
                  <Form.Item
                    className="chat-type-management-page__meta-item chat-type-management-page__meta-item--enabled"
                    label="사용 여부"
                    name="enabled"
                    valuePropName="checked"
                  >
                    <Switch checkedChildren="사용" unCheckedChildren="중지" />
                  </Form.Item>
                </div>
                <div className={`chat-type-management-page__meta-grid${isPaneMaximized ? ' chat-type-management-page__meta-grid--hidden' : ''}`}>
                  <Form.Item
                    className="chat-type-management-page__meta-item"
                    label="실행 정책"
                    name={['executionPolicy', 'mode']}
                  >
                    <Select
                      options={[
                        { value: 'default', label: '직접 구성 · 참가자 역할을 그대로 사용' },
                        { value: 'summary-free-talking', label: '회의 기록자 1명 + 프리토킹 Codex' },
                        { value: 'dispatcher-workers', label: '중계 지시자 1명 + 실작업자' },
                      ]}
                      onChange={(value) => {
                        const nextPolicy = createDefaultChatTypeExecutionPolicy(value as ChatTypeExecutionMode);
                        const currentPolicy = form.getFieldValue('executionPolicy') as ChatTypeExecutionPolicy;
                        form.setFieldsValue({
                          executionPolicy: {
                            ...nextPolicy,
                            reviewPolicy:
                              value === 'dispatcher-workers' ? currentPolicy?.reviewPolicy ?? nextPolicy.reviewPolicy : 'self',
                            resourceReportPolicy: currentPolicy?.resourceReportPolicy ?? nextPolicy.resourceReportPolicy,
                          },
                        });
                      }}
                    />
                  </Form.Item>
                  <Form.Item shouldUpdate noStyle>
                    {({ getFieldValue }) => {
                      const executionMode = (getFieldValue(['executionPolicy', 'mode']) as ChatTypeExecutionMode) ?? 'default';
                      return (
                        <>
                          <Form.Item className="chat-type-management-page__meta-item" label="참가자 자동 배치" name={['executionPolicy', 'participantBinding']}>
                            <Select
                              options={[
                                { value: 'manual', label: '수동 · 참가자 역할을 그대로 사용' },
                                { value: 'first-moderator-rest-conversation', label: '첫 참가자 중재, 나머지 프리토킹/실작업' },
                                { value: 'first-moderator-rest-conversation-last-reviewer', label: '첫 참가자 중재, 마지막 참가자 검토, 나머지 실작업' },
                              ]}
                            />
                          </Form.Item>
                          <Form.Item className="chat-type-management-page__meta-item" label="최종 검토" name={['executionPolicy', 'reviewPolicy']}>
                            <Select
                              disabled={executionMode !== 'dispatcher-workers'}
                              options={[
                                { value: 'self', label: '중재자가 직접 검토 후 종합' },
                                { value: 'reviewer', label: '별도 검토자 지정 후 중재자가 종합' },
                              ]}
                            />
                          </Form.Item>
                          <Form.Item className="chat-type-management-page__meta-item" label="결과물 보고" name={['executionPolicy', 'resourceReportPolicy']}>
                            <Select
                              options={[
                                { value: 'if-generated', label: '산출물이 생긴 경우만 보고' },
                                { value: 'always', label: '항상 결과물/검증 여부 보고' },
                                { value: 'none', label: '별도 resource 보고 없음' },
                              ]}
                            />
                          </Form.Item>
                          <Form.Item className="chat-type-management-page__meta-item" label="중간 개입 허용" name={['executionPolicy', 'allowModeratorIntervention']} valuePropName="checked">
                            <Switch checkedChildren="허용" unCheckedChildren="고정" />
                          </Form.Item>
                          <Form.Item className="chat-type-management-page__meta-item" label="마지막 종합 강제" name={['executionPolicy', 'finalSummaryRequired']} valuePropName="checked">
                            <Switch checkedChildren="강제" unCheckedChildren="선택" />
                          </Form.Item>
                        </>
                      );
                    }}
                  </Form.Item>
                </div>
                {isMobileViewport ? (
                  <Segmented
                    className="chat-type-management-page__mobile-toggle"
                    options={[
                      { label: '입력', value: 'edit' },
                      { label: '미리보기', value: 'preview' },
                      { label: '공통연결', value: 'default-contexts' },
                    ]}
                    value={mobileView}
                    onChange={(value) => {
                      setMobileView(value as 'default-contexts' | 'edit' | 'preview');
                      setMaximizedPane('none');
                    }}
                  />
                ) : null}
                <div
                  className={`chat-type-management-page__default-context-field${isPaneMaximized ? ' chat-type-management-page__default-context-field--hidden' : ''}${
                    isMobileViewport && mobileView === 'default-contexts'
                      ? ' chat-type-management-page__default-context-field--mobile-active'
                      : ''
                  }`}
                >
                  <div className="chat-type-management-page__default-context-header">
                    <Text strong>공통유형 연결</Text>
                    <Text type="secondary">여러 개를 선택하면 채팅 요청마다 함께 참조됩니다.</Text>
                  </div>
                  {defaultContexts.filter((context) => context.enabled).length > 0 ? (
                    <>
                      <Checkbox.Group
                        className="chat-type-management-page__default-context-options"
                        value={selectedDefaultContextIds}
                        onChange={(checkedValues) => {
                          setSelectedDefaultContextIds(
                            checkedValues
                              .map((value) => String(value).trim())
                              .filter((value) => defaultContexts.some((context) => context.id === value && context.enabled)),
                          );
                        }}
                      >
                        <Space direction="vertical" size={10} className="chat-type-management-page__default-context-space">
                          {defaultContexts
                            .filter((context) => context.enabled)
                            .map((context) => (
                              <label key={context.id} className="chat-type-management-page__default-context-option">
                                <Checkbox value={context.id}>{context.title}</Checkbox>
                                <Text type="secondary" className="chat-type-management-page__default-context-option-copy">
                                  {context.content.split('\n')[0]?.replace(/^#+\s*/, '') || '설명 없음'}
                                </Text>
                              </label>
                            ))}
                        </Space>
                      </Checkbox.Group>
                      {selectedDefaultContextIds.length > 0 ? (
                        <div className="chat-type-management-page__default-context-preview">
                          {selectedDefaultContextIds.map((contextId) => {
                            const context = defaultContexts.find((item) => item.id === contextId);

                            return context ? (
                              <Tag key={`preview-${context.id}`} color="gold">
                                {context.title}
                              </Tag>
                            ) : null;
                          })}
                        </div>
                      ) : null}
                    </>
                  ) : (
                    <Alert
                      showIcon
                      type="info"
                      message="등록된 기본 유형이 없습니다."
                      description="채팅 관리 > 기본 유형 관리에서 Markdown 스타일 기본 유형을 먼저 등록하세요."
                    />
                  )}
                </div>
                <div
                  className={`chat-type-management-page__markdown-field${
                    isMobileViewport && mobileView !== 'default-contexts'
                      ? ' chat-type-management-page__markdown-field--mobile-active'
                      : ''
                  }`}
                >
                  <Text strong className="chat-type-management-page__field-label">
                    기본 문맥 설명
                  </Text>
                  <div className="chat-type-management-page__markdown-editor">
                    <div className="chat-type-management-page__editor-toolbar">
                      {isMobileViewport ? null : (
                        <Space size={8} wrap>
                          <Button
                            type={maximizedPane === 'edit' ? 'primary' : 'default'}
                            icon={maximizedPane === 'edit' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                            onClick={() => {
                              setMaximizedPane((current) => (current === 'edit' ? 'none' : 'edit'));
                            }}
                          >
                            {maximizedPane === 'edit' ? '입력 축소' : '입력 최대화'}
                          </Button>
                          <Button
                            type={maximizedPane === 'preview' ? 'primary' : 'default'}
                            icon={maximizedPane === 'preview' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                            onClick={() => {
                              setMaximizedPane((current) => (current === 'preview' ? 'none' : 'preview'));
                            }}
                          >
                            {maximizedPane === 'preview' ? '미리보기 축소' : '미리보기 최대화'}
                          </Button>
                        </Space>
                      )}
                    </div>
                    <div
                      className={`chat-type-management-page__markdown-grid${
                        maximizedPane !== 'none' ? ' chat-type-management-page__markdown-grid--maximized' : ''
                      }`}
                    >
                      <div
                        className={`chat-type-management-page__markdown-pane${
                          isMobileViewport && mobileView === 'preview'
                            ? ' chat-type-management-page__markdown-pane--mobile-hidden'
                            : ''
                        }${
                          maximizedPane === 'preview' ? ' chat-type-management-page__markdown-pane--desktop-hidden' : ''
                        }`}
                      >
                        <div className="chat-type-management-page__markdown-pane-header">
                          <Text type="secondary">입력</Text>
                          {isMobileViewport ? (
                            <Button
                              size="small"
                              type={maximizedPane === 'edit' ? 'primary' : 'default'}
                              icon={maximizedPane === 'edit' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                              onClick={() => {
                                setMaximizedPane((current) => (current === 'edit' ? 'none' : 'edit'));
                              }}
                            >
                              {maximizedPane === 'edit' ? '축소' : '최대화'}
                            </Button>
                          ) : null}
                        </div>
                        <Form.Item name="description" noStyle>
                          <Input.TextArea
                            autoSize={isMobileViewport ? false : { minRows: 10, maxRows: 18 }}
                            className="chat-type-management-page__markdown-textarea"
                            placeholder={
                              '## 기본 처리\n- 이 채팅 유형의 실행 기준을 Markdown으로 정리하세요.\n\n## 검증\n- 모바일 브라우저 캡처/검증 기준\n\n## 구현 기준\n- clean code 원칙'
                            }
                          />
                        </Form.Item>
                      </div>
                      <div
                        className={`chat-type-management-page__markdown-pane${
                          isMobileViewport && mobileView === 'edit'
                            ? ' chat-type-management-page__markdown-pane--mobile-hidden'
                            : ''
                        }${
                          maximizedPane === 'edit' ? ' chat-type-management-page__markdown-pane--desktop-hidden' : ''
                        }`}
                      >
                        <div className="chat-type-management-page__markdown-preview">
                          <div className="chat-type-management-page__markdown-pane-header">
                            <Text type="secondary">미리보기</Text>
                            {isMobileViewport ? (
                              <Button
                                size="small"
                                type={maximizedPane === 'preview' ? 'primary' : 'default'}
                                icon={maximizedPane === 'preview' ? <ShrinkOutlined /> : <ArrowsAltOutlined />}
                                onClick={() => {
                                  setMaximizedPane((current) => (current === 'preview' ? 'none' : 'preview'));
                                }}
                              >
                                {maximizedPane === 'preview' ? '축소' : '최대화'}
                              </Button>
                            ) : null}
                          </div>
                          <div className="chat-type-management-page__markdown-preview-body">
                            <Form.Item noStyle shouldUpdate={(prev, next) => prev.description !== next.description}>
                              {({ getFieldValue }) => {
                                const description = String(getFieldValue('description') ?? '').trim();

                                return description ? (
                                  <MarkdownPreviewContent content={description} />
                                ) : (
                                  <Empty
                                    image={Empty.PRESENTED_IMAGE_SIMPLE}
                                    description="미리보기할 문맥 설명이 없습니다."
                                  />
                                );
                              }}
                            </Form.Item>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </Form>
          </div>
        </Card>
      )}
    </div>
  );
}
