"""
Grubtech Item Availability Update - Python

This example demonstrates how to update menu item availability in Grubtech
to keep items in sync with your inventory status.

Prerequisites:
- Python 3.8+
- requests library (pip install requests)
- Valid access token from authentication

Replace the following placeholders:
- {{AUTH_TOKEN}}: Access token from authentication step
- {{ITEM_ID}}: The menu item ID to update
- {{AVAILABLE_STATUS}}: Boolean availability status (True/False)
"""

import requests
import sys
from datetime import datetime
from typing import Dict, Any, List, Optional

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


def update_item_availability(
    item_id: str,
    available: bool,
    reason: Optional[str] = None
) -> Dict[str, Any]:
    """
    Update single item availability

    Args:
        item_id: The menu item ID
        available: True if in stock, False if out of stock
        reason: Optional reason for status change

    Returns:
        Dict: Response from API

    Raises:
        Exception: If update fails
    """
    try:
        # Construct payload
        payload = {
            'itemId': item_id,
            'available': available,
            'timestamp': datetime.utcnow().isoformat() + 'Z',
        }

        if reason:
            payload['reason'] = reason

        print(f'Updating item {item_id}: available={available}')

        # Make availability update request
        url = f'{BASE_URL}/v1/items/{item_id}/availability'
        headers = {
            'Authorization': f'Bearer {AUTH_TOKEN}',
            'Content-Type': 'application/json',
        }

        response = requests.put(url, json=payload, headers=headers, timeout=10)

        # Check for errors
        if not response.ok:
            raise Exception(
                f'Availability update failed: {response.status_code} - {response.text}'
            )

        # Parse response
        data = response.json()

        print(f'✅ Item availability updated successfully!')
        print(f'Item ID: {data["itemId"]}')
        print(f'Available: {available}')

        return data

    except requests.RequestException as e:
        print(f'❌ Availability update error: {e}', file=sys.stderr)
        raise
    except Exception as e:
        print(f'❌ Unexpected error: {e}', file=sys.stderr)
        raise


def update_bulk_availability(
    updates: List[Dict[str, Any]]
) -> Dict[str, Any]:
    """
    Update multiple items availability in bulk

    Args:
        updates: List of item availability updates
                 [{'itemId': 'item-1', 'available': False, 'reason': '...'}]

    Returns:
        Dict: Response from API

    Raises:
        Exception: If update fails
    """
    try:
        # Construct bulk payload
        payload = {
            'updates': updates,
            'timestamp': datetime.utcnow().isoformat() + 'Z',
        }

        print(f'Updating {len(updates)} items availability')

        # Make bulk availability update request
        url = f'{BASE_URL}/v1/items/availability/bulk'
        headers = {
            'Authorization': f'Bearer {AUTH_TOKEN}',
            'Content-Type': 'application/json',
        }

        response = requests.put(url, json=payload, headers=headers, timeout=30)

        # Check for errors
        if not response.ok:
            raise Exception(
                f'Bulk availability update failed: {response.status_code} - {response.text}'
            )

        # Parse response
        data = response.json()

        print(f'✅ Bulk availability updated successfully!')
        print(f'Updated: {data.get("updatedCount", 0)} items')

        # Report any errors
        errors = data.get('errors', [])
        if errors:
            print(f'⚠️  {len(errors)} items had errors:')
            for err in errors:
                print(f'  - {err["itemId"]}: {err["error"]}')

        return data

    except requests.RequestException as e:
        print(f'❌ Bulk availability update error: {e}', file=sys.stderr)
        raise
    except Exception as e:
        print(f'❌ Unexpected error: {e}', file=sys.stderr)
        raise


def mark_out_of_stock(item_id: str) -> Dict[str, Any]:
    """Mark item as out of stock"""
    return update_item_availability(item_id, False, 'Out of stock')


def mark_in_stock(item_id: str) -> Dict[str, Any]:
    """Mark item as back in stock"""
    return update_item_availability(item_id, True, 'Back in stock')


def sync_inventory(inventory: Dict[str, bool]) -> Dict[str, Any]:
    """
    Sync inventory with Grubtech

    Args:
        inventory: Dict mapping item IDs to availability status
                   {'item-123': False, 'item-456': True}
    """
    updates = [
        {
            'itemId': item_id,
            'available': available,
            'reason': 'In stock' if available else 'Out of stock',
        }
        for item_id, available in inventory.items()
    ]

    return update_bulk_availability(updates)


if __name__ == '__main__':
    try:
        item_id = '{{ITEM_ID}}'
        available = {{AVAILABLE_STATUS}}  # True or False

        # Example 1: Single item update
        update_item_availability(item_id, available, 'Inventory sync')

        # Example 2: Mark item out of stock
        # mark_out_of_stock('item-123')

        # Example 3: Bulk update from inventory
        # sync_inventory({
        #     'item-123': False,  # Out of stock
        #     'item-456': True,   # In stock
        #     'item-789': True,   # In stock
        # })

    except Exception as e:
        sys.exit(1)
