using AutoMapper;
using DamageAssesment.Api.Locations.Db;
using DamageAssesment.Api.Locations.Interfaces;
using DamageAssesment.Api.Locations.Models;
using Microsoft.EntityFrameworkCore;

namespace DamageAssesment.Api.Locations.Providers
{
    public class LocationsProvider : ILocationsProvider
    {
        private LocationDbContext locationDbContext;
        private ILogger<LocationsProvider> logger;
        private IMapper mapper;

        public LocationsProvider(LocationDbContext locationDbContext, ILogger<LocationsProvider> logger, IMapper mapper)
        {
            this.locationDbContext = locationDbContext;
            this.logger = logger;
            this.mapper = mapper;
          //  SeedData();
        }

        public async Task<(bool IsSuccess, IEnumerable<Models.Location> Locations, string ErrorMessage)> GetLocationsAsync()
        {
            try
            {
                logger?.LogInformation("Query Location");
                var locations = await locationDbContext.Locations.AsNoTracking().ToListAsync();
                if (locations != null)
                {
                    logger?.LogInformation($"{locations.Count} Locations(s) found");
                    var result = mapper.Map<IEnumerable<Db.Location>, IEnumerable<Models.Location>>(locations);
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }

        public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> GetLocationByIdAsync(int Id)
        {
            try
            {
                logger?.LogInformation("Query Location");
                var location = await locationDbContext.Locations.AsNoTracking().FirstOrDefaultAsync(q => q.Id == Id);
                if (location != null)
                {
                    logger?.LogInformation($"{location}  found");
                    var result = mapper.Map<Db.Location, Models.Location>(location);
                    return (true, result, null);
                }
                return (false, null, "Not found");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> PostLocationAsync(Models.Location location)
        {
            try
            {
                if (!LocationCodeExists(location.LocationCode))
                {
                    Db.Location _location = mapper.Map<Models.Location, Db.Location>(location);
                    locationDbContext.Locations.Add(_location);
                    await locationDbContext.SaveChangesAsync();
                    location.Id = _location.Id;
                    return (true, location, null);
                }
                else
                {
                    return (false, null, "Location code is already exists");
                }
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> UpdateLocationAsync(int Id, Models.Location location)
        {
            try
            {
                if (LocationExists(Id))
                {
                    Db.Location _location = mapper.Map<Models.Location, Db.Location>(location);
                    locationDbContext.Entry(_location).State = EntityState.Modified;
                    await locationDbContext.SaveChangesAsync();
                    return (true, location, "Record updated successfully");
                }
                else
                {
                    return (false, null, "Location is not exists");
                }
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }
        public async Task<(bool IsSuccess, Models.Location Location, string ErrorMessage)> DeleteLocationAsync(int Id)
        {
            try
            {
                Db.Location location = locationDbContext.Locations.AsNoTracking().Where(a => a.Id == Id).FirstOrDefault();
                if (location == null)
                {
                    return (false, null, "record not found");
                }
                locationDbContext.Locations.Remove(location);
                await locationDbContext.SaveChangesAsync();
                return (true, mapper.Map<Db.Location, Models.Location>(location), "Record deleted successfully");
            }
            catch (Exception ex)
            {
                logger?.LogError(ex.ToString());
                return (false, null, ex.Message);
            }
        }

        private bool LocationExists(int id)
        {
            return locationDbContext.Locations.AsNoTracking().Count(e => e.Id == id) > 0;
        }

        private bool LocationCodeExists(string locationCode)
        {
            return locationDbContext.Locations.AsNoTracking().Count(e => e.LocationCode.ToLower() == locationCode.ToLower()) > 0;
        }
        public void SeedData()
        {
            if (!locationDbContext.Locations.Any())
            {
                locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0091", RegionId = 5, Name = "BOB GRAHAM EDUCATION CENTER", MaintenanceCenter = "1", SchoolType = "K8" });
                locationDbContext.Locations.Add(new Db.Location() { LocationCode = "0092", RegionId = 1, Name = "NORMAN S. EDELCUP/SUNNY ISLES BEACH K-8", MaintenanceCenter = "1", SchoolType = "K8" });
                locationDbContext.Locations.Add(new Db.Location() { LocationCode = "7511", RegionId = 4, Name = "MIAMI SPRINGS SHS", MaintenanceCenter = "2", SchoolType = "S" });
                //locationDbContext.Locations.Add(new Db.Location() { Id = 3, LocationCode = "Loc3", RegionId = 3, Name = "BOB GRAHAM EDUCATION CENTER 3", MaintenanceCenter = "1", SchoolType = "US" });
                //locationDbContext.Locations.Add(new Db.Location() { Id = 4, LocationCode = "Loc4", RegionId = 1, Name = "BOB GRAHAM EDUCATION CENTER 4", MaintenanceCenter = "1", SchoolType = "US" });
                //locationDbContext.Locations.Add(new Db.Location() { Id = 5, LocationCode = "Loc5", RegionId = 2, Name = "BOB GRAHAM EDUCATION CENTER 5", MaintenanceCenter = "1", SchoolType = "US" });
                //locationDbContext.Locations.Add(new Db.Location() { Id = 6, LocationCode = "Loc6", RegionId = 3, Name = "BOB GRAHAM EDUCATION CENTER 6", MaintenanceCenter = "1", SchoolType = "US" });
                locationDbContext.SaveChanges();
            }

        }



    }
}