using BoredCareers.Entities;
using MySql.Data.MySqlClient;
using System.Data;
using System.Data.Common;
using System.Text;

namespace BoredCareers.Services.DatabaseService {
    public partial class DatabaseService {

        public async Task<Location[]> GetNearbyLocations(string PostalCode, string CountryCode, float MaxDistanceKm) {
            List<Location> closePostalCodes = new List<Location>();
            using (MySqlConnection connection = GetConnection()) {
                await connection.OpenAsync();
                string command = @"
                SELECT 
                    pc2.PostalCode,
                    pc2.CountryCode,
                    pc2.Latitude,
                    pc2.Longitude,
                    pc2.City,
                    (
                        6371 * acos(
                            cos(radians(pc1.Latitude)) * 
                            cos(radians(pc2.Latitude)) * 
                            cos(radians(pc2.Longitude) - radians(pc1.Longitude)) + 
                            sin(radians(pc1.Latitude)) * 
                            sin(radians(pc2.Latitude))
                        )
                    ) AS distance_km
                FROM PostalCodes pc1
                JOIN PostalCodes pc2 ON pc2.CountryCode = 'us'
                WHERE pc1.PostalCode = @PostalCode AND pc1.CountryCode = @CountryCode
                HAVING distance_km <= @MaxDistanceKm
                ORDER BY distance_km;
                ";

                MySqlCommand cmd = new MySqlCommand(command, connection);
                cmd.Parameters.AddWithValue("@PostalCode", PostalCode);
                cmd.Parameters.AddWithValue("@CountryCode", CountryCode);
                cmd.Parameters.AddWithValue("@MaxDistanceKm", MaxDistanceKm);

                using (DbDataReader reader = await cmd.ExecuteReaderAsync()) {
                    while (await reader.ReadAsync()) {
                        string _city = reader.GetString("City");
                        string _postalCode = reader.GetString("PostalCode");
                        string _countryCode = reader.GetString("CountryCode");
                        float _latitude = reader.GetFloat("Latitude");
                        float _longitude = reader.GetFloat("Longitude");
                        float _distanceKm = reader.GetFloat("distance_km");

                        closePostalCodes.Add(new Location() {
                            City = _city,
                            PostalCode = _postalCode,
                            CountryCode = _countryCode,
                            Latitude = _latitude,
                            Longitude = _longitude,
                            DistanceKM = _distanceKm
                        });
                    }
                }
            }
            return closePostalCodes.ToArray();
        }

    }
}
