import requests
import json
import logging
from google.oauth2 import service_account
from google.auth.transport.requests import Request

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class RouteSolver:
    BASE_URL = "https://routeoptimization.googleapis.com/v1/projects/{project_id}:optimizeTours"

    def __init__(self, service_account_info):
        """
        Initialize with Google Service Account Dictionary.
        """
        self.creds = service_account.Credentials.from_service_account_info(
            service_account_info, 
            scopes=['https://www.googleapis.com/auth/cloud-platform']
        )
        self.project_id = service_account_info.get("project_id")

    def _get_token(self):
        if not self.creds.valid:
            self.creds.refresh(Request())
        return self.creds.token

    def optimize_single_vehicle(self, orders, origin, cost_per_km=1.0, penalty_cost=1000.0):
        """
        Optimizes a route for a single vehicle.
        
        :param orders: List of dicts [{'id': '1', 'lat': 12.0, 'lng': 80.0}]
        :param origin: Dict {'lat': 12.0, 'lng': 80.0} (Start/End point)
        :return: Dictionary with polyline and sorted sequence
        """
        token = self._get_token()
        url = self.BASE_URL.format(project_id=self.project_id)
        
        # 1. Build Shipments
        shipments = []
        for order in orders:
            shipments.append({
                "label": str(order['id']),
                "penaltyCost": penalty_cost,
                "deliveries": [{
                    "arrivalWaypoint": {
                        "location": {
                            "latLng": {
                                "latitude": order['lat'],
                                "longitude": order['lng']
                            }
                        }
                    }
                }]
            })

        # 2. Build Vehicle
        vehicle = {
            "label": "v1",
            "costPerKilometer": cost_per_km,
            "startWaypoint": {
                "location": {
                    "latLng": {
                        "latitude": origin['lat'],
                        "longitude": origin['lng']
                    }
                }
            },
            "endWaypoint": {
                "location": {
                    "latLng": {
                        "latitude": origin['lat'],
                        "longitude": origin['lng']
                    }
                }
            }
        }

        # 3. Send Request
        headers = {
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json"
        }
        payload = {
            "model": {
                "shipments": shipments,
                "vehicles": [vehicle]
            },
            "populatePolylines": True
        }

        try:
            response = requests.post(url, headers=headers, json=payload)
            response.raise_for_status()
            return self._parse_response(response.json())
        except Exception as e:
            logger.error(f"Solver Error: {e}")
            if response:
                logger.error(response.text)
            raise e

    def _parse_response(self, data):
        if "routes" not in data:
            return {"success": False, "error": "No route found"}

        route = data["routes"][0]
        polyline = route.get("routePolyline", {}).get("points", "")
        
        sequence = []
        for visit in route.get("visits", []):
            label = visit.get("shipmentLabel")
            if label:
                sequence.append(label)

        return {
            "success": True,
            "polyline": polyline,
            "sequence": sequence
        }