import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "enterprise-culture",
  version: "2.0.0",
});

const BASE_URL =
  process.env.ENTERPRISE_CULTURE_BASE_URL || "http://192.168.2.55:8089";
const TOKEN = process.env.ENTERPRISE_CULTURE_TOKEN || process.env.CODE_LOGIN_TOKEN || "";

function buildUrl(path) {
  const normalizedBase = BASE_URL.replace(/\/+$/, "");
  const normalizedPath = path.startsWith("/") ? path : `/${path}`;
  return `${normalizedBase}${normalizedPath}`;
}

async function requestCultureApi({ path, method = "POST", body }) {
  const headers = {
    "Content-Type": "application/json",
  };
  if (TOKEN) headers.Authorization = TOKEN;

  const response = await fetch(buildUrl(path), {
    method,
    headers,
    body: body ? JSON.stringify(body) : undefined,
  });

  let payload = null;
  try {
    payload = await response.json();
  } catch {
    payload = null;
  }

  if (!response.ok) {
    return {
      ok: false,
      message: payload?.message || payload?.error || `HTTP ${response.status}`,
      payload,
    };
  }

  const bizError = payload?.error || payload?.msg;
  if (bizError && !payload?.data && !payload?.list) {
    return { ok: false, message: bizError, payload };
  }

  return { ok: true, payload };
}

function getMaybeList(payload) {
  if (Array.isArray(payload?.list)) return payload.list;
  if (Array.isArray(payload?.data?.list)) return payload.data.list;
  if (Array.isArray(payload?.data?.records)) return payload.data.records;
  if (Array.isArray(payload?.records)) return payload.records;
  return [];
}

function okText(title, value) {
  return {
    content: [
      {
        type: "text",
        text: `${title}\n${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`,
      },
    ],
  };
}

function failText(message, payload) {
  return {
    content: [
      {
        type: "text",
        text: `请求失败: ${message}\n${JSON.stringify(payload ?? {}, null, 2)}`,
      },
    ],
  };
}

const listActions = {
  listArticles: {
    path: "/api/cultureArticle/listByPage",
    buildBody: ({ current, size, title, type }) => ({ current, size, title, type }),
    format: (payload) => {
      const list = getMaybeList(payload);
      if (!list.length) return "未查询到文章。";
      return list
        .map(
          (item, idx) =>
            `${idx + 1}. 标题: ${item.title || "-"} | ID: ${item.id || item.articleId || "-"} | 发布人: ${item.showName || item.createUserName || "-"}`
        )
        .join("\n");
    },
  },
  getArticleDetail: {
    path: "/api/cultureArticle/getArticleDetail",
    method: "POST",
    useQuery: ({ articleId }) => `?articleId=${encodeURIComponent(String(articleId))}`,
    format: (payload) => JSON.stringify(payload?.data || payload, null, 2),
  },
};

const mutateActions = {
  publishArticle: {
    path: "/api/cultureArticle/addOrUpdateArticle",
  },
  deleteArticle: {
    path: "/api/personalCenter/deleteArticle",
    buildBody: ({ id }) => ({ id }),
  },
  updateRecommend: {
    path: "/api/cultureArticle/isRecommend",
  },
};

const interactActions = {
  likeArticle: {
    path: ({ articleId }) => `/api/cultureArticle/likeArticle?articleId=${encodeURIComponent(String(articleId))}`,
    method: "POST",
    noBody: true,
  },
  collectArticle: {
    path: ({ articleId }) => `/api/cultureArticle/collectArticle?articleId=${encodeURIComponent(String(articleId))}`,
    method: "POST",
    noBody: true,
  },
  rewardArticle: {
    path: "/api/culture/action/record/reward",
  },
};

async function runAction(actionMap, action, params) {
  const config = actionMap[action];
  if (!config) return failText(`不支持的 action: ${action}`, { supported: Object.keys(actionMap) });

  const path = typeof config.path === "function" ? config.path(params) : config.path;
  const query = config.useQuery ? config.useQuery(params) : "";
  const body = config.noBody ? undefined : config.buildBody ? config.buildBody(params) : params;
  const res = await requestCultureApi({ path: `${path}${query}`, method: config.method || "POST", body });

  if (!res.ok) return failText(res.message, res.payload);
  return okText(`action=${action} 执行成功`, config.format ? config.format(res.payload) : res.payload);
}

server.registerTool(
  "article_list",
  {
    description: "文章查询类能力：分页查询、详情查询",
    inputSchema: {
      action: z.enum(["listArticles", "getArticleDetail"]).describe("查询动作"),
      params: z
        .object({
          current: z.number().int().positive().optional(),
          size: z.number().int().positive().optional(),
          title: z.string().optional(),
          type: z.number().optional(),
          articleId: z.union([z.number(), z.string()]).optional(),
        })
        .describe("动作参数"),
    },
  },
  async ({ action, params }) => runAction(listActions, action, params)
);

server.registerTool(
  "article_mutate",
  {
    description: "文章写操作：发布/更新、删除、推荐设置",
    inputSchema: {
      action: z.enum(["publishArticle", "deleteArticle", "updateRecommend"]).describe("写操作动作"),
      params: z.record(z.string(), z.any()).describe("请求参数，按前端 src/api 对应接口传值"),
    },
  },
  async ({ action, params }) => runAction(mutateActions, action, params)
);

server.registerTool(
  "article_interact",
  {
    description: "文章互动操作：点赞、收藏、打赏",
    inputSchema: {
      action: z.enum(["likeArticle", "collectArticle", "rewardArticle"]).describe("互动动作"),
      params: z
        .object({
          articleId: z.union([z.number(), z.string()]).optional(),
          ayabi: z.number().optional(),
        })
        .passthrough()
        .describe("互动参数"),
    },
  },
  async ({ action, params }) => runAction(interactActions, action, params)
);

// 兼容你旧的单一工具名
server.registerTool(
  "get_article_list_by_page",
  {
    description: "根据传参获取企业文化文章列表分页（兼容旧调用）",
    inputSchema: {
      current: z.number().int().positive().describe("当前页码"),
      size: z.number().int().positive().default(10).describe("每页条数"),
    },
  },
  async ({ current, size }) => {
    return runAction(listActions, "listArticles", { current, size });
  }
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Enterprise Culture MCP Server running on stdio");
  console.error(`BASE_URL=${BASE_URL}`);
  console.error(`TOKEN=${TOKEN ? "configured" : "missing"}`);
}

main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});
