import type { ProjectDiscoveryPage, ProjectFolderPage } from "../projectDiscovery.js";

export type ProjectOnboardingView =
  | { readonly mode: "search"; readonly result: ProjectDiscoveryPage }
  | { readonly mode: "browse"; readonly result: ProjectFolderPage };

export interface ProjectOnboardingActionValue {
  readonly action:
    | "create_project_from_chat"
    | "bind_project"
    | "browse_folder"
    | "search_page"
    | "rename_project"
    | "select_agent_role"
    | "new_agent_session"
    | "show_session_history"
    | "resume_agent_session"
    | "compact_agent_session"
    | "browse_move_destination"
    | "move_project"
    | "create_folder";
  readonly organization_id: string;
  readonly project_id?: string | undefined;
  readonly folder_id?: string | undefined;
  readonly search_query?: string | undefined;
  readonly page?: number | undefined;
  readonly agent_role_id?: string | undefined;
  readonly session_id?: string | undefined;
}

export function buildUnboundChatOnboardingCard(params: {
  readonly organizationId: string;
  readonly organizationName: string;
  readonly canCreateProject: boolean;
  readonly view: ProjectOnboardingView;
}): Record<string, unknown> {
  const elements: unknown[] = [{
    tag: "markdown",
    content: onboardingSummary(params.organizationName, params.view),
  }];

  if (params.view.mode === "browse") {
    appendFolderNavigation(elements, params.organizationId, params.view.result);
  }
  appendProjectResults(
    elements,
    params.organizationId,
    params.view.mode === "search" ? params.view.result.items : params.view.result.projects,
  );
  appendPagination(elements, params.organizationId, params.view);
  appendCreation(elements, params.organizationId, params.canCreateProject, params.view);

  if (elements.length === 1) {
    elements.push({ tag: "markdown", content: "当前目录没有可浏览内容。" });
  }
  return {
    config: { wide_screen_mode: true },
    header: { title: { tag: "plain_text", content: "绑定项目" }, template: "blue" },
    elements,
  };
}

export function buildProjectOnboardingResolvedCard(params: {
  readonly title: string;
  readonly body: string;
  readonly template: "green" | "red";
}): Record<string, unknown> {
  return {
    config: { wide_screen_mode: true },
    header: { title: { tag: "plain_text", content: params.title }, template: params.template },
    elements: [{ tag: "markdown", content: params.body }],
  };
}

export function buildProjectManagementCard(params: {
  readonly organizationId: string;
  readonly projectId: string;
  readonly projectName: string;
  readonly title?: string | undefined;
  readonly breadcrumb?: string | undefined;
  readonly selectedRole?: { readonly id: string; readonly roleId: string; readonly label: string } | undefined;
  readonly roles?: readonly { readonly id: string; readonly roleId: string; readonly label: string }[] | undefined;
  readonly currentSession?: {
    readonly id: string;
    readonly title: string | null;
    readonly updatedAt: Date;
    readonly runCount: number;
    readonly sdkSessionReady: boolean;
  } | null | undefined;
  readonly canManageProject?: boolean | undefined;
}): Record<string, unknown> {
  const elements: unknown[] = [{
    tag: "markdown",
    content: [
      `当前项目: **${escapeMarkdown(params.projectName)}**`,
      `所在目录: **${escapeMarkdown(params.breadcrumb ?? "根目录")}**`,
      params.selectedRole === undefined
        ? "当前角色: **未配置**"
        : `当前角色: **${escapeMarkdown(params.selectedRole.label)}**`,
      sessionSummary(params.currentSession),
    ].join("\n"),
  }];
  const roles = params.roles ?? [];
  if (roles.length > 0) {
    elements.push({ tag: "markdown", content: "**切换角色**" });
    for (let index = 0; index < roles.length; index += 5) {
      elements.push({
        tag: "action",
        actions: roles.slice(index, index + 5).map((role) => actionButton(
          role.id === params.selectedRole?.id ? `✓ ${role.label}` : role.label,
          {
            action: "select_agent_role",
            organization_id: params.organizationId,
            project_id: params.projectId,
            agent_role_id: role.id,
          },
          role.id === params.selectedRole?.id ? "primary" : "default",
        )),
      });
    }
  }
  const sessionActions = [
    actionButton("新开会话", {
      action: "new_agent_session", organization_id: params.organizationId, project_id: params.projectId,
    }),
    actionButton("历史会话", {
      action: "show_session_history", organization_id: params.organizationId, project_id: params.projectId,
    }),
  ];
  if (params.currentSession?.sdkSessionReady === true) {
    sessionActions.push(actionButton("压缩上下文", {
      action: "compact_agent_session", organization_id: params.organizationId, project_id: params.projectId,
    }));
  }
  elements.push(
    { tag: "markdown", content: "**当前角色会话**" },
    { tag: "action", actions: sessionActions },
  );
  if (params.canManageProject === true) {
    elements.push(
      { tag: "markdown", content: "**项目管理**" },
      { tag: "action", actions: [actionButton("移动项目", {
        action: "browse_move_destination",
        organization_id: params.organizationId,
        project_id: params.projectId,
        page: 1,
      })] },
      renameProjectForm(params),
    );
  }
  return {
    config: { wide_screen_mode: true },
    header: {
      title: { tag: "plain_text", content: params.title ?? "项目管理" },
      template: "green",
    },
    elements,
  };
}

