import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { orderApi, inventoryApi, DEFAULT_SHOP_ID } from "../services/api-client.js";
import { errorResponse, textResponse } from "../services/error-handler.js";

interface PopularItemDto {
  productName: string;
  quantitySold: number;
  revenue: number;
}

interface PosDashboardDto {
  revenue: number;
  orderCount: number;
  itemsSold: number;
  avgOrderValue: number;
  popularItems: PopularItemDto[];
  hourlyRevenue: unknown[];
}

interface InventoryItemDto {
  id: string;
  name: string;
  quantity: number;
  costPerUnit: number;
  unit: string;
  reorderLevel: number;
}

export function registerAnalyticsTools(server: McpServer): void {
  server.tool(
    "popular_items",
    "Get top selling products by analyzing order data. Shows product name, quantity sold, and revenue.",
    {
      shopId: z
        .string()
        .uuid()
        .optional()
        .describe("Shop ID (defaults to configured shop)"),
      period: z
        .enum(["today", "7d", "30d"])
        .default("7d")
        .describe("Time period: today, 7d (last 7 days), 30d (last 30 days)"),
    },
    async ({ shopId, period }) => {
      try {
        const resolvedShopId = shopId ?? DEFAULT_SHOP_ID;
        const response = await orderApi.get("/orders/dashboard", {
          params: { shopId: resolvedShopId, period },
        });

        // Dashboard API returns directly (no {success, data} wrapper)
        const dashboard: PosDashboardDto = response.data?.data ?? response.data ?? {};
        const topItems = dashboard.popularItems ?? [];
        const totalRevenue = dashboard.revenue ?? 0;

        if (topItems.length === 0 && totalRevenue === 0) {
          return textResponse(`No sales data found for period: ${period}.`);
        }

        const lines = topItems.map((item, i) => {
          const rank = `#${i + 1}`;
          const rev = (item.revenue ?? 0).toLocaleString("vi-VN");
          return `${rank} ${item.productName} — ${item.quantitySold} sold (${rev} VND)`;
        });

        const summary = [
          `Top Selling Products (${period})`,
          `${"—".repeat(40)}`,
          `Total Revenue: ${totalRevenue.toLocaleString("vi-VN")} VND`,
          `Total Orders: ${dashboard.orderCount ?? 0}`,
          `Items Sold: ${dashboard.itemsSold ?? 0}`,
          `Avg Order Value: ${(dashboard.avgOrderValue ?? 0).toLocaleString("vi-VN")} VND`,
          ``,
          topItems.length > 0 ? `Rankings:` : `(No product rankings available)`,
          ...lines,
        ].join("\n");

        return textResponse(summary);
      } catch (err) {
        return errorResponse(err);
      }
    }
  );

  server.tool(
    "cost_analysis",
    "Analyze cost structure by comparing inventory costs with revenue. Shows inventory value and revenue breakdown.",
    {
      shopId: z
        .string()
        .uuid()
        .optional()
        .describe("Shop ID (defaults to configured shop)"),
    },
    async ({ shopId }) => {
      try {
        const resolvedShopId = shopId ?? DEFAULT_SHOP_ID;

        // Use Promise.allSettled for partial failure resilience
        const [inventoryResult, dashboardResult] = await Promise.allSettled([
          inventoryApi.get("/inventory", {
            params: { shopId: resolvedShopId, take: 200 },
          }),
          orderApi.get("/orders/dashboard", {
            params: { shopId: resolvedShopId, period: "30d" },
          }),
        ]);

        // Extract inventory data
        let inventoryItems: InventoryItemDto[] = [];
        let inventoryError = "";
        if (inventoryResult.status === "fulfilled") {
          const payload = inventoryResult.value.data?.data ?? inventoryResult.value.data;
          inventoryItems = payload?.items ?? [];
        } else {
          inventoryError = "Inventory data unavailable";
        }

        // Extract dashboard data
        let dashboard: Partial<PosDashboardDto> = {};
        let dashboardError = "";
        if (dashboardResult.status === "fulfilled") {
          dashboard = dashboardResult.value.data?.data ?? dashboardResult.value.data ?? {};
        } else {
          dashboardError = "Revenue data unavailable";
        }

        const totalInventoryValue = inventoryItems.reduce(
          (sum, item) => sum + (item.quantity || 0) * (item.costPerUnit || 0),
          0
        );

        const totalRevenue = dashboard.revenue ?? 0;

        const costBreakdown = inventoryItems
          .filter((item) => item.costPerUnit > 0)
          .sort((a, b) => b.quantity * b.costPerUnit - a.quantity * a.costPerUnit)
          .slice(0, 15)
          .map((item) => {
            const itemCost = item.quantity * item.costPerUnit;
            return `  - ${item.name}: ${item.quantity} ${item.unit} @ ${item.costPerUnit.toLocaleString("vi-VN")} = ${itemCost.toLocaleString("vi-VN")} VND`;
          });

        const warnings = [inventoryError, dashboardError].filter(Boolean);

        const report = [
          `Cost Analysis Report (Last 30 Days)`,
          `${"=".repeat(45)}`,
          warnings.length > 0 ? `\nWarnings: ${warnings.join(", ")}\n` : "",
          `Revenue (30d):     ${totalRevenue.toLocaleString("vi-VN")} VND`,
          `Inventory Value:   ${totalInventoryValue.toLocaleString("vi-VN")} VND`,
          ``,
          `Orders (30d):      ${dashboard.orderCount ?? "N/A"}`,
          `Items Sold:        ${dashboard.itemsSold ?? "N/A"}`,
          `Avg Order Value:   ${(dashboard.avgOrderValue ?? 0).toLocaleString("vi-VN")} VND`,
          ``,
          `Top Cost Items (by current inventory value):`,
          ...(costBreakdown.length > 0 ? costBreakdown : ["  (no cost data available)"]),
          ``,
          `Inventory Items Tracked: ${inventoryItems.length}`,
        ]
          .filter(Boolean)
          .join("\n");

        return textResponse(report);
      } catch (err) {
        return errorResponse(err);
      }
    }
  );
}
