from flask import Flask, request, jsonify, Response
import requests
import os
from flask_cors import CORS

# Initialize Flask app
app = Flask(__name__)

# Enhanced CORS configuration
CORS(app, 
     resources={r"/*": {"origins": "*"}}, 
     supports_credentials=True,
     allow_headers=["Content-Type", "Authorization", "Access-Control-Allow-Credentials"],
     methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"]
)

# Configuration - point to your main backend
MAIN_BACKEND_URL = "http://127.0.0.1:5000"  # Change this to your main backend URL

# Add OPTIONS handler for preflight requests
@app.before_request
def handle_preflight():
    if request.method == "OPTIONS":
        response = Response()
        response.headers.add("Access-Control-Allow-Origin", "*")
        response.headers.add('Access-Control-Allow-Headers', "*")
        response.headers.add('Access-Control-Allow-Methods', "*")
        return response

# Routes
@app.route('/login', methods=['POST'])
def login():
    """Handle machine login"""
    try:
        data = request.json
        print(f"Login request received: {data}")
        
        # Forward the login request to the main backend
        response = requests.post(f"{MAIN_BACKEND_URL}/login", json=data)
        print(f"Login response status: {response.status_code}")
        
        # Pass through the response
        return Response(
            response.content, 
            status=response.status_code, 
            content_type=response.headers.get('Content-Type', 'application/json')
        )
    except Exception as e:
        print(f"Login error: {e}")
        return jsonify({"error": "Login service unavailable"}), 500

@app.route('/uploads/<path:filename>', methods=['GET'])
def get_image(filename):
    """Forward image requests to the main backend"""
    try:
        response = requests.get(f"{MAIN_BACKEND_URL}/uploads/{filename}", stream=True)
        
        return Response(
            response.content, 
            status=response.status_code, 
            content_type=response.headers.get('Content-Type', 'image/jpeg')
        )
    except Exception as e:
        print(f"Image fetch error: {e}")
        return jsonify({"error": "Image not found"}), 404

@app.route('/machine-slots/<machine_id>', methods=['GET'])
def get_machine_slots(machine_id):
    """Get slots for a specific machine"""
    try:
        print(f"Fetching slots for machine: {machine_id}")
        # Simply forward the request to the main backend
        response = requests.get(f"{MAIN_BACKEND_URL}/machine-slots/{machine_id}")
        print(f"Slots response status: {response.status_code}")
        
        # Pass through the response
        return Response(
            response.content, 
            status=response.status_code, 
            content_type=response.headers.get('Content-Type', 'application/json')
        )
    except Exception as e:
        print(f"Machine slots error: {e}")
        return jsonify({"error": "Could not fetch machine slots"}), 500