export function buildSessionHistoryCard(params: {
  readonly organizationId: string;
  readonly projectId: string;
  readonly roleLabel: string;
  readonly sessions: readonly {
    readonly id: string;
    readonly title: string | null;
    readonly updatedAt: Date;
    readonly runCount: number;
  }[];
}): Record<string, unknown> {
  const elements: unknown[] = [{ tag: "markdown", content: `角色: **${escapeMarkdown(params.roleLabel)}**` }];
  if (params.sessions.length === 0) elements.push({ tag: "markdown", content: "没有可恢复的历史会话。" });
  for (const session of params.sessions) {
    elements.push(
      {
        tag: "markdown",
        content: `**${escapeMarkdown(session.title ?? "未命名会话")}**\n${session.runCount} runs · ${formatDate(session.updatedAt)}`,
      },
      { tag: "action", actions: [actionButton("恢复此会话", {
        action: "resume_agent_session",
        organization_id: params.organizationId,
        project_id: params.projectId,
        session_id: session.id,
      }, "primary")] },
    );
  }
  return {
    config: { wide_screen_mode: true },
    header: { title: { tag: "plain_text", content: "历史会话" }, template: "blue" },
    elements,
  };
}

export function buildMoveProjectCard(params: {
  readonly organizationId: string;
  readonly projectId: string;
  readonly projectName: string;
  readonly folderId: string | null;
  readonly parentFolderId: string | null;
  readonly breadcrumb: string;
  readonly childFolders: readonly { readonly id: string; readonly name: string }[];
  readonly canCreateFolder: boolean;
}): Record<string, unknown> {
  const navigation: unknown[] = [];
  if (params.folderId !== null) {
    navigation.push(actionButton("⬆ 上一级", {
      action: "browse_move_destination",
      organization_id: params.organizationId,
      project_id: params.projectId,
      ...(params.parentFolderId !== null ? { folder_id: params.parentFolderId } : {}),
    }));
  }
  for (const folder of params.childFolders) {
    navigation.push(actionButton(`📁 ${buttonLabel(folder.name, 22)}`, {
      action: "browse_move_destination",
      organization_id: params.organizationId,
      project_id: params.projectId,
      folder_id: folder.id,
    }));
  }
  const elements: unknown[] = [
    { tag: "markdown", content: `移动 **${escapeMarkdown(params.projectName)}**\n当前位置: **${escapeMarkdown(params.breadcrumb)}**` },
  ];
  for (let index = 0; index < navigation.length; index += 5) {
    elements.push({ tag: "action", actions: navigation.slice(index, index + 5) });
  }
  elements.push({ tag: "action", actions: [actionButton("移动到这里", {
    action: "move_project",
    organization_id: params.organizationId,
    project_id: params.projectId,
    ...(params.folderId !== null ? { folder_id: params.folderId } : {}),
  }, "primary")] });
  if (params.canCreateFolder) {
    elements.push(createFolderAndMoveForm({
      organizationId: params.organizationId,
      projectId: params.projectId,
      parentFolderId: params.folderId,
    }));
  }
  return {
    config: { wide_screen_mode: true },
    header: { title: { tag: "plain_text", content: "移动项目" }, template: "blue" },
    elements,
  };
}

