using ConfectioneryContracts.BindingModels;
using ConfectioneryContracts.BusinessLogicsContracts;
using ConfectioneryContracts.SearchModels;
using ConfectioneryDataModels.Models;
using Microsoft.Extensions.Logging;

namespace ConfectioneryView
{
	public partial class FormPastry : Form
	{
		private readonly ILogger _logger;
		private readonly IPastryLogic _logic;
		private int? _id;
		private Dictionary<int, (IComponentModel, int)> _pastryComponents;
		public int Id { set { _id = value; } }
		public FormPastry(ILogger<FormPastry> logger, IPastryLogic logic)
		{
			InitializeComponent();
			_logger = logger;
			_logic = logic;
			_pastryComponents = new Dictionary<int, (IComponentModel, int)>();
		}
		private void FormPastry_Load(object sender, EventArgs e)
		{
			if (_id.HasValue)
			{
				_logger.LogInformation("Загрузка изделия");
				try
				{
					var view = _logic.ReadElement(new PastrySearchModel
					{
						Id = _id.Value
					});
					if (view != null)
					{
						textBoxName.Text = view.PastryName;
						textBoxPrice.Text = view.Price.ToString();
						_pastryComponents = view.PastryComponents ?? new
						Dictionary<int, (IComponentModel, int)>();
						LoadData();
					}
				}
				catch (Exception ex)
				{
					_logger.LogError(ex, "Ошибка загрузки изделия");
					MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
					MessageBoxIcon.Error);
				}
			}
		}
		private void LoadData()
		{
			_logger.LogInformation("Загрузка компонент изделия");
			try
			{
				if (_pastryComponents != null)
				{
					dataGridView.Rows.Clear();
					foreach (var pc in _pastryComponents)
					{
						dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.Item1.ComponentName, pc.Value.Item2 });
					}
					textBoxPrice.Text = CalcPrice().ToString();
				}
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка загрузки компонент изделия");
				MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
				MessageBoxIcon.Error);
			}
		}
		private void ButtonAdd_Click(object sender, EventArgs e)
		{
			var service =
			Program.ServiceProvider?.GetService(typeof(FormPastryComponent));
			if (service is FormPastryComponent form)
			{
				if (form.ShowDialog() == DialogResult.OK)
				{
					if (form.ComponentModel == null)
					{
						return;
					}
					_logger.LogInformation("Добавление нового компонента: { ComponentName}- { Count}",
						form.ComponentModel.ComponentName, form.Count);
					if (_pastryComponents.ContainsKey(form.Id))
					{
						_pastryComponents[form.Id] = (form.ComponentModel,
						form.Count);
					}
					else
					{
						_pastryComponents.Add(form.Id, (form.ComponentModel,
						form.Count));
					}
					LoadData();
				}
			}
		}
		private void ButtonUpd_Click(object sender, EventArgs e)
		{
			if (dataGridView.SelectedRows.Count == 1)
			{
				var service = Program.ServiceProvider?.GetService(typeof(FormPastryComponent));
				if (service is FormPastryComponent form)
				{
					int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
					form.Id = id;
					form.Count = _pastryComponents[id].Item2;
					if (form.ShowDialog() == DialogResult.OK)
					{
						if (form.ComponentModel == null)
						{
							return;
						}
						_logger.LogInformation("Изменение компонента: { ComponentName} - { Count} ",
							form.ComponentModel.ComponentName, form.Count);
						_pastryComponents[id] = (form.ComponentModel, form.Count);
						LoadData();
					}
				}
			}
		}
		private void ButtonDel_Click(object sender, EventArgs e)
		{
			if (dataGridView.SelectedRows.Count == 1)
			{
				if (MessageBox.Show("Удалить запись?", "Вопрос",
				MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
				{
					try
					{
						_logger.LogInformation("Удаление компонента: { ComponentName}- { Count}",
							dataGridView.SelectedRows[0].Cells[1].Value);
						_pastryComponents?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
					}
					catch (Exception ex)
					{
						MessageBox.Show(ex.Message, "Ошибка",
						MessageBoxButtons.OK, MessageBoxIcon.Error);
					}
					LoadData();
				}
			}
		}
		private void ButtonRef_Click(object sender, EventArgs e)
		{
			LoadData();
		}
		private void ButtonSave_Click(object sender, EventArgs e)
		{
			if (string.IsNullOrEmpty(textBoxName.Text))
			{
				MessageBox.Show("Заполните название", "Ошибка",
				MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			if (string.IsNullOrEmpty(textBoxPrice.Text))
			{
				MessageBox.Show("Заполните цену", "Ошибка", MessageBoxButtons.OK,
				MessageBoxIcon.Error);
				return;
			}
			if (_pastryComponents == null || _pastryComponents.Count == 0)
			{
				MessageBox.Show("Заполните компоненты", "Ошибка",
				MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			_logger.LogInformation("Сохранение изделия");
			try
			{
				var model = new PastryBindingModel
				{
					Id = _id ?? 0,
					PastryName = textBoxName.Text,
					Price = Convert.ToDouble(textBoxPrice.Text),
					PastryComponents = _pastryComponents
				};
				var operationResult = _id.HasValue ? _logic.Update(model) :
				_logic.Create(model);
				if (!operationResult)
				{
					throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
				}
				MessageBox.Show("Сохранение прошло успешно", "Сообщение",
				MessageBoxButtons.OK, MessageBoxIcon.Information);
				DialogResult = DialogResult.OK;
				Close();
			}
			catch (Exception ex)
			{
				_logger.LogError(ex, "Ошибка сохранения изделия");
				MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}
		private void ButtonCancel_Click(object sender, EventArgs e)
		{
			DialogResult = DialogResult.Cancel;
			Close();
		}
		private double CalcPrice()
		{
			double price = 0;
			foreach (var elem in _pastryComponents)
			{
				price += ((elem.Value.Item1?.Cost ?? 0) * elem.Value.Item2);
			}
			return Math.Round(price * 1.1, 2);
		}
	}
}