import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

import { POST_MESSAGE_TYPES, sendToParent } from "@/core/iframe-messages";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

/** Shared class for external links (underline by default). */
export const externalLinkClass =
  "text-primary underline underline-offset-2 hover:no-underline";
/** Link style without underline by default (e.g. for streaming/loading). */
export const externalLinkClassNoUnderline = "text-primary hover:underline";

/**
 * Copy text to clipboard, using postMessage when in iframe.
 * In iframe context, sends message to parent window to handle clipboard operation.
 */
export async function copyToClipboard(text: string): Promise<void> {
  const isInIframe = window.self !== window.top;
  const message = {
    type: POST_MESSAGE_TYPES.COPY_TO_CLIPBOARD,
    text,
  } as const;

  if (isInIframe) {
    try {
      // Request parent window to copy
      sendToParent(message);
      console.log(
        "[copyToClipboard] iframe mode → postMessage to parent",
        message,
      );
      return;
    } catch (error) {
      console.warn("[copyToClipboard] iframe postMessage failed", error);
    }
  }

  // Direct clipboard access when not in iframe
  console.log("[copyToClipboard] direct mode", message);
  await navigator.clipboard.writeText(text);
}

/**
 * 计算字符串的视觉宽度（中文算2，英文算1）
 */
export function getVisualWidth(text: string): number {
  let width = 0;
  for (const char of text) {
    // 中文字符范围：\u4e00-\u9fff（基本汉字）
    width += /[\u4e00-\u9fff]/.test(char) ? 2 : 1;
  }
  return width;
}

/**
 * 截断字符串中间部分，保留开头和结尾
 * 例如: "very-long-file-name.txt" -> "very-lon...me.txt"
 * 中文按视觉宽度计算（中文算2，英文算1）
 */
export function truncateMiddle(text: string, maxVisualWidth = 30): string {
  const visualWidth = getVisualWidth(text);
  if (visualWidth <= maxVisualWidth) return text;

  const startWidth = Math.ceil(maxVisualWidth * 0.6);
  const endWidth = Math.floor(maxVisualWidth * 0.4) - 3; // -3 for "..."

  let startPart = "";
  let currentWidth = 0;
  for (const char of text) {
    const charWidth = /[\u4e00-\u9fff]/.test(char) ? 2 : 1;
    if (currentWidth + charWidth > startWidth) break;
    startPart += char;
    currentWidth += charWidth;
  }

  let endPart = "";
  currentWidth = 0;
  for (let i = text.length - 1; i >= 0; i--) {
    const char = text[i]!;
    const charWidth = /[\u4e00-\u9fff]/.test(char) ? 2 : 1;
    if (currentWidth + charWidth > endWidth) break;
    endPart = char + endPart;
    currentWidth += charWidth;
  }

  return `${startPart}...${endPart}`;
}
