using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Npgsql;
using Register_office.BaseClasses;
using Register_office.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Register_office.ViewModel
{
	internal class PatientViewModel
	{
		private readonly GeneralViewModel _general;

		internal GeneralViewModel General => _general;

		public PatientViewModel()
		{
			_general = GeneralViewModel.Instance;
		}

		/// <summary>
		/// Привязка данных к источникам данных таблицы
		/// </summary>
		/// <param name="dgv"></param>
		internal void SetDefaultDataSource(DataGridView dgv)
		{
			dgv.DataSource = new SortableBindingList<PatientWrapper>(PatientWrapper.ToList(GetPatient()));
		}

		/// <summary>
		/// Настраивает таблицу под вывод данных
		/// </summary>
		/// <param name="dgv"></param>
		internal void ConfigureSettingsDGV<T>(DataGridView dgv)
		{
			_general.SetDefaultSettingsToDGV(dgv);
			_general.ConfigureGrid<T>(dgv);
		}

		public List<Patient> GetPatient(int? id = null)
		{
			List<Patient> res = _general.Context.Patients
				.Include(x => x.HospitalAdmissions)
				.Include(x => x.Prescriptions)
				.Include(x => x.PatientNavigation)
				.ToList();

			if (id == null)
				return res;
			else
				return res
				.Where(item => item.PatientId == id)
				.ToList();
		}

		public List<Person> GetPerson(int? id = null)
		{
			List<Person> res = _general.Context.People
				.Include(x => x.Patient)
				.ToList();

			if (id == null)
				return res;
			else
				return res
				.Where(item => item.PersonId == id)
				.ToList();
		}

		public bool AddPatient(Patient patient)
		{
			try
			{
				_general.Context.Patients.Add(patient);
				_general.Context.SaveChanges();
				return true;
			}
			catch (DbUpdateException ex)
			{
				DeletePatient(patient);
				string message = "";
				if (ex.GetBaseException() is PostgresException pgException)
				{
					if (pgException.ConstraintName != null)
					{
						message = "Нарушено ограничение " + pgException.ConstraintName;
					}
					else
					{
						message = pgException.Message;
					}
				}

				MessageBox.Show(message, "Ошибка добавления",
						MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}

		public int AddPerson(Person person)
		{
			try
			{
				_general.Context.People.Add(person);
				_general.Context.SaveChanges();
				return _general.Context.People.OrderByDescending(x => x.PersonId).First().PersonId;
			}
			catch (DbUpdateException ex)
			{
				_general.Context.People.Remove(person);
				string message = "";
				if (ex.GetBaseException() is PostgresException pgException)
				{
					if (pgException.ConstraintName != null)
					{
						message = "Нарушено ограничение " + pgException.ConstraintName;
					}
					else
					{
						message = pgException.Message;
					}
				}

				MessageBox.Show(message, "Ошибка добавления",
						MessageBoxButtons.OK, MessageBoxIcon.Error);
				return -1;
			}
		}

		public void Update()
		{
			try
			{
				_general.Context.SaveChanges();
			}
			catch (DbUpdateException ex)
			{
				string message = "";
				if (ex.GetBaseException() is PostgresException pgException)
				{
					if (pgException.ConstraintName != null)
					{
						message = "Нарушено ограничение " + pgException.ConstraintName;
					}
					else
					{
						message = pgException.Message;
					}
				}

				MessageBox.Show(message, "Ошибка добавления",
						MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		public void DeletePatient(Patient p)
		{
			Person person = p.PatientNavigation;
			_general.Context.Patients.Remove(p);
			_general.Context.People.Remove(person);
			_general.Context.SaveChanges();
		}
	}
}