export function projectOnboardingActionFromValue(value: unknown): ProjectOnboardingActionValue | null {
  const raw = unwrapValue(value);
  if (typeof raw !== "object" || raw === null || Array.isArray(raw) || !("project_onboarding" in raw)) return null;
  const action = raw.project_onboarding;
  if (typeof action !== "object" || action === null || Array.isArray(action)) return null;
  const fields = action as Record<string, unknown>;
  const rawAction = fields.action;
  const organizationId = fields.organization_id;
  const projectId = fields.project_id;
  const folderId = fields.folder_id;
  const searchQuery = fields.search_query;
  const page = fields.page;
  const agentRoleId = fields.agent_role_id;
  const sessionId = fields.session_id;
  if (!isAction(rawAction) || typeof organizationId !== "string" || organizationId === "") return null;
  if ((rawAction === "bind_project" || rawAction === "rename_project") && (typeof projectId !== "string" || projectId === "")) return null;
  if (rawAction === "search_page" && (typeof searchQuery !== "string" || !validPage(page))) return null;
  if (folderId !== undefined && (typeof folderId !== "string" || folderId === "")) return null;
  if (page !== undefined && !validPage(page)) return null;
  if (rawAction === "select_agent_role" && (typeof agentRoleId !== "string" || agentRoleId === "")) return null;
  if (rawAction === "resume_agent_session" && (typeof sessionId !== "string" || sessionId === "")) return null;
  return {
    action: rawAction,
    organization_id: organizationId,
    ...(typeof projectId === "string" && projectId !== "" ? { project_id: projectId } : {}),
    ...(typeof folderId === "string" && folderId !== "" ? { folder_id: folderId } : {}),
    ...(typeof searchQuery === "string" ? { search_query: searchQuery.slice(0, 100) } : {}),
    ...(typeof page === "number" ? { page } : {}),
    ...(typeof agentRoleId === "string" && agentRoleId !== "" ? { agent_role_id: agentRoleId } : {}),
    ...(typeof sessionId === "string" && sessionId !== "" ? { session_id: sessionId } : {}),
  };
}

function onboardingSummary(organizationName: string, view: ProjectOnboardingView): string {
  if (view.mode === "search") {
    const result = view.result;
    return [
      "这个飞书群还没有绑定项目。",
      "",
      `组织: **${escapeMarkdown(organizationName)}**`,
      `搜索: **${escapeMarkdown(result.query)}**`,
      result.totalItems === 0
        ? "没有匹配的可绑定项目，请换一个关键词。"
        : `共 **${result.totalItems}** 个匹配结果 · 第 **${result.page}/${result.totalPages}** 页`,
    ].join("\n");
  }
  const location = view.result.breadcrumb === "" ? "根目录" : view.result.breadcrumb;
  return [
    "这个飞书群还没有绑定项目。",
    "",
    `组织: **${escapeMarkdown(organizationName)}**`,
    `当前位置: **${escapeMarkdown(location)}**`,
    "可以进入 folder 浏览，或选择有管理权限的未绑定项目。",
  ].join("\n");
}

function appendFolderNavigation(elements: unknown[], organizationId: string, result: ProjectFolderPage): void {
  const navigation: unknown[] = [];
  if (result.folderId !== null) {
    navigation.push(actionButton("⬆ 上一级", {
      action: "browse_folder",
      organization_id: organizationId,
      ...(result.parentFolderId !== null ? { folder_id: result.parentFolderId } : {}),
      page: 1,
    }));
  }
  for (const folder of result.childFolders) {
    navigation.push(actionButton(`📁 ${buttonLabel(folder.name, 22)}`, {
      action: "browse_folder",
      organization_id: organizationId,
      folder_id: folder.folderId,
      page: 1,
    }));
  }
  for (let index = 0; index < navigation.length; index += 5) {
    elements.push({ tag: "action", actions: navigation.slice(index, index + 5) });
  }
}

function appendProjectResults(
  elements: unknown[],
  organizationId: string,
  projects: readonly ProjectDiscoveryPage["items"][number][],
): void {
  for (const project of projects) {
    const path = project.breadcrumb === "" ? "根目录" : project.breadcrumb;
    elements.push({
      tag: "markdown",
      content: `**${escapeMarkdown(project.name)}**\n${escapeMarkdown(path)}`,
    });
    elements.push({
      tag: "action",
      actions: [actionButton("绑定这个项目", {
        action: "bind_project",
        organization_id: organizationId,
        project_id: project.projectId,
      })],
    });
  }
}

function appendPagination(elements: unknown[], organizationId: string, view: ProjectOnboardingView): void {
  const result = projectPage(view);
  if (result.totalPages <= 1) return;
  const actions: unknown[] = [];
  if (result.page > 1) actions.push(pageButton("上一页", organizationId, view, result.page - 1));
  if (result.page < result.totalPages) actions.push(pageButton("下一页", organizationId, view, result.page + 1));
  elements.push({ tag: "action", actions });
}

function appendCreation(
  elements: unknown[],
  organizationId: string,
  canCreateProject: boolean,
  view: ProjectOnboardingView,
): void {
  if (!canCreateProject || view.mode !== "browse") return;
  elements.push({
    tag: "action",
    actions: [actionButton(view.result.folderId === null ? "新建项目" : "在此 folder 新建项目", {
      action: "create_project_from_chat",
      organization_id: organizationId,
      ...(view.result.folderId !== null ? { folder_id: view.result.folderId } : {}),
    }, "primary")],
  });
}

