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

dotenv.config();

const LISTMONK_URL = process.env.LISTMONK_URL || "https://listmonk.infra.mintel.me";
const LISTMONK_USERNAME = process.env.LISTMONK_USERNAME || "mmintel";
const LISTMONK_PASSWORD = process.env.LISTMONK_PASSWORD || "Tim300493.";

const apiClient = axios.create({
  baseURL: LISTMONK_URL,
  auth: {
    username: LISTMONK_USERNAME,
    password: LISTMONK_PASSWORD,
  },
  headers: {
    "Content-Type": "application/json",
  },
});

const server = new McpServer({
  name: "listmonk-mcp",
  version: "1.0.0",
});

// GET /api/subscribers
server.tool(
  "listmonk_list_subscribers",
  {
    query: z.string().optional().describe("Search query (email or name)"),
    page: z.number().optional().describe("Page number (default 1)"),
    per_page: z.number().optional().describe("Results per page (default 20)"),
  },
  async ({ query, page, per_page }) => {
    try {
      const response = await apiClient.get("/api/subscribers", {
        params: { query, page, per_page },
      });
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// GET /api/subscribers/{id}
server.tool(
  "listmonk_get_subscriber",
  { id: z.number().describe("Subscriber ID") },
  async ({ id }) => {
    try {
      const response = await apiClient.get(`/api/subscribers/${id}`);
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// POST /api/subscribers
server.tool(
  "listmonk_create_subscriber",
  {
    email: z.string().email().describe("Subscriber email address"),
    name: z.string().describe("Subscriber name"),
    status: z.enum(["enabled", "disabled", "blocklisted"]).describe("Subscriber status"),
    lists: z.array(z.number()).describe("Array of list IDs to subscribe to"),
    attribs: z.record(z.string(), z.any()).optional().describe("Optional JSON attributes"),
    preconfirm_subscriptions: z.boolean().optional().describe("Mark subscriptions as confirmed (opt-in bypassed)"),
  },
  async ({ email, name, status, lists, attribs, preconfirm_subscriptions }) => {
    try {
      const response = await apiClient.post("/api/subscribers", {
        email,
        name,
        status,
        lists,
        attribs,
        preconfirm_subscriptions,
      });
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// PUT /api/subscribers/{id}
server.tool(
  "listmonk_update_subscriber",
  {
    id: z.number().describe("Subscriber ID"),
    email: z.string().email().optional().describe("Subscriber email address"),
    name: z.string().optional().describe("Subscriber name"),
    status: z.enum(["enabled", "disabled", "blocklisted"]).optional().describe("Subscriber status"),
    lists: z.array(z.number()).optional().describe("Array of list IDs to subscribe to"),
    attribs: z.record(z.string(), z.any()).optional().describe("Optional JSON attributes"),
  },
  async ({ id, email, name, status, lists, attribs }) => {
    try {
      const data: any = {};
      if (email) data.email = email;
      if (name) data.name = name;
      if (status) data.status = status;
      if (lists) data.lists = lists;
      if (attribs) data.attribs = attribs;

      const response = await apiClient.put(`/api/subscribers/${id}`, data);
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// GET /api/lists
server.tool(
  "listmonk_list_lists",
  {},
  async () => {
    try {
      const response = await apiClient.get("/api/lists");
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// POST /api/lists
server.tool(
  "listmonk_create_list",
  {
    name: z.string().describe("List name"),
    type: z.enum(["public", "private"]).describe("List type"),
    optin: z.enum(["single", "double"]).describe("Opt-in type"),
    description: z.string().optional().describe("Optional description"),
    tags: z.array(z.string()).optional().describe("Optional tags"),
  },
  async ({ name, type, optin, description, tags }) => {
    try {
      const response = await apiClient.post("/api/lists", {
        name,
        type,
        optin,
        description,
        tags,
      });
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// GET /api/campaigns
server.tool(
  "listmonk_list_campaigns",
  {
    page: z.number().optional().describe("Page number"),
    per_page: z.number().optional().describe("Results per page"),
  },
  async ({ page, per_page }) => {
    try {
      const response = await apiClient.get("/api/campaigns", {
        params: { page, per_page },
      });
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// POST /api/campaigns
server.tool(
  "listmonk_create_campaign",
  {
    name: z.string().describe("Internal campaign name"),
    subject: z.string().describe("Email subject line"),
    lists: z.array(z.number()).describe("Array of list IDs to send to"),
    type: z.enum(["regular", "optin"]).describe("Campaign type"),
    content_type: z.enum(["richtext", "html", "markdown", "plain"]).describe("Content type"),
    body: z.string().describe("Email body content"),
    altbody: z.string().optional().describe("Optional plain text alternative body"),
    from_email: z.string().optional().describe("From email address"),
    messenger: z.string().describe("Messenger to use (e.g. 'email')"),
    template_id: z.number().optional().describe("Template ID to wrap the content"),
    tags: z.array(z.string()).optional().describe("Optional tags"),
  },
  async (params) => {
    try {
      const response = await apiClient.post("/api/campaigns", params);
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

// POST /api/tx
server.tool(
  "listmonk_send_tx",
  {
    subscriber_email: z.string().email().describe("Subscriber email to send to"),
    subscriber_id: z.number().optional().describe("Subscriber ID (optional, alternative to email)"),
    template_id: z.number().describe("Template ID to use"),
    data: z.record(z.string(), z.any()).describe("JSON data for template variables"),
    messenger: z.string().optional().describe("Messenger type (default 'email')"),
  },
  async ({ subscriber_email, subscriber_id, template_id, data, messenger }) => {
    try {
      const payload: any = {
        template_id,
        data,
        messenger: messenger || "email",
      };
      if (subscriber_email) payload.subscriber_email = subscriber_email;
      if (subscriber_id) payload.subscriber_id = subscriber_id;

      const response = await apiClient.post("/api/tx", payload);
      return {
        content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
      };
    } catch (error: any) {
      return {
        content: [{ type: "text", text: `Error: ${error.response?.data?.message || error.message}` }],
        isError: true,
      };
    }
  }
);

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Listmonk MCP Server running on stdio");
}

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