using AppLibs.Libs;
using ManagementApp.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Graph;
using Azure.Identity;
using Microsoft.AspNetCore.Connections.Features;
using System.Diagnostics.Metrics;
using ManagementApp.Models.Services;
using System.Security.Cryptography;
using System.Text.Encodings;
using System.Text;
using Microsoft.Graph.Models;
using AppLibs.Libs.Crypt;

namespace ManagementApp.Controllers
{
    public class StorageController : Controller
    {
        Microsoft365Service service;
        public StorageController(Microsoft365Service service) {
            this.service = service;
        }

        [PageInfor("6101", "Config Storage")]
        public Task<IActionResult> Index()
        {
            return this.ViewAsync();
        }

        [PageInfor("6102", "Type Storage")]
        public Task<IActionResult> Type()
        {
            return this.ViewAsync();
        }

        [PageInfor("6103", "Validation Domain")]
        public Task<IActionResult> ValidationDomain()
        {
            return this.ViewAsync();
        }


        [HttpPost]
        public async Task<IActionResult> AddValidationDomain([FromForm] ValidationDomainModel model)
        {
            return Json(await model.AddAsync());
        }

        [HttpPost]
        public async Task<IActionResult> GetValidationDomain([FromForm] ValidationDomainModel model)
        {
            return await model.GetValidationDomainAsync();
        }

        [HttpPost]
        public async Task<IActionResult> UpdateValidationDomain([FromForm] ValidationDomainModel model)
        {
            return Json(await model.UpdateAsync());
        }

        [HttpPost]
        public async Task<IActionResult> AddType([FromBody] TypeStorageServerModel model)
        { 
            return Json(await model.AddAsync());
        }

        [HttpPost]
        public async Task<IActionResult> GetTypeStorage([FromForm] TypeStorageServerModel model)
        {
            return await model.GetTypeStoragesAsync();
        }

        [HttpGet]
        public async Task<IActionResult> GetTypeStorage()
        {
            return await TypeStorageServerModel.GetAllTypeStorage();
        }

        [HttpGet]
        public async Task<IActionResult> GetValidationDomain()
        {
            return await ValidationDomainModel.GetAllValidationDomain();
        }

        [HttpPost]
        public async Task<IActionResult> UpdateType([FromBody] TypeStorageServerModel model)
        {
            return Json(await model.UpdateAsync());
        }

        [HttpGet]
        public async Task<IActionResult> GenerationAccessToken()
        {
            var t1 = Task<string>.Run(() =>
            {
                var g = Guid.NewGuid();
                return Base64UrlTextEncoder.Encode(g.ToByteArray().Concat(BitConverter.GetBytes(DateTime.UtcNow.ToFileTime())).ToArray());
            });

            var t2 = Task<string>.Run(() => {
                var g = Guid.NewGuid();
                var bytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);

                Array.Resize(ref bytes, 16);

               
                byte[] data = new byte[32];
                bytes.CopyTo(data, 0);
                g.ToByteArray().CopyTo(data, 16);
                var hash = new CRC64();
              
                return hash.HashToString(data);

            });
            await Task.WhenAll(t1, t2);

            return Json(new
            {
                idToken = t2.Result.ToLower(),
                tokenValue = t1.Result
            });
        }
        //[HttpPost]
        //public async Task<IActionResult> AddConfig

        public async Task<IActionResult> LongPolling()
        {
            await Task.Delay(TimeSpan.FromSeconds(1));
            if (this.service.Status == 0)
            {
                var u = await service.GetUser();
                
                return Json(new
                {
                    Message = service.Message,
                    User = (u != null)?u.Value.Select(u=>u.DisplayName).ToList<string>(): null
                });
            }
            return StatusCode(StatusCodes.Status204NoContent);
        }

        public async Task<IActionResult> GetSites()
        {
            if (this.service.Status == 0)
            {
                var u = await service.GetDrives();

                return Json(new
                {
                    Message = service.Message,
                    User = (u != null) ? u.Value.Where(a => a.IsPersonalSite == false && a.DisplayName == "Storage Backup").Select(a => new { a.Id, a.Name, a.WebUrl, a.SiteCollection, a.IsPersonalSite }): null
                });
            }
            return StatusCode(StatusCodes.Status204NoContent);
        }


        [HttpGet]
        public async Task<IActionResult> LoginMicrosoft365()
        {
            service.Host = Request.Scheme + "://" + Request.Host.Value;
            return Json(new { Path = await service.ConnectMicrosoft365() } );
        }
    }
}