@app.route('/machine-slots/update-inventory', methods=['POST'])
def update_inventory():
    """Forward inventory update request to main backend"""
    try:
        print("=== Inventory Update Request ===")
        data = request.json
        
        if not data:
            return jsonify({"error": "No data received"}), 400
        
        machine_id = data.get('machineId')
        updates = data.get('inventoryUpdates', [])
        
        print(f"Machine ID: {machine_id}")
        print(f"Inventory updates: {len(updates)}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/machine-slots/update-inventory", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Inventory update response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Inventory update error: {e}")
        return jsonify({"error": "Could not update inventory"}), 500

@app.route('/vending-state/<machine_id>', methods=['GET'])
def get_vending_state(machine_id):
    """Get the vending state for a machine"""
    try:
        # Forward the request to the main backend
        response = requests.get(f"{MAIN_BACKEND_URL}/machines/{machine_id}")
        
        # Pass through the response
        return Response(
            response.content, 
            status=response.status_code, 
            content_type=response.headers.get('Content-Type', 'application/json')
        )
    except Exception as e:
        print(f"Vending state error: {e}")
        return jsonify({"error": "Could not fetch vending state"}), 500

@app.route('/create-payu-order', methods=['POST', 'OPTIONS'])
def create_payu_order():
    """Create PayU payment order - forward to main backend"""
    try:
        print("=== PayU Order Creation Request ===")
        data = request.json
        print(f"Request data: {data}")
        
        if not data:
            print("No data received in request")
            return jsonify({"error": "No data received"}), 400
            
        # Forward to main backend
        print(f"Forwarding to: {MAIN_BACKEND_URL}/create-payu-order")
        response = requests.post(
            f"{MAIN_BACKEND_URL}/create-payu-order", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Main backend response status: {response.status_code}")
        print(f"Main backend response: {response.text}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except requests.exceptions.ConnectionError as e:
        print(f"Connection error to main backend: {e}")
        return jsonify({"error": "Payment service unavailable"}), 503
    except Exception as e:
        print(f"PayU order creation error: {e}")
        return jsonify({"error": "Could not create payment order"}), 500

@app.route('/vending-state/<machine_id>', methods=['PUT'])
def update_vending_state(machine_id):
    """Update the vending state for a machine"""
    try:
        # Forward the request to the main backend
        headers = {k: v for k, v in request.headers.items() if k not in ['Host', 'Content-Length']}
        response = requests.put(
            f"{MAIN_BACKEND_URL}/machines/{machine_id}/vending-state", 
            json=request.json,
            headers=headers
        )
        
        # Pass through the response
        return Response(
            response.content, 
            status=response.status_code, 
            content_type=response.headers.get('Content-Type', 'application/json')
        )
    except Exception as e:
        print(f"Update vending state error: {e}")
        return jsonify({"error": "Could not update vending state"}), 500

# NEW: Serial Communication Routes

@app.route('/machine/connect', methods=['POST'])
def connect_machine():
    """Forward machine connection request to main backend"""
    try:
        print("=== Machine Connection Request ===")
        data = request.json or {}
        print(f"Connection data: {data}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/machine/connect", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Connection response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Machine connection error: {e}")
        return jsonify({"error": "Could not connect to machine"}), 500

@app.route('/machine/status', methods=['GET'])
def get_machine_status():
    """Forward machine status request to main backend"""
    try:
        print("=== Machine Status Request ===")
        
        response = requests.get(f"{MAIN_BACKEND_URL}/machine/status")
        
        print(f"Status response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Machine status error: {e}")
        return jsonify({"error": "Could not get machine status"}), 500

@app.route('/machine/dispense', methods=['POST'])
def dispense_product():
    """Forward single product dispensing to main backend"""
    try:
        print("=== Single Product Dispensing Request ===")
        data = request.json
        
        if not data:
            return jsonify({"error": "No data received"}), 400
        
        print(f"Dispense data: {data}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/machine/dispense", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Dispense response: {response.status_code}")
        print(f"Dispense result: {response.text}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Product dispensing error: {e}")
        return jsonify({"error": "Could not dispense product"}), 500

@app.route('/machine/dispense-multiple', methods=['POST'])
def dispense_multiple_products():
    """Forward multiple product dispensing to main backend"""
    try:
        print("=== Multiple Product Dispensing Request ===")
        data = request.json
        
        if not data:
            return jsonify({"error": "No data received"}), 400
        
        machine_id = data.get('machineId')
        items = data.get('items', [])
        
        print(f"Machine ID: {machine_id}")
        print(f"Items to dispense: {len(items)}")
        for item in items:
            print(f"  - Slot {item.get('slotId')}: {item.get('quantity')}x {item.get('productName')}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/machine/dispense-multiple", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Multiple dispense response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Multiple product dispensing error: {e}")
        return jsonify({"error": "Could not dispense multiple products"}), 500

@app.route('/machine/reset', methods=['POST'])
def reset_machine():
    """Forward machine reset request to main backend"""
    try:
        print("=== Machine Reset Request ===")
        
        response = requests.post(f"{MAIN_BACKEND_URL}/machine/reset")
        
        print(f"Reset response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Machine reset error: {e}")
        return jsonify({"error": "Could not reset machine"}), 500

@app.route('/machine/disconnect', methods=['POST'])
def disconnect_machine():
    """Forward machine disconnect request to main backend"""
    try:
        print("=== Machine Disconnect Request ===")
        
        response = requests.post(f"{MAIN_BACKEND_URL}/machine/disconnect")
        
        print(f"Disconnect response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Machine disconnect error: {e}")
        return jsonify({"error": "Could not disconnect machine"}), 500

@app.route('/payment-confirmed', methods=['POST'])
def payment_confirmed():
    """Forward payment confirmation to main backend for dispensing"""
    try:
        print("=== Payment Confirmation Request ===")
        data = request.json
        
        if not data:
            return jsonify({"error": "No data received"}), 400
        
        machine_id = data.get('machineId')
        cart_items = data.get('cartItems', [])
        
        print(f"Payment confirmed for machine: {machine_id}")
        print(f"Cart items: {len(cart_items)}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/payment-confirmed", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Payment confirmation response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Payment confirmation error: {e}")
        return jsonify({"error": "Could not process payment confirmation"}), 500

@app.route('/transactions/bulk-create', methods=['POST'])
def bulk_create_transactions():
    """Forward bulk transaction creation to main backend"""
    try:
        print("=== Bulk Transaction Creation Request ===")
        data = request.json
        
        if not data:
            return jsonify({"error": "No data received"}), 400
        
        transactions = data.get('transactions', [])
        print(f"Creating {len(transactions)} transactions")
        
        for trans in transactions:
            print(f"  - {trans.get('product_name')} x {trans.get('quantity')} = ₹{trans.get('amount')}")
        
        response = requests.post(
            f"{MAIN_BACKEND_URL}/transactions/bulk-create", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        print(f"Bulk transaction response: {response.status_code}")
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        print(f"Bulk transaction creation error: {e}")
        return jsonify({"error": "Could not create transactions"}), 500

# LEGACY: Keep existing dispense-products route for backward compatibility
@app.route('/dispense-products', methods=['POST'])
def dispense_products():
    """Legacy route - redirect to new dispensing system"""
    print("=== Legacy Dispense Products Request ===")
    print("Redirecting to new dispensing system...")
    
    # Get dispensing instructions from the request
    data = request.json
    if not data:
        print("No JSON data received")
        return jsonify({"error": "No data received"}), 400
        
    machine_id = data.get('machineId')
    dispensing_instructions = data.get('dispensingInstructions', [])
    
    if not machine_id or not dispensing_instructions:
        print("Missing machine ID or dispensing instructions")
        return jsonify({"error": "Missing machine ID or dispensing instructions"}), 400
    
    # Convert to new format and forward to new dispensing endpoint
    try:
        new_format = {
            'machineId': machine_id,
            'items': [
                {
                    'slotId': instruction.get('slotId'),
                    'quantity': instruction.get('quantity', 1),
                    'productName': instruction.get('productName', 'Unknown')
                }
                for instruction in dispensing_instructions
            ]
        }
        
        return dispense_multiple_products_internal(new_format)
        
    except Exception as e:
        print(f"Legacy conversion error: {e}")
        return jsonify({"error": "Could not process legacy request"}), 500

def dispense_multiple_products_internal(data):
    """Internal function to handle dispensing without duplicate logging"""
    try:
        response = requests.post(
            f"{MAIN_BACKEND_URL}/machine/dispense-multiple", 
            json=data,
            headers={'Content-Type': 'application/json'}
        )
        
        return Response(
            response.content,
            status=response.status_code,
            content_type=response.headers.get('Content-Type', 'application/json')
        )
        
    except Exception as e:
        return jsonify({"error": "Could not dispense products"}), 500

@app.route('/payment-success', methods=['POST', 'GET'])
def payment_success():
    data = request.form.to_dict() or request.args.to_dict()
    print("✅ Payment Success:", data)
    return jsonify({
        "success": True,
        "message": "Payment successful",
        "data": data
    }), 200

@app.route('/payment-failure', methods=['POST', 'GET'])
def payment_failure():
    data = request.form.to_dict() or request.args.to_dict()
    print("❌ Payment Failure:", data)
    return jsonify({
        "success": False,
        "message": "Payment failed",
        "data": data
    }), 200



# Add a test route to verify the server is running
@app.route('/', methods=['GET'])
def test_route():
    return jsonify({"status": "Flask server is running"}), 200

# Add error handlers
@app.errorhandler(404)
def not_found(error):
    return jsonify({"error": "Endpoint not found"}), 404

@app.errorhandler(500)
def internal_error(error):
    return jsonify({"error": "Internal server error"}), 500

if __name__ == '__main__':
    # Print startup message
    print("Starting Flask server on port 5001...")
    print("Available routes:")
    print("  - /")
    print("  - /login [POST]")
    print("  - /uploads/<filename> [GET]")
    print("  - /machine-slots/<machine_id> [GET]")
    print("  - /vending-state/<machine_id> [GET/PUT]")
    print("  - /create-payu-order [POST]")
    print("  - /dispense-products [POST] (legacy)")
    print("  - /machine/connect [POST]")
    print("  - /machine/status [GET]")
    print("  - /machine/dispense [POST]")
    print("  - /machine/dispense-multiple [POST]")
    print("  - /machine/reset [POST]")
    print("  - /machine/disconnect [POST]")
    print("  - /payment-confirmed [POST]")
    print(f"Main backend URL: {MAIN_BACKEND_URL}")
    
    # Run the server
    app.run(host='0.0.0.0', debug=True, port=5001)