import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import pg from 'pg';

const server = new Server(
  {
    name: "shopify-mcp-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Helper to get Shopify credentials from Odoo Database
async function getShopifyCredentials() {
  const client = new pg.Client({
    host: '172.18.0.2',
    port: 5432,
    user: 'odoo',
    password: 'odoo',
    database: 'hazard_new'
  });

  try {
    await client.connect();
    const res = await client.query('SELECT access_token, shop_url FROM shopify_config LIMIT 1;');
    if (res.rows.length === 0) {
      throw new Error("No Shopify configuration found in database.");
    }
    return {
      accessToken: res.rows[0].access_token,
      shopUrl: res.rows[0].shop_url
    };
  } finally {
    await client.end();
  }
}

// Define available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "shopify_get_order",
        description: "Retrieve a complete Shopify order JSON by its order name (e.g., 4854)",
        inputSchema: {
          type: "object",
          properties: {
            order_name: {
              type: "string",
              description: "The order number/name without the # (e.g. 4854)",
            },
          },
          required: ["order_name"],
        },
      },
      {
        name: "shopify_get_product_by_sku",
        description: "Retrieve product variants from Shopify matching a specific SKU",
        inputSchema: {
          type: "object",
          properties: {
            sku: {
              type: "string",
              description: "The SKU of the product variant",
            },
          },
          required: ["sku"],
        },
      },
      {
        name: "shopify_get_inventory_by_sku",
        description: "Retrieve inventory levels across all locations for a specific SKU",
        inputSchema: {
          type: "object",
          properties: {
            sku: {
              type: "string",
              description: "The SKU of the product variant",
            },
          },
          required: ["sku"],
        },
      },
      {
        name: "shopify_get_order_transactions",
        description: "Retrieve the financial transactions (payments/refunds) for an order by its name (e.g., 4854)",
        inputSchema: {
          type: "object",
          properties: {
            order_name: {
              type: "string",
              description: "The order number/name without the # (e.g. 4854)",
            },
          },
          required: ["order_name"],
        },
      }
    ],
  };
});

// Handle tool execution
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  try {
    const creds = await getShopifyCredentials();
    const headers = {
      "X-Shopify-Access-Token": creds.accessToken,
      "Content-Type": "application/json"
    };
    const baseUrl = `https://${creds.shopUrl}/admin/api/2023-04`;

    switch (request.params.name) {
      case "shopify_get_order": {
        const orderName = String(request.params.arguments.order_name).replace('#', '');
        const response = await fetch(`${baseUrl}/orders.json?name=${orderName}&status=any`, { headers });
        const data = await response.json();
        
        if (!data.orders || data.orders.length === 0) {
          return {
            content: [{ type: "text", text: `Order ${orderName} not found.` }],
            isError: true,
          };
        }
        return {
          content: [{ type: "text", text: JSON.stringify(data.orders[0], null, 2) }],
        };
      }
      
      case "shopify_get_product_by_sku": {
        const sku = String(request.params.arguments.sku);
        const query = `
          {
            productVariants(first: 5, query: "sku:${sku}") {
              edges {
                node {
                  id
                  title
                  sku
                  inventoryQuantity
                  product {
                    title
                  }
                }
              }
            }
          }
        `;
        const response = await fetch(`${baseUrl}/graphql.json`, { 
          method: 'POST',
          headers,
          body: JSON.stringify({ query })
        });
        const data = await response.json();
        
        return {
          content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
        };
      }
      
      case "shopify_get_inventory_by_sku": {
        const sku = String(request.params.arguments.sku);
        const query = `
          {
            productVariants(first: 5, query: "sku:${sku}") {
              edges {
                node {
                  sku
                  inventoryItem {
                    inventoryLevels(first: 10) {
                      edges {
                        node {
                          quantities(names: ["available"]) {
                            name
                            quantity
                          }
                          location {
                            id
                            name
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        `;
        const response = await fetch(`${baseUrl}/graphql.json`, { 
          method: 'POST',
          headers,
          body: JSON.stringify({ query })
        });
        const data = await response.json();
        
        return {
          content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
        };
      }
      
      case "shopify_get_order_transactions": {
        const orderName = String(request.params.arguments.order_name).replace('#', '');
        // First get the order ID
        const orderResp = await fetch(`${baseUrl}/orders.json?name=${orderName}&status=any&fields=id,name`, { headers });
        const orderData = await orderResp.json();
        
        if (!orderData.orders || orderData.orders.length === 0) {
          return {
            content: [{ type: "text", text: `Order ${orderName} not found.` }],
            isError: true,
          };
        }
        
        const orderId = orderData.orders[0].id;
        const transResp = await fetch(`${baseUrl}/orders/${orderId}/transactions.json`, { headers });
        const transData = await transResp.json();
        
        return {
          content: [{ type: "text", text: JSON.stringify(transData, null, 2) }],
        };
      }

      default:
        throw new Error(`Unknown tool: ${request.params.name}`);
    }
  } catch (error) {
    return {
      content: [{ type: "text", text: `Error: ${error.message}` }],
      isError: true,
    };
  }
});

// Run the server using stdio transport
async function run() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Shopify MCP Server running on stdio");
}

run().catch((error) => {
  console.error("Server error:", error);
  process.exit(1);
});
