using ManagementPage.Database;
using ManagementPage.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using MongoDB.Bson;
using MongoDB.Driver;
using System.Security.Claims;

namespace ManagementPage.Pages
{
    [Authorize]
    public class DevicePageModel : PageModel
    {
        public List<EnvironmentData> data;
        public List<DataSet> humidity;
        public List<DataSet> temperature;
        public DeviceData device;

        private readonly MongoDbClient _dbClient;

        public DevicePageModel(MongoDbClient dbClient)
        {
            data = new List<EnvironmentData>();
            humidity = new List<DataSet>();
            temperature = new List<DataSet>();
            _dbClient = dbClient;
        }

        public async Task<IActionResult> OnGetAsync()
        {
            var deviceId = 0l ;
            try
            {
                var idString = (string?)RouteData.Values.Where(k => k.Key == "id")?.First().Value;
                if (idString == null)
                {
                    throw new NullReferenceException();
                }

                deviceId = (Int64)UInt64.Parse(idString);
            }
            catch
            {
                return NotFound();
            }

            // get the logged in user
            var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            var filter = new BsonDocument("OpenId", userId);
            var claims = await _dbClient.AccountsCollection.Find(filter).SingleOrDefaultAsync();

            // No user?
            if (claims == null)
            {
                return Forbid();
            }

            // Get the device
            filter = new BsonDocument("ApiID", deviceId);
            device = await _dbClient.DeviceCollection.Find(filter).FirstOrDefaultAsync();

            // No device?
            if (device == null)
            {
                return NotFound();
            }

            // Device owned by someone else?
            if (!claims.Devices.Contains(device._id))
            {
                return Forbid();
            }

            using var cursor = await _dbClient.Collection.Find(filter).SortByDescending(x => x.Time).Limit(100).ToCursorAsync();
            data.AddRange(await cursor.ToListAsync());
            foreach (var item in data)
            {
                humidity.Add(new DataSet() { x = item.Time, y = item.Humidity });
                temperature.Add(new DataSet() { x = item.Time, y = item.Temperature });
            }

            humidity.Reverse();
            temperature.Reverse();

            return Page();
        }
    }
}
