import type { ChatConversationSummary, ChatRuntimeSnapshot } from './types';

const CHAT_LIST_TEXT_SUMMARY_MAX_LENGTH = 240;
const CONVERSATION_TRIVIAL_MESSAGE_PATTERN =
  /^(?:[ㅋㅎ]{1,}|[ㅋㅎ]{2,}[~!?.]*|[ㅇ][ㅋ케예]?|ok(?:ay)?|thanks|thx|감사(?:합니다|해요)?|고마워(?:요)?|넵|네|예|응|웅|ㅇㅇ|ㄴㄴ|ㅎㅎ+|ㅋㅋ+|ㅎㅎㅋㅋ|ㅋㅋㅎㅎ|헉|오|아|음|흠|허허|test|테스트)\s*[~!?.…]*$/iu;

function trimConversationRequestBadgeLabel(label: string, maxLength = 18) {
  const normalized = label.replace(/\s+/g, ' ').trim();

  if (!normalized) {
    return '';
  }

  if (normalized.length <= maxLength) {
    return normalized;
  }

  return `${normalized.slice(0, maxLength - 1).trimEnd()}…`;
}

function compactConversationBadgeLabel(label: string | null | undefined, maxWords = 2) {
  const normalized = (label ?? '').replace(/\s+/g, ' ').trim();

  if (!normalized) {
    return null;
  }

  const words = normalized.split(' ').filter(Boolean);
  return trimConversationRequestBadgeLabel(words.slice(0, maxWords).join(' '));
}

function normalizeConversationPromptFollowupText(text: string | null | undefined) {
  const normalized = String(text ?? '')
    .replace(/\s+/g, ' ')
    .trim();

  if (!normalized) {
    return '';
  }

  const followupMatch = normalized.match(
    /^(?<selection>.+?)\s*기준으로\s+(?:(?:다음\s+단계를?)\s+)?(?:이어서\s+)?진행해\s+주세요\.?$/u,
  );
  const selectedText = followupMatch?.groups?.selection?.trim();

  if (selectedText) {
    return selectedText;
  }

  return normalized;
}

function isConversationTrivialMessage(text: string | null | undefined) {
  const normalized = normalizeConversationPromptFollowupText(text);

  if (!normalized) {
    return true;
  }

  return CONVERSATION_TRIVIAL_MESSAGE_PATTERN.test(normalized);
}

function isConversationPromptFollowupText(text: string | null | undefined) {
  const normalized = String(text ?? '')
    .replace(/\s+/g, ' ')
    .trim();

  return normalized.length > 0 && normalizeConversationPromptFollowupText(normalized) !== normalized;
}

function isConversationBadgeMetaRequest(text: string) {
  const normalized = normalizeConversationPromptFollowupText(text);

  if (!normalized) {
    return false;
  }

  return (
    /((최근|촤근)?\s*작업|최근작업|촤근작업).*(뱃지|badge|라벨)/iu.test(normalized) ||
    /(요청내역|이전\s*요청|마지막\s*요청|두\s*단어|두단어|문맥을\s*읽어서|문맥\s*읽어서)/u.test(normalized)
  );
}

