using CarCenterAdministratorApp.Models;
using CarCenterBusinessLogic.BusinessLogics;
using CarCenterContracts.BindingModels;
using CarCenterContracts.BusinessLogicsContracts;
using CarCenterContracts.SearchModels;
using CarCenterContracts.ViewModels;
using CarCenterDataBaseImplement;
using CarCenterDataBaseImplement.Models;
using CarCenterDataModels.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.IdentityModel.Tokens;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;

namespace CarCenterAdministratorApp.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly ICarLogic _car;
        private readonly IEquipmentLogic _equipment;
        private readonly IInspectionLogic _inspection;


        public HomeController(ILogger<HomeController> logger, ICarLogic car, IEquipmentLogic equipment, IInspectionLogic inspection)
        {
            _logger = logger;
            _car = car;
            _equipment = equipment;
            _inspection = inspection;
        }

        public IActionResult Index()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View();
        }

        [HttpGet]
        public IActionResult Privacy()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View(APIClient.Administrator);
        }

        [HttpPost]
        public void Privacy(string email, string password, string fio, string telephone)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Вы как сюда попали? Сюда вход только авторизованным");
            }
            if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
            {
                throw new Exception("Введите логин, пароль и ФИО");
            }
            APIClient.PostRequest("api/administrator/updatedata", new AdministratorBindingModel
            {
                Id = APIClient.Administrator.Id,
                AdministratorFIO = fio,
                AdministratorLogin = email,
                AdministratorPassword = password,
                AdministratorEmail = email,
                AdministratorNumber = telephone
            });

            APIClient.Administrator.AdministratorFIO = fio;
            APIClient.Administrator.AdministratorLogin = email;
            APIClient.Administrator.AdministratorPassword = password;
            APIClient.Administrator.AdministratorEmail = email;
            APIClient.Administrator.AdministratorNumber = telephone;
            Response.Redirect("Index");
        }

        [HttpGet]
        public IActionResult Register()
        {
            return View();
        }

        [HttpPost]
        public void Register(string email, string password, string fio, string telephone)
        {
            if (string.IsNullOrEmpty(password) || string.IsNullOrEmpty(fio))
            {
                throw new Exception("Введите логин, пароль и ФИО");
            }
            APIClient.PostRequest("api/administrator/register", new AdministratorBindingModel
            {
                AdministratorFIO = fio,
                AdministratorNumber = telephone,
                AdministratorLogin = email,
                AdministratorEmail = email,
                AdministratorPassword = password

            });

            Response.Redirect("Enter");
            return;
        }

        [HttpGet]
        public IActionResult Enter()
        {
            return View();
        }

        [HttpPost]
        public void Enter(string login, string password)
        {
            if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
            {
                throw new Exception("Введите логин и пароль");
            }
            APIClient.Administrator = APIClient.GetRequest<AdministratorViewModel>($"api/administrator/login?login={login}&password={password}");
            if (APIClient.Administrator == null)
            {
                throw new Exception("Неверный логин/пароль");
            }
            Response.Redirect("Index");
        }

        public IActionResult CreateCar()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View();
        }

        [HttpPost]
        public void CreateCar(string brandCar, string model)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            if (string.IsNullOrEmpty(brandCar))
            {
                throw new Exception("Введите бренд машины");
            }
            if (string.IsNullOrEmpty(model))
            {
                throw new Exception("Введите модель машины");
            }
            APIClient.PostRequest("api/main/createcar", new CarBindingModel
            {
                BrandCar = brandCar,
                Model = model,
                AdministratorId = APIClient.Administrator.Id,
            });
            Response.Redirect("ListCars");
        }

        public IActionResult ListCars()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View(APIClient.GetRequest<List<CarViewModel>>($"api/main/getcarlist?administratorId={APIClient.Administrator.Id}"));
        }

        public IActionResult UpdateCar()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>($"api/main/getcarlist?administratorId={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void UpdateCar(int car, string brandCar, string model)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            if (string.IsNullOrEmpty(brandCar))
            {
                throw new Exception("заполните все поля");
            }
            if (string.IsNullOrEmpty(model))
            {
                throw new Exception("заполните все поля");
            }

            APIClient.PostRequest("api/main/updatecar", new CarBindingModel
            {
                Id = car,
                BrandCar = brandCar,
                Model = model,
                AdministratorId = APIClient.Administrator.Id,
            });

            Response.Redirect("ListCars");
        }

        public IActionResult DeleteCar()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>($"api/main/getcarlist?administratorId={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void DeleteCar(int car)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            APIClient.PostRequest("api/main/deletecar", new CarBindingModel
            {
                Id = car
            });
            Response.Redirect("ListCars");
        }

        public IActionResult ListEquipments()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View(APIClient.GetRequest<List<EquipmentViewModel>>($"api/main/getequipmentlist?administratorId={APIClient.Administrator.Id}"));
        }

		[HttpGet]
		public IActionResult CreateEquipment()
		{
			if (APIClient.Administrator == null)
			{
				return Redirect("~/Home/Enter");
			}
			var list = _car.ReadList(new CarSearchModel { AdministratorId = APIClient.Administrator.Id });
			var simpCar = list.Select(x => new { CarId = x.Id, BrandCar = x.BrandCar });
			ViewBag.Cars = new MultiSelectList(simpCar, "CarId", "BrandCar");
			return View();
		}

		[HttpPost]
		public void CreateEquipment(string equipmentName, double equipmentPrice, int[] cars)
		{
			if (APIClient.Administrator == null)
			{
				throw new Exception("Необходима авторизация");
			}
			if (string.IsNullOrEmpty(equipmentName) || equipmentPrice <= 0 || cars.Length == 0)
			{
				throw new Exception("Введите название и стоимость");
			}
			Dictionary<int, ICarModel> equipmentCars = new Dictionary<int, ICarModel>();
			foreach (int id in cars)
			{
				equipmentCars.Add(id, _car.ReadElement(new CarSearchModel { Id = id }));
			}

			APIClient.PostRequest("api/main/CreateEquipment", new EquipmentBindingModel
			{
				AdministratorId = APIClient.Administrator.Id,
				EquipmentName = equipmentName,
				EquipmentPrice = equipmentPrice,
				DateCreateEquipment = DateTime.Now
			});
			for (int i = 0; i < cars.Length; i++)
			{
				APIClient.PostRequest("api/main/AddCarToEquipment", Tuple.Create(
				new EquipmentSearchModel() { EquipmentName = equipmentName },
				new CarViewModel() { Id = cars[i] }
			));
			}
			Response.Redirect("ListEquipments");
		}


        public IActionResult UpdateEquipment()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Equipments = APIClient.GetRequest<List<EquipmentViewModel>>($"api/main/getequipmentlist?administratorId={APIClient.Administrator.Id}");
            ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>($"api/main/getcarlist?administratorid={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void UpdateEquipment(int equipment, string equipmentName, double equipmentPrice, List<int> cars)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            if (string.IsNullOrEmpty(equipmentName))
            {
                throw new Exception("Введите название");
            }
            if (string.IsNullOrEmpty(equipmentPrice.ToString()))
            {
                throw new Exception("Введите стоимость");
            }
            Dictionary<int, ICarModel> a = new Dictionary<int, ICarModel>();
            foreach (int car in cars)
            {
                a.Add(car, new CarSearchModel { Id = car } as ICarModel);
            }
            APIClient.PostRequest("api/main/updateequipment", new EquipmentBindingModel
            {
                Id = equipment,
                AdministratorId = APIClient.Administrator.Id,
                EquipmentName = equipmentName,
                EquipmentPrice = equipmentPrice,
                EquipmentCars = a,
            });
            Response.Redirect("ListEquipments");
        }


        public IActionResult DeleteEquipment()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Equipments = APIClient.GetRequest<List<EquipmentViewModel>>($"api/main/getequipmentlist?administratorId={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void DeleteEquipment(int equipment)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            APIClient.PostRequest("api/main/deleteequipment", new EquipmentBindingModel
            {
                Id = equipment
            });
            Response.Redirect("ListEquipments");
        }

        public IActionResult ListInspections()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            return View(APIClient.GetRequest<List<InspectionViewModel>>($"api/main/getInspectionlist?administratorId={APIClient.Administrator.Id}"));
        }
        public IActionResult CreateInspection()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            var list = _car.ReadList(new CarSearchModel { AdministratorId = APIClient.Administrator.Id });
            var simpCar = list.Select(x => new { CarId = x.Id, BrandCar = x.BrandCar });
            ViewBag.Cars = new MultiSelectList(simpCar, "CarId", "BrandCar");
            return View();
        }

        [HttpPost]
        public void CreateInspection(string inspectionName, DateTime inspectionDate, int[] cars)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            if (string.IsNullOrEmpty(inspectionName) || cars.Length == 0)
            {
                throw new Exception("Введите название и стоимость");
            }
            Dictionary<int, ICarModel> inspectionCars = new Dictionary<int, ICarModel>();
            foreach (int id in cars)
            {
                inspectionCars.Add(id, _car.ReadElement(new CarSearchModel { Id = id }));
            }

            APIClient.PostRequest("api/main/Createinspection", new InspectionBindingModel
            {
                AdministratorId = APIClient.Administrator.Id,
                InspectionName = inspectionName,
                InspectionDate = inspectionDate
            });
            for (int i = 0; i < cars.Length; i++)
            {
                APIClient.PostRequest("api/main/AddCarToInspection", Tuple.Create(
                new InspectionSearchModel() { InspectionName = inspectionName },
                new CarViewModel() { Id = cars[i] }
            ));
            }
            Response.Redirect("ListInspections");
        }
        public IActionResult UpdateInspection()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
			ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>($"api/main/getcarlist?administratorid={APIClient.Administrator.Id}");
			ViewBag.Inspections = APIClient.GetRequest<List<InspectionViewModel>>($"api/main/getinspectionlist?administratorId={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void UpdateInspection(int inspection, string inspectionName, DateTime inspectionDate, List<int> cars)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            if (string.IsNullOrEmpty(inspectionName))
            {
                throw new Exception("Введите название");
            }
			Dictionary<int, ICarModel> a = new Dictionary<int, ICarModel>();
			foreach (int car in cars)
			{
				a.Add(car, new CarSearchModel { Id = car } as ICarModel);
			}
			APIClient.PostRequest("api/main/updateinspection", new InspectionBindingModel
            {
                Id = inspection,
                AdministratorId = APIClient.Administrator.Id,
                InspectionName = inspectionName,
                InspectionDate = inspectionDate,
				InspectionCars = a,
			});
			Response.Redirect("ListInspections");
        }

        public IActionResult DeleteInspection()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Inspections = APIClient.GetRequest<List<InspectionViewModel>>($"api/main/getinspectionlist?administratorId={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void DeleteInspection(int inspection)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }
            APIClient.PostRequest("api/main/deleteinspection", new InspectionBindingModel
            {
                Id = inspection
            });
            Response.Redirect("ListInspections");
        }

        public IActionResult AddEquipmentToPreSaleWork()
		{
			if (APIClient.Administrator == null)
			{
				return Redirect("~/Home/Enter");
			}
			ViewBag.Equipments = APIClient.GetRequest<List<EquipmentViewModel>>($"api/main/getequipmentlist?administratorId={APIClient.Administrator.Id}");
			ViewBag.PreSaleWorks = APIClient.GetRequest<List<PreSaleWorkViewModel>>($"api/main/getpreSaleWorks");
			return View();
		}

        [HttpPost]
        public void AddEquipmentToPreSaleWork(int preSaleWork, int equipment)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Необходима авторизация");
            }

            using var context = new CarCenterDataBase();
            List<int> cars = context.EquipmentCars
                .Where(rd => rd.EquipmentId == equipment)
                .Select(rd => rd.CarId)
                .ToList();

            Dictionary<int, ICarModel> a = new Dictionary<int, ICarModel>();
            foreach (int car in cars)
            {
                a.Add(car, new CarSearchModel { Id = car } as ICarModel);
            }

            var equipmentElem = APIClient.GetRequest<EquipmentViewModel>($"api/main/getequipmentbyid?EquipmentId={equipment}");
            APIClient.PostRequest("api/main/updateequipment", new EquipmentBindingModel
            {
                Id = equipment,
                PreSaleWorkId = preSaleWork,
                EquipmentName = equipmentElem.EquipmentName,
                EquipmentPrice = equipmentElem.EquipmentPrice,
                AdministratorId = equipmentElem.AdministratorId,
                EquipmentCars = a,
            });
            Response.Redirect("ListEquipments");
        }


        /*public IActionResult ListCarsToPdfFile()
        {
            return View();
        }
        public IActionResult ListCarEquipmentToFile()
        {
            return View();
        }*/
        [HttpGet]
        public IActionResult PreSaleWorkCarReport()
        {
            if (APIClient.Administrator == null)
            {
                return Redirect("~/Home/Enter");
            }
            ViewBag.Cars = APIClient.GetRequest<List<CarViewModel>>($"api/main/GetCarList?Administratorid={APIClient.Administrator.Id}");
            return View();
        }

        [HttpPost]
        public void PreSaleWorkCarReport(List<int> cars, string type)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Вы как суда попали? Суда вход только авторизованным");
            }

            if (cars.Count <= 0)
            {
                throw new Exception("Количество должно быть больше 0");
            }

            if (string.IsNullOrEmpty(type))
            {
                throw new Exception("Неверный тип отчета");
            }

            if (type == "docx")
            {
                APIClient.PostRequest("api/main/createPreSaleWorklistwordfile", new ReportPreSaleWorkCarBindingModel
                {
                    Cars = cars,
                    FileName = "C:\\Users\\kozlo\\Desktop\\reports\\wordfile.docx"
                });
                Response.Redirect("GetWordFile");
            }
            else
            {
                APIClient.PostRequest("api/main/createPreSaleWorklistexcelfile", new ReportPreSaleWorkCarBindingModel
                {
                    Cars = cars,
                    FileName = "C:\\Users\\kozlo\\Desktop\\reports\\excelfile.xlsx"
                });
                Response.Redirect("GetExcelFile");
            }
        }

        [HttpGet]
        public IActionResult GetWordFile()
        {
            return new PhysicalFileResult("C:\\Users\\kozlo\\Desktop\\reports\\wordfile.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        }

        public IActionResult GetExcelFile()
        {
            return new PhysicalFileResult("C:\\Users\\kozlo\\Desktop\\reports\\excelfile.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        }

        [HttpGet]
        public IActionResult Report()
        {
            ViewBag.Report = new List<ReportEquipmentsEmployeesBindingModel>();
            return View();
        }

        [HttpGet]
        public string GetCarsReport(DateTime dateFrom, DateTime dateTo)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Вы как суда попали? Суда вход только авторизованным");
            }
            List<ReportEquipmentsEmployeesViewModel> result;
            try
            {
                string dateFromS = dateFrom.ToString("s", CultureInfo.InvariantCulture);
                string dateToS = dateTo.ToString("s", CultureInfo.InvariantCulture);
                result = APIClient.GetRequest<List<ReportEquipmentsEmployeesViewModel>>
                    ($"api/main/GetEquipmentsEmployeesReport?datefrom={dateFromS}&dateto={dateToS}&administratorid={APIClient.Administrator.Id}")!;

            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка создания отчета");
                throw;
            }
            string table = "";
            table += "<h2 class=\"text-custom-color-1\">Предварительный отчет</h2>";
            table += "<div class=\"table-responsive\">";
            table += "<table class=\"table table-striped table-bordered table-hover\">";
            table += "<thead class=\"table-dark\">";
            table += "<tr>";
            table += "<th scope=\"col\">Дата</th>";
            table += "<th scope=\"col\">Название машины</th>";
            table += "<th scope=\"col\">Комплектация</th>";
            table += "<th scope=\"col\">Сотрудник</th>";
            table += "</tr>";
            table += "</thead>";
            foreach (var car in result)
            {
                table += "<tbody>";
                table += "<tr>";
                table += $"<td></td>";
                table += $"<td>{car.BrandCar}</td>";
                table += $"<td></td>";
                table += $"<td></td>";
                table += "</tr>";
                foreach (var equipment in car.Equipments)
                {
                    table += "<tr>";
                    table += $"<td>{equipment.DateCreateEquipment}</td>";
                    table += $"<td></td>";
                    table += $"<td>{equipment.EquipmentName}</td>";
                    table += $"<td></td>";
                    table += "</tr>";
                }
                foreach (var employee in car.Employees)
                {
                    table += "<tr>";
                    table += $"<td></td>";
                    table += $"<td></td>";
                    table += $"<td></td>";
                    table += $"<td>{employee.EmployeeFIO}</td>";
                    table += "</tr>";
                }
                table += "</tbody>";
            }
            table += "</table>";
            table += "</div>";
            return table;
        }

        [HttpPost]
        public void Report(DateTime dateFrom, DateTime dateTo)
        {
            if (APIClient.Administrator == null)
            {
                throw new Exception("Вы как суда попали? Суда вход только авторизованным");
            }
            APIClient.PostRequest("api/main/sendEquipmentsEmployeesreporttoemail", new ReportEquipmentsEmployeesBindingModel
            {
                FileName = "C:\\Users\\kozlo\\Desktop\\reports\\pdffile.pdf",
                AdministratorId = APIClient.Administrator.Id,
                DateFrom = dateFrom,
                DateTo = dateTo,
                Email = APIClient.Administrator.AdministratorEmail

            });
            Response.Redirect("Report");

        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
}