using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using RestaurantAPI.Models;

public class GooglePlacesService
{
    private readonly HttpClient _httpClient;
    private readonly string _apiKey;

    public GooglePlacesService(HttpClient httpClient, IConfiguration configuration)
    {
        _httpClient = httpClient;
        _apiKey = configuration["GooglePlaces:ApiKey"];
    }

    public async Task<List<Restaurant>> GetRestaurantsAsync(
        double latitude,
        double longitude,
        int radius = 5000,
        int? minPrice = null,
        int? maxPrice = null)
    {
        // Build the Nearby Search URL
        string url = $"https://maps.googleapis.com/maps/api/place/nearbysearch/json" +
                     $"?location={latitude},{longitude}" +
                     $"&radius={radius}" +
                     $"&type=restaurant" +
                     $"&key={_apiKey}";

        // Append optional minPrice/maxPrice
        if (minPrice.HasValue) url += $"&minprice={minPrice.Value}";
        if (maxPrice.HasValue) url += $"&maxprice={maxPrice.Value}";

        // Call Google Places Nearby Search
        HttpResponseMessage response = await _httpClient.GetAsync(url);
        string json = await response.Content.ReadAsStringAsync();

        Console.WriteLine("Google API Response: " + json);

        // Return empty list if the request failed
        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("Error: " + response.StatusCode);
            return new List<Restaurant>();
        }

        // Deserialize the JSON into our GooglePlacesResponse model
        var data = JsonSerializer.Deserialize<GooglePlacesResponse>(
            json,
            new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
        );

        var restaurants = new List<Restaurant>();

        if (data?.Results != null)
        {
            foreach (var place in data.Results)
            {
                // Skip places missing a name or location
                if (string.IsNullOrEmpty(place.Name) || place.Geometry?.Location == null)
                {
                    Console.WriteLine($"Skipping a place due to missing name or location. Name: {place.Name}");
                    continue;
                }

                // Use Google's Place ID for unique identification
                string placeId = place.PlaceId ?? Guid.NewGuid().ToString();

                // Extract the first photo reference if available
                string firstPhotoReference = place.Photos?.FirstOrDefault()?.PhotoReference;

                // Generate the Google Maps URL
                string googleMapsUrl = $"https://www.google.com/maps/place/?q=place_id:{placeId}";


                // Create a Restaurant object with all necessary data
                restaurants.Add(new Restaurant
                {
                    Id = placeId,
                    PlaceId = placeId,
                    Name = place.Name,
                    Type = place.PriceLevel switch
                    {
                        1 => "Fast Food",
                        2 => "Casual Dining",
                        3 => "Fine Dining",
                        4 => "Luxury Dining",
                        _ => "Unknown"
                    },
                    Latitude = place.Geometry.Location.Lat,
                    Longitude = place.Geometry.Location.Lng,
                    Rating = place.Rating,
                    PriceLevel = place.PriceLevel,
                    PhotoReference = firstPhotoReference,
                    GoogleMapsUrl = googleMapsUrl
                });
            }
        }

        return restaurants;
    }
}

// -------------------- Google Places Response Models --------------------

public class GooglePlacesResponse
{
    [JsonPropertyName("results")]
    public List<GooglePlace> Results { get; set; }
}

public class GooglePlace
{
    [JsonPropertyName("place_id")]
    public string PlaceId { get; set; }

    [JsonPropertyName("name")]
    public string Name { get; set; }

    public GoogleGeometry Geometry { get; set; }

    [JsonPropertyName("rating")]
    public double Rating { get; set; }

    [JsonPropertyName("price_level")]
    public int? PriceLevel { get; set; }

    [JsonPropertyName("photos")]
    public List<GooglePhoto> Photos { get; set; }
}

public class GoogleGeometry
{
    public GoogleLocation Location { get; set; }
}

public class GoogleLocation
{
    [JsonPropertyName("lat")]
    public double Lat { get; set; }

    [JsonPropertyName("lng")]
    public double Lng { get; set; }
}

public class GooglePhoto
{
    [JsonPropertyName("photo_reference")]
    public string PhotoReference { get; set; }
}
