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

interface RecipeIngredientDto {
  id: string;
  ingredientName: string;
  quantity: number;
  unit: string;
  costPerUnit: number;
  inventoryItemId?: string;
  quantityPerServing: number;
}

interface RecipeDto {
  id: string;
  productId: string;
  shopId: string;
  name: string;
  instructions?: string;
  prepTimeMinutes: number;
  isActive: boolean;
  ingredients: RecipeIngredientDto[];
  createdAt: string;
}

export function registerRecipeTools(server: McpServer): void {
  server.tool(
    "list_recipes",
    "List all recipes for a shop. Shows recipe name, linked product, prep time, and ingredients.",
    {
      shopId: z
        .string()
        .uuid()
        .optional()
        .describe("Shop ID (defaults to configured shop)"),
    },
    async ({ shopId }) => {
      try {
        const resolvedShopId = shopId ?? DEFAULT_SHOP_ID;
        const response = await fnbApi.get("/kitchen/recipes", {
          params: { shopId: resolvedShopId },
        });

        const recipes: RecipeDto[] = response.data?.data ?? response.data ?? [];

        if (!Array.isArray(recipes) || recipes.length === 0) {
          return textResponse("No recipes found for this shop.");
        }

        const lines = recipes.map((r, i) => {
          const status = r.isActive ? "Active" : "Inactive";
          const ingredientLines =
            r.ingredients && r.ingredients.length > 0
              ? r.ingredients
                  .map((ing) => {
                    const cost =
                      ing.costPerUnit > 0
                        ? ` @ ${ing.costPerUnit.toLocaleString("vi-VN")}d/unit`
                        : "";
                    return `    - ${ing.ingredientName}: ${ing.quantity} ${ing.unit}${cost}`;
                  })
                  .join("\n")
              : "    (no ingredients)";

          return [
            `${i + 1}. ${r.name} [${status}]`,
            `   ID: ${r.id}`,
            `   Product: ${r.productId}`,
            `   Prep time: ${r.prepTimeMinutes} min`,
            `   Ingredients:`,
            ingredientLines,
          ].join("\n");
        });

        return textResponse(`Found ${recipes.length} recipe(s):\n\n${lines.join("\n\n")}`);
      } catch (err) {
        return errorResponse(err);
      }
    }
  );

  server.tool(
    "create_recipe",
    "Create a new recipe with ingredients list. Links to a product in the catalog.",
    {
      shopId: z
        .string()
        .uuid()
        .optional()
        .describe("Shop ID (defaults to configured shop)"),
      productId: z
        .string()
        .uuid()
        .describe("The catalog product this recipe is for"),
      name: z.string().min(1).max(200).describe("Recipe name"),
      instructions: z
        .string()
        .max(2000)
        .optional()
        .describe("Preparation instructions"),
      prepTimeMinutes: z
        .number()
        .int()
        .positive()
        .default(5)
        .describe("Preparation time in minutes (default 5)"),
      ingredients: z
        .array(
          z.object({
            ingredientName: z.string().min(1).describe("Name of the ingredient"),
            quantity: z.number().positive().describe("Quantity required"),
            unit: z.string().min(1).describe("Unit of measurement (g, ml, pcs, etc.)"),
            costPerUnit: z
              .number()
              .min(0)
              .default(0)
              .describe("Cost per unit of ingredient (default 0)"),
            inventoryItemId: z
              .string()
              .uuid()
              .optional()
              .describe("Linked inventory item ID"),
            quantityPerServing: z
              .number()
              .min(0)
              .default(0)
              .describe("Quantity per serving for inventory deduction"),
          })
        )
        .min(1)
        .describe("List of ingredients for the recipe (at least 1)"),
    },
    async ({ shopId, productId, name, instructions, prepTimeMinutes, ingredients }) => {
      try {
        const resolvedShopId = shopId ?? DEFAULT_SHOP_ID;

        const response = await fnbApi.post("/kitchen/recipes", {
          shopId: resolvedShopId,
          productId,
          name,
          instructions: instructions ?? "",
          prepTimeMinutes,
          ingredients,
        });

        const recipeId = response.data?.data ?? response.data;

        const ingredientSummary = ingredients
          .map((ing) => `  - ${ing.ingredientName}: ${ing.quantity} ${ing.unit}`)
          .join("\n");

        return textResponse(
          [
            `Recipe created successfully!`,
            `ID: ${recipeId}`,
            `Name: ${name}`,
            `Product: ${productId}`,
            `Prep time: ${prepTimeMinutes} min`,
            `Ingredients (${ingredients.length}):`,
            ingredientSummary,
          ].join("\n"),
        );
      } catch (err) {
        return errorResponse(err);
      }
    }
  );
}
