using ComputerShopContracts.BindingModels;
using ComputerShopContracts.BusinessLogicContracts;
using ComputerShopContracts.SearchModels;
using ComputerShopContracts.StorageContracts;
using ComputerShopContracts.ViewModels;
using ComputerShopDatabaseImplement.Implements;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing.Charts;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Reflection;

namespace ComputerShopRestApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class OrderController : Controller
    {
        private readonly ILogger _logger;
        private readonly IOrderLogic _order;
        private readonly IOrderStorage _orderStorage;

        public OrderController(ILogger<MainController> logger, IOrderLogic order, ISupplyLogic supply, IOrderStorage orderStorage)
        {
            _logger = logger;
            _order = order;
			_orderStorage = orderStorage;

        }

        [HttpGet]
        public List<OrderViewModel>? GetOrderList(int clientId)
        {

            try
            {
                return _order.ReadList(new OrderSearchModel { ClientId = clientId });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка получения списка заказов");
                throw;
            }
        }

		[HttpGet]
		public OrderViewModel? GetOrder(int id)
		{

			try
			{
				var order = new OrderViewModel();
				order = _order.ReadElement(new OrderSearchModel { Id = id });
				return order;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка получения заказа");
				throw;
			}
		}

		[HttpGet]
        public List<OrderViewModel>? GetOrders(int clientId)
        {
            try
            {
                return _order.ReadList(new OrderSearchModel {});
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка получения списка заказов клиента id={Id}", clientId);
                throw;
            }
        }

        [HttpPost]
        public void CreateOrder(int assembly_id, int amount, OrderBindingModel model)
        {
            try
            {
                var new_order = _order.CreateOrder(model);
				if (new_order != null)
				{
					_order.AddAssembly(new OrderSearchModel() { Id = new_order.Id }, 
						new AssemblySearchModel() { Id = assembly_id } , amount);
				}
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка создания заказа");
                throw;
            }
        }
        [HttpPost]
        public void DeleteOrder(OrderBindingModel model)
        {
            try
            {
                _order.Delete(model);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка при удалении заказа");
                throw;
            }
        }

		[HttpPost]
		public void FinishOrder(int id)
		{
			try
			{
				var order = _orderStorage.GetElement(new() { Id = id });
				OrderBindingModel model = new OrderBindingModel()
				{
					Id = id,
					ClientId = order.ClientId,
					DateImplement = order.DateImplement,
					Status = order.Status
				};
				_order.FinishOrder(model);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка изменения закупки");
				throw;
			}
		}
		[HttpPost]
		public void DeliveryOrder(int id)
		{
			try
			{
				var order = _orderStorage.GetElement(new() { Id = id });
				OrderBindingModel model = new OrderBindingModel()
				{
					Id = id,
					ClientId = order.ClientId,
					DateImplement = order.DateImplement,
					Status = order.Status
				};
				_order.DeliveryOrder(model);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка изменения закупки");
				throw;
			}
		}
		[HttpPost]
		public void TakeOrderInWork(int id)
		{
			try
			{
				var order = _orderStorage.GetElement(new() { Id = id });

				OrderBindingModel model = new OrderBindingModel()
				{
					Id = id,
					ClientId = order.ClientId,
					DateImplement = order.DateImplement,
					Status = order.Status
				};
				_order.TakeOrderInWork(model);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка изменения получения техники");
				throw;
			}
		}

		[HttpPost]
		public void AddAssembly(Tuple<OrderSearchModel, AssemblySearchModel, int> model)
		{
			try
			{
				_order.AddAssembly(model.Item1, model.Item2, model.Item3);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка добавления компонента в сборку.");
				throw;
			}
		}
		

		[HttpPost]
		public void EditOrder(OrderBindingModel model)
		{
			try
			{
				_order.Update(model);
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка обновления заказа.");
				throw;
			}
		}
		[HttpGet]
		public List<AssemblyViewModel>? GetAssembliesByOrder(int orderId)
		{
			try
			{
				var list = _orderStorage.GetAssembliesByOrder(new OrderSearchModel() { Id = orderId });
                return list;
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка получения компонента по orderid={Id}", orderId);
				throw;
			}
		}
	}
}
