import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';
import { createApiClient } from '../lib/api.js';
import { config } from '../config.js';
import { requestContext } from '../context.js';
import { logger } from '../lib/logger.js';
import { ApiResponse, Product, CheckoutResponse } from '../types/api.js';
import { oauth2Schemes, setToolSecuritySchemes, handleApiError } from '../lib/tool-security.js';
import { UI_TEMPLATE_URI, withWidgetData } from '../lib/ui.js';

const checkAuth = () => {
  const context = requestContext.getStore();
  if (!context?.token) {
    throw new Error("AUTHENTICATION_REQUIRED");
  }
  return context;
};

export const registerPaymentTools = (server: McpServer) => {
  /**
   * Tool: list_products
   * Displays available products and instructs the user/AI to use productId.
   */
  server.registerTool(
    "list_products",
    {
      title: "List Products",
      description: "List available credit packages to purchase.",
      inputSchema: {
        raw: z.boolean().optional().default(false).describe("If true, returns the raw JSON from the API")
      },
      _meta: {
        "openai/outputTemplate": UI_TEMPLATE_URI,
        "openai/widgetAccessible": true
      }
    },
    async ({ raw }) => {
      try {
        checkAuth();
        const client = createApiClient();
        const { data: response } = await client.get<ApiResponse<Product[]>>('/api/v1/products?per_page=50');
        
        const items = response.data || [];

        const structuredContent = withWidgetData({
          products: items.map(p => ({
            id: p.id,
            name: p.name || "Token Pack",
            tokens: p.token_quantity || 0,
            price: p.price || "0.00",
            currency: "EUR"
          })),
          screen: "products"
        });

        if (items.length === 0) {
          return { 
            content: [{ type: "text" as const, text: "No products available for purchase." }],
            structuredContent
          };
        }

        let output = "### Available Credit Packages\n\n";
        
        items.forEach((p) => {
          const name = p.name || "Token Pack";
          const tokens = p.token_quantity || 0;
          const price = p.price || "0.00";
          const currency = "EUR";
          output += `- **${name}**: ${tokens} tokens for ${price} ${currency} (ID: 
${p.id}
)\n`;
        });
        
        output += "\nI've also opened the product list in the ProovIT dashboard.";

        return { 
          content: [{ type: "text" as const, text: raw ? JSON.stringify(items, null, 2) : output }],
          structuredContent
        };
      } catch (error: any) {
        return handleApiError(error);
      }
    }
  );

  setToolSecuritySchemes("list_products", oauth2Schemes());

  /**
   * Tool: create_checkout_link_v2
   * STRICTLY aligned on productId. 
   * No mention of priceId in schema or code.
   */
  server.registerTool(
    "create_checkout_link_v2",
    {
      title: "Create Checkout Link",
      description: "Generate a Stripe payment link for ProovIT products.",
      inputSchema: {
        items: z.array(z.object({
          id: z.string().describe("The product ID"),
          quantity: z.number().int().min(1).optional().default(1).describe("Quantity of the item")
        })).min(1).describe("List of items to purchase"),
        successUrl: z.string().optional().describe("Override default success URL"),
        cancelUrl: z.string().optional().describe("Override default cancel URL"),
        billing: z.object({
          email: z.string().email().optional(),
          name: z.string().optional(),
          company: z.string().optional(),
          phone: z.string().optional(),
          vat: z.string().optional(),
          address: z.object({
            line1: z.string().optional(),
            line2: z.string().optional(),
            city: z.string().optional(),
            postal_code: z.string().optional(),
            state: z.string().optional(),
            country: z.string().optional()
          }).optional()
        }).optional().describe("Optional billing information")
      },
      _meta: {
        "openai/outputTemplate": UI_TEMPLATE_URI,
        "openai/widgetAccessible": true
      }
    },
    async ({ items, successUrl, cancelUrl, billing }) => {
      try {
        checkAuth();
        logger.info(`[Payment] Creating checkout link for ${items.length} items`);
        
        const client = createApiClient();
        
        const payload: any = {
          items: items,
          success_url: successUrl || config.proovit.checkoutSuccessUrl,
          cancel_url: cancelUrl || config.proovit.checkoutCancelUrl,
          billing: billing
        };

        const { data } = await client.post<CheckoutResponse>('/api/v1/checkout/mcp-session', payload);
        
        const url = data.checkoutUrl || data.url || data.data?.checkoutUrl || data.data?.url;
        
        if (!url) {
          throw new Error("The API did not return a checkout URL.");
        }

        return {
          content: [{
            type: "text" as const, 
            text: `🛒 **Payment Link Generated**\n\nPlease click the link below to complete your purchase safely via Stripe:\n\n${url}` 
          }],
          structuredContent: withWidgetData({
            checkoutUrl: url,
            status: "pending",
            screen: "products"
          })
        };
      } catch (error: any) {
        return handleApiError(error);
      }
    }
  );

  setToolSecuritySchemes("create_checkout_link_v2", oauth2Schemes());
};
