using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Xml.Linq;
using Google.Maps;
using Google.Maps.Geocoding;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using PositioningWebApp.DBServices;
using PositioningWebApp.Models;
using PositioningWebApp.Models.Ajax;
using PositioningWebApp.Models.Api;
using PositioningWebApp.Models.DB;
using PositioningWebApp.Models.UserProfile;
using PositioningWebApp.Models.ViewModels;
using PositioningWebApp.Security;
using PositioningWebApp.Services;
using PositioningWebApp.Services.Validation;

namespace PositioningWebApp.Pages
{
	public class IndexModel : PageModel
	{
		private readonly DevicesOnMapBackgroundContext databaseManager;
		private readonly IHostingEnvironment _hostingEnvironment;
		public IndexModel(DevicesOnMapBackgroundContext context, IHostingEnvironment hostingEnvironment)
		{
			try
			{
				_hostingEnvironment = hostingEnvironment;
				databaseManager = context;
			} catch(Exception ex)
			{
				throw ex;
			}
		}
		[BindProperty]
		public ModelLogin LoginViewModel { get; set; }
		[BindProperty]
		public Register RegisterViewModel { get; set; }
		public void OnGet()
		{
			List<int> vs = new List<int> { 1 };
			Point point = new Point
			{
				Latitude = 49.583288,
				Longitude = 17.252007
			};
			new InZone().IsDeviceInsideZones(vs, point, databaseManager);
			
		}
		public async Task<IActionResult> OnPostLogIn()
		{
			try
			{


				// Verification.  
				if (IsStateValid(6))
				{
					if (new UserService().LoginCorect(LoginViewModel.Email, LoginViewModel.Password, databaseManager))
					{


						await new Sign().In(new UserService().GetProfile(LoginViewModel.Email, databaseManager), false, Request.HttpContext);
						// Info.  
						var r = RedirectToPage("/Home/Home");

						return r;
					}
					else
					{
						// Setting.  
						ModelState.AddModelError(string.Empty, "Invalid email or password.");
						return this.Page();
					}
				} else
				{
					ModelState.AddModelError(string.Empty, "Please fill both fields.");
					return this.Page();
				}
				
				
			}
			catch (Exception ex)
			{
				// Info  
				throw ex;
			}
		}

		public async Task<IActionResult> OnPostReg()
		{
			try
			{
				
				if(IsStateValid(2))
				{
					if (RegisterViewModel.Email != null && RegisterViewModel.FirstName != null && RegisterViewModel.Password != null &&
					RegisterViewModel.Password2 != null && RegisterViewModel.PhoneNumber != null && RegisterViewModel.Surname != null)
					{
						string passw1 = this.RegisterViewModel.Password;
						string passw2 = this.RegisterViewModel.Password2;
						string firstName = this.RegisterViewModel.FirstName;
						string surname = this.RegisterViewModel.Surname;
						string email = this.RegisterViewModel.Email;
						string phone = this.RegisterViewModel.PhoneNumber;
						if (!passw1.Equals(passw2))
						{
							ModelState.AddModelError(string.Empty, "Passwords are not the same.");
							return this.Page();
						}

						// Verification.
						if (!new Email().Validate(email))
						{
							ModelState.AddModelError(string.Empty, "Not a valid email address");
							return this.Page();
						}
						if (new UserService().RegistrationEmailExist(email, databaseManager))
						{
							// Setting.  
							ModelState.AddModelError(string.Empty, "Email already exists.");
							return this.Page();
						}

						HashPassword hash = new HashPassword();

						var login = new Users
						{
							FirstName = firstName,
							Surname = surname,
							Email = email,
							PasswordHash = hash.GetHash(passw1),
							CreationDate = DateTime.Now,
							PhoneNumber = phone
						};
						var user = new UserService().AddUser(login, databaseManager);
						await new Sign().In(user, false, Request.HttpContext);
						return RedirectToPage("/Home/Home");
					}
					else
					{
						ModelState.AddModelError(string.Empty, "Please fill all fields.");
						return this.Page();
					}
				} else
				{
					return this.Page();
				}	
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}

		public JsonResult OnPostLogOff([FromBody] Select s)
		{
			try
			{
				new Sign().Off(Request.HttpContext);
			}
			catch (Exception ex)
			{
				// Info  
				throw ex;
			}

			// Info.  

			return new JsonResult("ret");
		}

		private bool IsStateValid(int position)
		{
			bool ret = true;
			foreach (var item in ModelState.Root.Children[position].Children)
			{
				if (!item.ValidationState.ToString().Equals("Valid"))
				{
					ret = false;
				}
				
			}
			return ret;
		}
	}
}

