// desktop/src/react/utils/screenshot.ts
import { useStore } from '../stores';
import { selectSelectedIdsBySession } from '../stores/session-selectors';
import { extractScreenshotPayload, buildThemeName } from './screenshot-extract';
import type { ChatMessage } from '../stores/chat-types';
import {
  appendConnectionAuth,
  buildConnectionUrl,
  createLocalServerConnection,
} from '../services/server-connection';

function getErrorMessage(err: unknown): string {
  return err instanceof Error ? err.message : String(err);
}

function dispatchInlineNotice(text: string, type: 'success' | 'error', deskDir?: string) {
  window.dispatchEvent(new CustomEvent('hana-inline-notice', {
    detail: { text, type, deskDir },
  }));
}

/**
 * 截图指定消息并保存到文件（离屏渲染管线）。
 */
export async function takeScreenshot(targetMessageId: string, sessionPath: string): Promise<void> {
  const state = useStore.getState();
  const ids = selectSelectedIdsBySession(state, sessionPath);
  const messageIds = ids.length > 0 ? ids : [targetMessageId];

  // 1. 从 store 提取消息数据
  const session = state.chatSessions[sessionPath];
  if (!session) return;

  const messages: ChatMessage[] = [];
  for (const item of session.items) {
    if (item.type !== 'message') continue;
    if (messageIds.includes(item.data.id)) {
      messages.push(item.data);
    }
  }
  if (messages.length === 0) return;

  // 2. 读取截图设置
  const color = localStorage.getItem('hana-screenshot-color') || 'light';
  const width = localStorage.getItem('hana-screenshot-width') || 'mobile';
  const theme = buildThemeName(color, width);

  // 3. 提取 payload
  const payload = extractScreenshotPayload(messages, theme) as any;
  payload.saveDir = state.homeFolder || null;

  // 4. 填充角色名和头像（conversation 模式）
  if (payload.messages) {
    const globalAgentName = state.agentName || 'Hanako';
    const userName = state.userName || '';
    const agentId = state.currentAgentId;

    for (const msg of payload.messages) {
      if (msg.role === 'assistant') {
        msg.name = globalAgentName;
        try {
          msg.avatarDataUrl = await fetchAvatarAsDataUrl('assistant', agentId);
        } catch { /* fallback null */ }
      } else {
        msg.name = userName || '我';
        try {
          msg.avatarDataUrl = await fetchAvatarAsDataUrl('user', null);
        } catch { /* fallback null */ }
      }

      // 图片 filePath → base64 data URL
      for (const block of msg.blocks) {
        if (block.type === 'image' && block.content && !block.content.startsWith('data:')) {
          try {
            block.content = await fetchImageAsDataUrl(block.content);
          } catch { /* 图片加载失败跳过 */ }
        }
      }
    }
  }

  // 5. IPC 调用
  const t = window.t ?? ((p: string) => p);
  const hana = (window as any).hana;
  if (!hana?.screenshotRender) {
    dispatchInlineNotice(t('common.screenshotFailed'), 'error');
    return;
  }

  try {
    const result = await hana.screenshotRender(payload);
    if (result.success) {
      dispatchInlineNotice(t('common.screenshotSaved'), 'success', result.dir);
    } else {
      dispatchInlineNotice(`${t('common.screenshotFailed')}: ${result.error}`, 'error');
    }
  } catch (err) {
    dispatchInlineNotice(`${t('common.screenshotFailed')}: ${getErrorMessage(err)}`, 'error');
  }
}

/**
 * Markdown 编辑器截图（纯文章模式）。
 */
export async function takeArticleScreenshot(markdown: string): Promise<void> {
  const color = localStorage.getItem('hana-screenshot-color') || 'light';
  const width = localStorage.getItem('hana-screenshot-width') || 'mobile';
  const theme = buildThemeName(color, width);

  const t = window.t ?? ((p: string) => p);
  const hana = (window as any).hana;
  if (!hana?.screenshotRender) {
    dispatchInlineNotice(t('common.screenshotFailed'), 'error');
    return;
  }

  const homeFolder = useStore.getState().homeFolder || null;
  try {
    const result = await hana.screenshotRender({
      mode: 'article',
      theme,
      markdown,
      saveDir: homeFolder,
    });

    if (result.success) {
      dispatchInlineNotice(t('common.screenshotSaved'), 'success', result.dir);
    } else {
      dispatchInlineNotice(`${t('common.screenshotFailed')}: ${result.error}`, 'error');
    }
  } catch (err) {
    dispatchInlineNotice(`${t('common.screenshotFailed')}: ${getErrorMessage(err)}`, 'error');
  }
}

// ── 辅助：fetch 图片转 data URL ──

async function fetchImageAsDataUrl(filePath: string): Promise<string> {
  const url = window.platform?.getFileUrl?.(filePath) ?? '';
  const resp = await fetch(url);
  const blob = await resp.blob();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = () => reject(reader.error);
    reader.readAsDataURL(blob);
  });
}

async function fetchAvatarAsDataUrl(role: string, agentId: string | null): Promise<string | null> {
  const port = await (window as any).hana?.getServerPort?.();
  const token = await (window as any).hana?.getServerToken?.();
  const connection = createLocalServerConnection({ serverPort: port, serverToken: token });
  if (!connection || !connection.token) return null;

  const path = role === 'user'
    ? '/api/avatar/user'
    : `/api/agents/${agentId}/avatar`;

  const resp = await fetch(buildConnectionUrl(connection, path), {
    headers: appendConnectionAuth(connection),
  });
  if (!resp.ok) return null;
  const blob = await resp.blob();
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = () => resolve(null);
    reader.readAsDataURL(blob);
  });
}