function pageButton(label: string, organizationId: string, view: ProjectOnboardingView, page: number): unknown {
  if (view.mode === "search") {
    return actionButton(label, {
      action: "search_page",
      organization_id: organizationId,
      search_query: view.result.query,
      page,
    });
  }
  return actionButton(label, {
    action: "browse_folder",
    organization_id: organizationId,
    ...(view.result.folderId !== null ? { folder_id: view.result.folderId } : {}),
    page,
  });
}

function projectPage(view: ProjectOnboardingView): ProjectDiscoveryPage {
  if (view.mode === "search") return view.result;
  return {
    query: "",
    page: view.result.page,
    pageSize: view.result.pageSize,
    totalItems: view.result.totalFolders + view.result.totalProjects,
    totalPages: view.result.totalPages,
    items: view.result.projects,
  };
}

function renameProjectForm(params: {
  readonly organizationId: string;
  readonly projectId: string;
  readonly projectName: string;
}): unknown {
  return {
    tag: "form",
    name: "project_rename_form",
    fallback: {
      tag: "fallback_text",
      text: { tag: "plain_text", content: "请升级飞书客户端后修改项目名称。" },
    },
    elements: [
      {
        tag: "input",
        name: "project_name",
        required: true,
        max_length: 100,
        default_value: params.projectName,
        placeholder: { tag: "plain_text", content: "请输入项目名称" },
      },
      {
        tag: "button",
        name: "project_rename_submit",
        text: { tag: "plain_text", content: "保存项目名称" },
        type: "primary",
        complex_interaction: true,
        action_type: "form_submit",
        value: { project_onboarding: {
          action: "rename_project",
          organization_id: params.organizationId,
          project_id: params.projectId,
        } },
      },
    ],
  };
}

function createFolderAndMoveForm(params: {
  readonly organizationId: string;
  readonly projectId: string;
  readonly parentFolderId: string | null;
}): unknown {
  return {
    tag: "form",
    name: "folder_create_form",
    elements: [
      {
        tag: "input",
        name: "folder_name",
        required: true,
        max_length: 100,
        placeholder: { tag: "plain_text", content: "在当前目标目录下新建 Folder" },
      },
      {
        tag: "button",
        name: "folder_create_submit",
        text: { tag: "plain_text", content: "新建并移动" },
        type: "default",
        complex_interaction: true,
        action_type: "form_submit",
        value: { project_onboarding: {
          action: "create_folder",
          organization_id: params.organizationId,
          project_id: params.projectId,
          ...(params.parentFolderId !== null ? { folder_id: params.parentFolderId } : {}),
        } },
      },
    ],
  };
}

function sessionSummary(session: {
  readonly title: string | null;
  readonly updatedAt: Date;
  readonly runCount: number;
} | null | undefined): string {
  if (session === null || session === undefined) return "当前会话: **尚未开始**";
  return `当前会话: **${escapeMarkdown(session.title ?? "未命名会话")}** · ${session.runCount} runs · ${formatDate(session.updatedAt)}`;
}

function formatDate(value: Date): string {
  return new Intl.DateTimeFormat("zh-CN", {
    timeZone: "Asia/Shanghai",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  }).format(value);
}

function actionButton(
  label: string,
  value: ProjectOnboardingActionValue,
  type: "default" | "primary" = "default",
): unknown {
  return {
    tag: "button",
    text: { tag: "plain_text", content: label },
    type,
    value: { project_onboarding: value },
  };
}

function isAction(value: unknown): value is ProjectOnboardingActionValue["action"] {
  return value === "create_project_from_chat" || value === "bind_project"
    || value === "browse_folder" || value === "search_page" || value === "rename_project"
    || value === "select_agent_role" || value === "new_agent_session"
    || value === "show_session_history" || value === "resume_agent_session"
    || value === "compact_agent_session" || value === "browse_move_destination"
    || value === "move_project" || value === "create_folder";
}

function validPage(value: unknown): value is number {
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 1 && value <= 10_000;
}

function unwrapValue(value: unknown): unknown {
  if (typeof value !== "string") return value;
  try { return JSON.parse(value); } catch { return value; }
}

function buttonLabel(label: string, maxLength: number): string {
  return label.length <= maxLength ? label : `${label.slice(0, maxLength - 3)}...`;
}

function escapeMarkdown(value: string): string {
  return value.replace(/([`*_{}[\]<>])/g, "\\$1");
}
