/**
 * Grubtech Menu Sync - TypeScript
 *
 * This example demonstrates how to push menu data to Grubtech API.
 *
 * Prerequisites:
 * - Node.js 18+ with fetch API
 * - Valid access token from authentication
 *
 * Replace the following placeholders:
 * - {{AUTH_TOKEN}}: Access token from authentication step
 * - {{MENU_DATA}}: Your menu data in the required format
 */

const AUTH_TOKEN = '{{AUTH_TOKEN}}';
const BASE_URL = 'https://api.staging.grubtech.io';

interface MenuItem {
  id: string;
  name: string;
  description: string;
  price: number;
  available: boolean;
  modifiers?: Modifier[];
}

interface Modifier {
  id: string;
  name: string;
  price: number;
  available: boolean;
}

interface MenuCategory {
  id: string;
  name: string;
  description: string;
  sortOrder: number;
  items: MenuItem[];
}

interface MenuData {
  name: string;
  description: string;
  categories: MenuCategory[];
}

interface MenuResponse {
  menuId: string;
  status: string;
  message: string;
}

/**
 * Example menu data structure
 * Replace this with your actual menu data
 */
const MENU_DATA: MenuData = {
  name: 'Restaurant Menu',
  description: 'Main menu with categories and items',
  categories: [
    {
      id: 'cat-1',
      name: 'Appetizers',
      description: 'Start your meal right',
      sortOrder: 1,
      items: [
        {
          id: 'item-1',
          name: 'Spring Rolls',
          description: 'Crispy vegetable spring rolls',
          price: 8.99,
          available: true,
          modifiers: [
            {
              id: 'mod-1',
              name: 'Extra Sauce',
              price: 1.50,
              available: true,
            },
          ],
        },
      ],
    },
    {
      id: 'cat-2',
      name: 'Main Courses',
      description: 'Delicious entrees',
      sortOrder: 2,
      items: [
        {
          id: 'item-2',
          name: 'Grilled Chicken',
          description: 'Tender chicken with herbs',
          price: 15.99,
          available: true,
          modifiers: [],
        },
      ],
    },
  ],
};

/**
 * Push menu data to Grubtech API
 */
async function createMenu(menuData: MenuData): Promise<string> {
  try {
    // Validate menu data before sending
    if (!menuData.categories || menuData.categories.length === 0) {
      throw new Error('Menu must have at least one category');
    }

    // Make menu creation request
    const response = await fetch(`${BASE_URL}/v1/menus`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${AUTH_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(menuData),
    });

    // Check for errors
    if (!response.ok) {
      const errorBody = await response.text();
      throw new Error(
        `Menu creation failed: ${response.status} - ${errorBody}`
      );
    }

    // Extract menu ID from response
    const data: MenuResponse = await response.json();
    const menuId = data.menuId;

    console.log('✅ Menu created successfully!');
    console.log(`Menu ID: ${menuId}`);
    console.log(`Status: ${data.status}`);

    return menuId;
  } catch (error) {
    console.error('❌ Menu creation error:', error);
    throw error;
  }
}

/**
 * Update existing menu
 */
async function updateMenu(menuId: string, menuData: MenuData): Promise<void> {
  try {
    const response = await fetch(`${BASE_URL}/v1/menus/${menuId}`, {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${AUTH_TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(menuData),
    });

    if (!response.ok) {
      const errorBody = await response.text();
      throw new Error(`Menu update failed: ${response.status} - ${errorBody}`);
    }

    console.log('✅ Menu updated successfully!');
  } catch (error) {
    console.error('❌ Menu update error:', error);
    throw error;
  }
}

// Main execution
(async () => {
  try {
    // Create new menu
    const menuId = await createMenu(MENU_DATA);

    // Optionally update the menu
    // await updateMenu(menuId, MENU_DATA);
  } catch (error) {
    process.exit(1);
  }
})();