function normalizeConversationBadgeToken(token: string) {
  return token
    .replace(/^[^0-9A-Za-z가-힣/_-]+|[^0-9A-Za-z가-힣/_-]+$/gu, '')
    .replace(/[()[\]{}"'`~!@#$%^&*+=|\\:;,.<>?…]+/g, '')
    .trim();
}

function canonicalizeConversationBadgeToken(token: string) {
  const normalized = normalizeConversationBadgeToken(token)
    .replace(/^(최근작업|촤근작업)$/iu, '작업')
    .replace(/^(대화방|대화)$/u, '채팅')
    .replace(/^(badge|라벨)$/iu, '뱃지')
    .replace(/^(api)$/iu, 'API')
    .replace(/^(command|cmd|명령어)$/iu, 'command')
    .replace(/^(sql)$/iu, 'SQL')
    .replace(/^(db|database)$/iu, 'DB')
    .replace(/^(웹소켓|ws\/chat)$/iu, '소켓')
    .replace(/^(업데이투|업뎃|업데이트)$/iu, '업데이트');

  if (/(codex|cdex)?\s*cli/iu.test(normalized)) {
    return 'CLI';
  }

  if (/^release\/test$/iu.test(normalized)) {
    return '설정';
  }

  if (/^(이전세션|새세션|세션들)$/u.test(normalized)) {
    return '세션';
  }

  return normalized
    .replace(/(입니다|이에요|예요|합니다|해요|해주세요|해주세여|됐나요|되나요|맞나요|인가요|인가|입니다만|입니다요)$/u, '')
    .replace(/(하기|하기를|하기랑|하기와|하거나|하면서|되어서|되게|되도록)$/u, '')
    .replace(/(으로|로|과|와|을|를|은|는|이|가|도|만|랑|이라도|이라던지|라던지|에서|에게|께|마다|부터|까지)$/u, '')
    .trim();
}

const CONVERSATION_BADGE_ACTION_RULES = [
  { label: '재기동', pattern: /(재기동|재시작|재부팅)/iu },
  { label: '업데이트', pattern: /(업데이트|update|업데이투|업뎃)/iu },
  { label: '분리', pattern: /(분리|구분)/iu },
  { label: '수정', pattern: /(수정|고쳐|고치|개선|반영|복구|정리|보완|조정|변경|보정|맞춰|맞추|손봐|손보)/iu },
  { label: '추가', pattern: /(추가|노출|표시|표현|붙여|붙이|삽입|넣어)/iu },
  { label: '생성', pattern: /(생성|만들어|만들기|신규)/iu },
  { label: '시작', pattern: /(시작|개시)/iu },
  { label: '실행', pattern: /(실행|호출|등록|설치|빌드)/iu },
  { label: '확인', pattern: /(확인|점검|검증|테스트|조회|체크)/iu },
  { label: '문의', pattern: /(문의|질문|왜|어떻게|맞나요|되나요|안보이나요|이상한데|\?)/iu },
] as const;

const CONVERSATION_BADGE_QUESTION_LIKE_PATTERN = /(문의|질문|왜|어떻게|맞나요|되나요|안보이나요|이상한데|\?)/iu;
const CONVERSATION_BADGE_STRONG_ACTION_LABELS = new Set(['재기동', '업데이트', '분리', '수정', '추가', '생성', '시작', '실행']);

function isConversationBadgeStopToken(token: string) {
  return /^(최근|촤근|작업|요청|요청내역|이전요청|마지막요청|문맥|읽어서|문의|답변|참조|이유|왜|안보이나요|안보임|일반|처리|대화방|대화|현재|실제|통해서|맞나요|이상한데|개선하세여|수정하는지|생성하는지|실행인지|항목을|어떤|아떤|조합|두개|두단어|단어조합|요청문|업데이투|이후|다시|원인|방식|맞는지|먼저|기준|단계|진행)$/iu.test(
    token,
  );
}

function collectConversationBadgeMeaningfulTokens(text: string) {
  return normalizeConversationPromptFollowupText(text)
    .replace(/[()[\]{}"'`~!@#$%^&*+=|\\:;,.<>?]+/g, ' ')
    .split(/\s+/)
    .map((token) => canonicalizeConversationBadgeToken(token))
    .filter((token) => token.length > 1 && !isConversationBadgeStopToken(token));
}

function findStrongConversationBadgeActionLabel(...texts: Array<string | null | undefined>) {
  for (const text of texts) {
    const normalized = text?.trim();
    if (!normalized) {
      continue;
    }

    for (const rule of CONVERSATION_BADGE_ACTION_RULES) {
      if (CONVERSATION_BADGE_STRONG_ACTION_LABELS.has(rule.label) && rule.pattern.test(normalized)) {
        return rule.label;
      }
    }
  }

  return null;
}

function isConversationInquiryRequest(...texts: Array<string | null | undefined>) {
  const hasQuestionLikeText = texts.some((text) =>
    CONVERSATION_BADGE_QUESTION_LIKE_PATTERN.test(normalizeConversationPromptFollowupText(text)),
  );
  if (!hasQuestionLikeText) {
    return false;
  }

  return !findStrongConversationBadgeActionLabel(...texts);
}

function findConversationBadgeActionLabel(...texts: Array<string | null | undefined>) {
  const strongActionLabel = findStrongConversationBadgeActionLabel(...texts);
  if (strongActionLabel) {
    return strongActionLabel;
  }

  if (isConversationInquiryRequest(...texts)) {
    return '문의';
  }

  for (const text of texts) {
    const normalized = text?.trim();
    if (!normalized) {
      continue;
    }

    for (const rule of CONVERSATION_BADGE_ACTION_RULES) {
      if (!CONVERSATION_BADGE_STRONG_ACTION_LABELS.has(rule.label) && rule.label !== '문의' && rule.pattern.test(normalized)) {
        return rule.label;
      }
    }
  }

  return null;
}

function isProgramImprovementActionLabel(actionLabel: string | null) {
  return actionLabel === '수정' || actionLabel === '추가' || actionLabel === '생성' || actionLabel === '분리' || actionLabel === '업데이트';
}

function isProgramImprovementRequest(...texts: Array<string | null | undefined>) {
  const joinedText = texts
    .map((text) => text?.trim())
    .filter(Boolean)
    .join(' ');
  const actionLabel = findConversationBadgeActionLabel(...texts);

  if (isProgramImprovementActionLabel(actionLabel)) {
    return true;
  }

  return /(프로그램|화면|기능|ui|ux).*(개선|수정|추가|변경|반영|정리|보완|복구|조정|생성|분리|업데이트)/iu.test(joinedText);
}

function normalizeConversationBadgeTargetToken(token: string) {
  if (/^(뱃지|채팅|목록|세션|cbt|소켓|설정|요일|기간|토큰|프록시|캡처|화면|버튼|미리보기|preview|연결|cli)$/iu.test(token)) {
    return token.toUpperCase() === 'CLI' ? 'CLI' : token;
  }

  if (/^release\/test$/iu.test(token)) {
    return '설정';
  }

  if (/^(이어서|계속|새로|최근작업|요청문|단어조합|명령|응답|내용|항목|항목문의)$/u.test(token)) {
    return '';
  }

  return token;
}

function findConversationBadgeTargetLabel(...texts: Array<string | null | undefined>) {
  const weightedTokens = new Map<string, { score: number; firstIndex: number }>();
  let tokenIndex = 0;

  texts.forEach((text, sourceIndex) => {
    const weight = Math.max(1, texts.length - sourceIndex);
    const tokens = collectConversationBadgeMeaningfulTokens(text ?? '')
      .map((token) => normalizeConversationBadgeTargetToken(token))
      .filter((token) => {
        if (!token) {
          return false;
        }

        return !CONVERSATION_BADGE_ACTION_RULES.some((rule) => rule.label === token);
      });

    tokens.forEach((token) => {
      const current = weightedTokens.get(token);
      if (current) {
        current.score += weight;
        return;
      }

      weightedTokens.set(token, { score: weight, firstIndex: tokenIndex });
      tokenIndex += 1;
    });
  });

  const rankedTokens = Array.from(weightedTokens.entries())
    .sort((left, right) => {
      const scoreDiff = right[1].score - left[1].score;
      if (scoreDiff !== 0) {
        return scoreDiff;
      }

      return left[1].firstIndex - right[1].firstIndex;
    })
    .map(([token]) => token);

  const strongPairRules = [
    {
      pattern: /(뱃지|badge|라벨).*(정의|규칙|기준|추론|정리|보정)|((정의|규칙|기준|추론|정리|보정).*(뱃지|badge|라벨))/iu,
      label: '라벨 규칙',
    },
    { pattern: /(최근\s*작업|최근작업|촤근작업).*(뱃지|badge|라벨)/iu, label: '뱃지' },
    { pattern: /(뱃지|badge|라벨)/iu, label: '뱃지' },
    { pattern: /(채팅|대화).*(목록|리스트)/iu, label: '채팅 목록' },
    { pattern: /(최근\s*5개방|최근\s*대화방\s*5개)/u, label: '5개방' },
    { pattern: /((codex|cdex)\s*cli|cli)/iu, label: 'CLI' },
    { pattern: /(소켓|웹소켓|ws\/chat)/iu, label: '소켓' },
    { pattern: /(세션|이전세션|새세션)/u, label: '세션' },
    { pattern: /(cbt)/iu, label: 'CBT' },
    { pattern: /(release\/test|설정)/iu, label: '설정' },
  ] as const;

  const joinedText = texts
    .map((text) => text?.trim())
    .filter(Boolean)
    .join(' ');

  for (const rule of strongPairRules) {
    if (rule.pattern.test(joinedText)) {
      return trimConversationRequestBadgeLabel(rule.label);
    }
  }

  if (rankedTokens.length >= 2) {
    return trimConversationRequestBadgeLabel(rankedTokens.slice(0, 2).join(' '));
  }

  return rankedTokens[0] ? trimConversationRequestBadgeLabel(rankedTokens[0]) : null;
}

function buildConversationTaskDescriptionLabel(text: string) {
  const normalizedText = normalizeConversationPromptFollowupText(text);

  if (isConversationInquiryRequest(normalizedText)) {
    return null;
  }

  const tokens = collectConversationBadgeMeaningfulTokens(normalizedText)
    .map((token) => normalizeConversationBadgeTargetToken(token))
    .filter((token) => {
      if (!token) {
        return false;
      }

      return !CONVERSATION_BADGE_ACTION_RULES.some((rule) => rule.label === token);
    });

  if (tokens.length === 0) {
    return null;
  }

  if (/(뱃지|badge|라벨).*(정의|규칙|기준|추론|정리)|((정의|규칙|기준|추론|정리).*(뱃지|badge|라벨))/iu.test(normalizedText)) {
    return '라벨 규칙';
  }

  const taskTypeTokens = new Set(['API', 'command', 'CLI', 'SQL', 'DB', '로그', '프록시', '소켓']);
  const genericContextTokens = new Set(['응답', '호출', '요청', '설정', '연결', '에러', '오류', '문제', '상태', '흐름']);

  for (let index = 0; index < tokens.length; index += 1) {
    const currentToken = tokens[index];
    if (!taskTypeTokens.has(currentToken)) {
      continue;
    }

    const previousToken = tokens[index - 1];
    if (previousToken && !taskTypeTokens.has(previousToken) && !genericContextTokens.has(previousToken)) {
      return trimConversationRequestBadgeLabel(`${previousToken} ${currentToken}`);
    }

    const nextToken = tokens[index + 1];
    if (nextToken && !taskTypeTokens.has(nextToken) && !genericContextTokens.has(nextToken)) {
      return trimConversationRequestBadgeLabel(`${nextToken} ${currentToken}`);
    }

    return trimConversationRequestBadgeLabel(currentToken);
  }

  return compactConversationBadgeLabel(tokens.join(' '), 2);
}

type BadgeSourceItem = Pick<
  ChatConversationSummary,
  'title' | 'contextLabel' | 'contextDescription' | 'lastMessagePreview' | 'lastRequestPreview' | 'lastResponsePreview'
>;

function sanitizeConversationBadgeFallbackText(text: string | null | undefined) {
  const normalized = normalizeConversationPromptFollowupText(text);
  if (!normalized) {
    return '';
  }

  if (isConversationInquiryRequest(normalized)) {
    return '';
  }

  if (normalized.length <= CHAT_LIST_TEXT_SUMMARY_MAX_LENGTH) {
    return normalized;
  }

  return `${normalized.slice(0, CHAT_LIST_TEXT_SUMMARY_MAX_LENGTH - 3).trimEnd()}...`;
}

function isConversationGenericBadgeFallbackText(text: string) {
  return /^(새\s*대화|기본\s*처리|기본처리|일반\s*요청|기본\s*요청|Codex\s*Live|chat|채팅|기본|다음\s*단계|확인\s*요청)$/iu.test(
    text,
  );
}

function sanitizeConversationBadgeContextFallbackText(text: string | null | undefined) {
  const normalized = sanitizeConversationBadgeFallbackText(text);
  return isConversationGenericBadgeFallbackText(normalized) ? '' : normalized;
}

function sanitizeConversationBadgeTitleFallbackText(text: string | null | undefined) {
  const normalized = sanitizeConversationBadgeFallbackText(text);
  return /^(새\s*대화|Codex\s*Live)$/iu.test(normalized) ? '' : normalized;
}

function buildConversationBadgeSourceTexts(item: BadgeSourceItem, runtimeSummary?: string | null) {
  const requestText = normalizeConversationPromptFollowupText(item.lastRequestPreview);
  const responseText = normalizeConversationPromptFollowupText(item.lastResponsePreview);
  const messageText = normalizeConversationPromptFollowupText(item.lastMessagePreview);
  const contextLabel = sanitizeConversationBadgeContextFallbackText(item.contextLabel);
  const contextDescription = sanitizeConversationBadgeContextFallbackText(item.contextDescription);
  const titleText = sanitizeConversationBadgeTitleFallbackText(item.title);
  const runtimeText = normalizeConversationPromptFollowupText(runtimeSummary);
  const isMetaRequest = isConversationBadgeMetaRequest(requestText);
  const isInquiryRequest = isConversationInquiryRequest(requestText);

  if (isMetaRequest || isInquiryRequest) {
    return [runtimeText, responseText, messageText, titleText, contextDescription, contextLabel];
  }

  return [runtimeText, responseText, requestText, messageText, titleText, contextDescription, contextLabel];
}

function inferConversationRequestBadgeLabel(
  item: Pick<
    ChatConversationSummary,
    | 'title'
    | 'requestBadgeLabel'
    | 'contextLabel'
    | 'contextDescription'
    | 'lastMessagePreview'
    | 'lastRequestPreview'
    | 'lastResponsePreview'
  >,
  runtimeSummary?: string | null,
) {
  const labelSourceTexts = buildConversationBadgeSourceTexts(item, runtimeSummary);
  const requestText = normalizeConversationPromptFollowupText(item.lastRequestPreview);
  const responseText = normalizeConversationPromptFollowupText(item.lastResponsePreview);
  const messageText = normalizeConversationPromptFollowupText(item.lastMessagePreview);
  const contextLabel = sanitizeConversationBadgeContextFallbackText(item.contextLabel);
  const contextDescription = sanitizeConversationBadgeContextFallbackText(item.contextDescription);
  const titleText = sanitizeConversationBadgeTitleFallbackText(item.title);
  const requestActionLabel = findConversationBadgeActionLabel(requestText);
  const actionLabel = findConversationBadgeActionLabel(...labelSourceTexts);
  const targetLabel = findConversationBadgeTargetLabel(...labelSourceTexts);
  const taskDescriptionLabel = buildConversationTaskDescriptionLabel(requestText);

  if (taskDescriptionLabel && requestActionLabel && isConversationPromptFollowupText(item.lastRequestPreview)) {
    return trimConversationRequestBadgeLabel(`${taskDescriptionLabel} ${requestActionLabel}`);
  }

  if (taskDescriptionLabel && actionLabel && isProgramImprovementActionLabel(actionLabel)) {
    return trimConversationRequestBadgeLabel(`${taskDescriptionLabel} ${actionLabel}`);
  }

  if (targetLabel && actionLabel) {
    if (targetLabel === '라벨 규칙') {
      return trimConversationRequestBadgeLabel(`${targetLabel} ${actionLabel}`);
    }

    const targetWords = targetLabel.split(/\s+/).filter(Boolean);
    if (targetWords.includes(actionLabel)) {
      return trimConversationRequestBadgeLabel(targetLabel);
    }

    const primaryTarget = targetWords[targetWords.length - 1] || targetLabel;
    return trimConversationRequestBadgeLabel(`${primaryTarget} ${actionLabel}`);
  }

  if (targetLabel) {
    return trimConversationRequestBadgeLabel(targetLabel);
  }

  if (actionLabel) {
    const fallbackLabel = compactConversationBadgeLabel(
      requestText || responseText || messageText || titleText || contextDescription || contextLabel,
      1,
    );
    return fallbackLabel ? trimConversationRequestBadgeLabel(`${fallbackLabel} ${actionLabel}`) : actionLabel;
  }

  const fallbackLabel = compactConversationBadgeLabel(
    requestText || responseText || messageText || titleText || contextDescription || contextLabel,
    2,
  );
  if (fallbackLabel) {
    return fallbackLabel;
  }

  return isConversationInquiryRequest(requestText) ? '문의' : compactConversationBadgeLabel(requestText, 2);
}

export function resolveConversationRequestBadgeLabelForUserText(args: {
  requestText: string;
  currentMenuLabel?: string | null;
  title?: string | null;
  contextLabel?: string | null;
  contextDescription?: string | null;
}) {
  const normalizedRequestText = normalizeConversationPromptFollowupText(args.requestText);

  if (!normalizedRequestText) {
    return null;
  }

  if (isConversationTrivialMessage(normalizedRequestText)) {
    return null;
  }

  const requestActionLabel = findConversationBadgeActionLabel(normalizedRequestText);
  const taskDescriptionLabel = buildConversationTaskDescriptionLabel(normalizedRequestText);

  if (taskDescriptionLabel && requestActionLabel && isConversationPromptFollowupText(args.requestText)) {
    return trimConversationRequestBadgeLabel(`${taskDescriptionLabel} ${requestActionLabel}`);
  }

  if (args.currentMenuLabel && isProgramImprovementRequest(normalizedRequestText)) {
    return trimConversationRequestBadgeLabel(args.currentMenuLabel);
  }

  if (isConversationInquiryRequest(normalizedRequestText)) {
    const fallbackLabel = compactConversationBadgeLabel(
      sanitizeConversationBadgeTitleFallbackText(args.title) ||
        sanitizeConversationBadgeContextFallbackText(args.contextDescription) ||
        sanitizeConversationBadgeContextFallbackText(args.contextLabel) ||
        sanitizeConversationBadgeTitleFallbackText(args.currentMenuLabel) ||
        '',
      2,
    );

    return fallbackLabel || '문의';
  }

  if (taskDescriptionLabel) {
    return taskDescriptionLabel;
  }

  return inferConversationRequestBadgeLabel({
    title: args.title?.trim() || '',
    requestBadgeLabel: null,
    contextLabel: args.contextLabel?.trim() || '',
    contextDescription: args.contextDescription?.trim() || '',
    lastMessagePreview: '',
    lastRequestPreview: normalizedRequestText,
    lastResponsePreview: '',
  });
}

export function resolveConversationTitleForUserText(args: {
  requestText: string;
  fallbackTitle?: string | null;
}) {
  const normalizedRequestText = normalizeConversationPromptFollowupText(args.requestText);
  const fallbackTitle = args.fallbackTitle?.trim() || '';

  if (!normalizedRequestText) {
    return fallbackTitle || '새 대화';
  }

  if (isConversationTrivialMessage(normalizedRequestText)) {
    return fallbackTitle || '새 대화';
  }

  const requestActionLabel = findConversationBadgeActionLabel(normalizedRequestText);
  const taskDescriptionLabel = buildConversationTaskDescriptionLabel(normalizedRequestText);
  const targetLabel = findConversationBadgeTargetLabel(normalizedRequestText);

  if (taskDescriptionLabel && requestActionLabel && isConversationPromptFollowupText(args.requestText)) {
    return trimConversationRequestBadgeLabel(`${taskDescriptionLabel} ${requestActionLabel}`);
  }

  if (taskDescriptionLabel && requestActionLabel && isProgramImprovementActionLabel(requestActionLabel)) {
    return trimConversationRequestBadgeLabel(`${taskDescriptionLabel} ${requestActionLabel}`);
  }

  if (!taskDescriptionLabel && requestActionLabel) {
    const actionSuffixPattern = new RegExp(`^(?<subject>.+?)(?:으로|로)?\\s+${requestActionLabel}$`, 'u');
    const subjectText = normalizedRequestText.match(actionSuffixPattern)?.groups?.subject?.trim() || '';
    const subjectLabel = compactConversationBadgeLabel(subjectText, 2);

    if (subjectLabel) {
      return trimConversationRequestBadgeLabel(`${subjectLabel} ${requestActionLabel}`);
    }
  }

  if (targetLabel && requestActionLabel) {
    const targetWords = targetLabel.split(/\s+/).filter(Boolean);
    if (targetWords.includes(requestActionLabel)) {
      return trimConversationRequestBadgeLabel(targetLabel);
    }

    const primaryTarget = targetWords[targetWords.length - 1] || targetLabel;
    return trimConversationRequestBadgeLabel(`${primaryTarget} ${requestActionLabel}`);
  }

  if (taskDescriptionLabel) {
    return taskDescriptionLabel;
  }

  if (targetLabel) {
    return trimConversationRequestBadgeLabel(targetLabel);
  }

  return compactConversationBadgeLabel(normalizedRequestText, 2) || fallbackTitle || '새 대화';
}

const TOP_MENU_BADGE_LABELS: Record<string, string> = {
  docs: 'Docs',
  apis: 'API',
  plans: '작업',
  chat: 'Codex Live',
  play: 'Play',
};

function resolvePageTitleSegments(pageTitle?: string | null) {
  const segments = String(pageTitle ?? '')
    .split('/')
    .map((segment) => segment.trim())
    .filter(Boolean);

  return segments.filter((segment, index) => segments.indexOf(segment) === index);
}

export function resolveConversationScreenTitle(pageTitle?: string | null, topMenu?: string | null) {
  const uniqueSegments = resolvePageTitleSegments(pageTitle);
  const pageLabel = uniqueSegments.join(' / ').trim();

  if (pageLabel) {
    return pageLabel;
  }

  const topMenuLabel = TOP_MENU_BADGE_LABELS[String(topMenu ?? '').trim()];
  return topMenuLabel?.trim() || null;
}

export function shouldPreferRequestTitleOverScreenTitle(pageTitle?: string | null, topMenu?: string | null) {
  const screenTitle = resolveConversationScreenTitle(pageTitle, topMenu);

  if (!screenTitle) {
    return true;
  }

  return String(topMenu ?? '').trim() === 'chat' && /^Codex Live(?:\s*\/\s*Codex Live)?$/u.test(screenTitle);
}

export function resolveCurrentMenuRequestLabel(pageTitle?: string | null, topMenu?: string | null) {
  const uniqueSegments = resolvePageTitleSegments(pageTitle);
  const preferredPageLabel = uniqueSegments.at(-1) ?? uniqueSegments[0] ?? '';

  if (preferredPageLabel) {
    return trimConversationRequestBadgeLabel(preferredPageLabel);
  }

  const topMenuLabel = TOP_MENU_BADGE_LABELS[String(topMenu ?? '').trim()];
  return topMenuLabel ? trimConversationRequestBadgeLabel(topMenuLabel) : null;
}

export function toRuntimeStatusTime(value: string | null | undefined) {
  if (!value) {
    return 0;
  }

  const parsed = Date.parse(value);
  return Number.isFinite(parsed) ? parsed : 0;
}

function resolveRuntimeItemStatusTime(
  item:
    | ChatRuntimeSnapshot['running'][number]
    | ChatRuntimeSnapshot['queued'][number]
    | ChatRuntimeSnapshot['recent'][number],
) {
  if ('lastUpdatedAt' in item) {
    return toRuntimeStatusTime(item.lastUpdatedAt);
  }

  if (item.status === 'running') {
    return toRuntimeStatusTime(item.startedAt ?? item.enqueuedAt);
  }

  return toRuntimeStatusTime(item.enqueuedAt);
}

export function buildConversationRequestBadgeLabel(
  item: Pick<
    ChatConversationSummary,
    | 'sessionId'
    | 'title'
    | 'requestBadgeLabel'
    | 'currentJobStatus'
    | 'contextLabel'
    | 'contextDescription'
    | 'lastMessagePreview'
    | 'lastRequestPreview'
    | 'lastResponsePreview'
  >,
  runtimeSnapshot: ChatRuntimeSnapshot | null,
) {
  const explicitLabel = trimConversationRequestBadgeLabel(item.requestBadgeLabel ?? '');

  if (explicitLabel) {
    return explicitLabel;
  }

  if (!runtimeSnapshot) {
    return inferConversationRequestBadgeLabel(item);
  }

  const latestRuntimeItem = [...runtimeSnapshot.running, ...runtimeSnapshot.queued, ...runtimeSnapshot.recent]
    .filter((runtimeItem) => runtimeItem.sessionId === item.sessionId)
    .sort((left, right) => resolveRuntimeItemStatusTime(right) - resolveRuntimeItemStatusTime(left))[0];

  const runtimeSummary = latestRuntimeItem?.summary?.trim() || '';
  const inferredLabel = inferConversationRequestBadgeLabel(item, runtimeSummary);

  if (item.currentJobStatus === 'queued' || item.currentJobStatus === 'started') {
    return inferredLabel || '작업중';
  }

  if (inferredLabel) {
    return inferredLabel;
  }

  return runtimeSummary ? compactConversationBadgeLabel(runtimeSummary, 3) : null;
}
