namespace sngc.Web.Controllers
{
    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class LocationController : ODataController
    {
        private readonly MyDbContext db;
        private readonly AuthorizationHelper authHelper;
        public LocationController(MyDbContext context)
        {
            db = context;
            authHelper = new AuthorizationHelper(Main.IsAuthenticationEnabled);
        }

        [Permission("location", PermissionType.View)]
        [Route("/odata/GetLocation")]
        public IActionResult GetLocation(ODataQueryOptions<LocationModel> queryOptions, bool isExport)
        {
            queryOptions = Util.GetQueryOptionsWithConvertedDates(queryOptions);
            var itemsQueryable = GetLocation();
            var items = (queryOptions.ApplyTo(itemsQueryable) as IEnumerable<LocationModel>)?.ToList();

            if (isExport)
                return File(Util.Excel.GetExportFileStream(items), "application/octet-stream");
            else
                return Ok(items);
        }
        [Permission("location", PermissionType.View)]
        [Route("[action]")]
        public IQueryable<LocationModel> GetLocation()
        {
            var itemsQueryable = db.Locations.Select(x => new LocationModel()
            {
                LocationId = x.Id,
                LocationName = x.Name
            }
            ).AsNoTracking();

            return itemsQueryable;
        }

        [Permission("Location", PermissionType.View)]
        [Route("GetRequiredData")]
        public async Task<IActionResult> GetRequiredData()
        {
            var hasModifyPermission = await authHelper.IsAuthorizedAsync(User, "Location", PermissionType.Modify);
            var result = new { hasModifyPermission };
            return Ok(result);
        }
        [Permission("Location", PermissionType.View)]
        [Route("[action]")]
        public async Task<IActionResult> GetDetail(string LocationName)
        {
            var detail = await (
                from q in db.Locations
                where q.Name == LocationName
                select new LocationModel
                {
                    LocationId = q.Id,
                    LocationName = q.Name ?? "",

                }
            ).AsNoTracking().FirstAsync();

            return Ok(detail);
        }

        [Permission("Location", PermissionType.Modify)]
        [Route("[action]")]
        public async Task<IActionResult> SaveLocation(LocationModel detail, Enums.SaveType saveType)
        {
            int resultId = 0;

            await db.Database.CreateExecutionStrategy().Execute(async () =>
            {
                using var dbContextTransaction = await db.Database.BeginTransactionAsync();
                Location? dbItem = null;
                if (saveType != Enums.SaveType.New)
                {
                    dbItem = await (
                        from q in db.Locations
                        where q.Id == detail.LocationId
                        select q
                    ).FirstOrDefaultAsync();
                }

                if (dbItem == null) //if the item does not exist then add it
                {
                    dbItem = new Location();
                    db.Locations.Add(dbItem);
                }
                else
                {
                    //remove existing items so that they get completely re-inserted
                }

                var d = detail;
                dbItem.Name = d.LocationName;

                await db.SaveChangesAsync();
                resultId = dbItem.Id;


                await dbContextTransaction.CommitAsync();
            });

            return Ok(resultId);
        }
        [Permission("Location", PermissionType.Modify)]
        [HttpDelete]
        [Route("[action]/{Name}")]
        public async Task<IActionResult> Deletelocation(string Name)
        {
            Location dbitem = await db.Locations.Where(x => x.Name == Name).FirstAsync();
            db.Locations.Remove(dbitem);

            await db.SaveChangesAsync();

            return Ok();
        }
    }
}
