using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using LeafWeb.Core.Entities;

namespace LeafWeb.Core.DAL
{
	public class DataService : IDisposable
	{
		public static void RegisterInitializer()
		{
			Database.SetInitializer(new LeafWebInitializer());
			new LeafWebContext().Database.Initialize(true);
		}

		private readonly LeafWebContext _db = new LeafWebContext();

		public void Dispose()
		{
			_db.Dispose();
		}

		#region Fluxnet Sites

		public IQueryable<FluxnetSite> GetFluxnetSites()
		{
			return _db.FluxnetSites;
		}

		public IQueryable<FluxnetSite> GetFluxnetSitesAutocomplete(string term)
		{
			return 
				from fs in GetFluxnetSites()
				where fs.FluxnetId.StartsWith(term)
				|| fs.SiteName.Contains(term)
				select fs;
		}
		#endregion

		#region LeafInput

		public IQueryable<LeafInput> GetLeafInputs()
		{
			return _db.LeafInputs;
		}

		public LeafInput GetLeafInput(int id)
		{
			return _db.LeafInputs.FirstOrDefault(li => li.Id == id);
		}

		public void AddLeafInput(LeafInput leafInput)
		{
			leafInput.Added = DateTime.Now;
			_db.LeafInputs.Add(leafInput);
			foreach (var leafInputFile in leafInput.Files)
			{
				SetLeafInputFileStatusNoUpdate(leafInputFile, LeafInputStatusType.Queued);
			}
			_db.SaveChanges();
		}
		#endregion

		#region LeafInputFile

		public IQueryable<LeafInputFile> GetLeafInputFiles()
		{
			return _db.LeafInputFiles;
		}

		public IQueryable<LeafInputFile> GetLeafInputFiles(LeafInputStatusType status)
		{
			return
				from file in _db.LeafInputFiles
				where file.CurrentStatus == status
				select file;
		}

		public void UpdateLeafInputFile(LeafInputFile leafInputFile)
		{
			_db.Entry(leafInputFile).State = EntityState.Modified;
			_db.SaveChanges();
		}

		private void SetLeafInputFileStatusNoUpdate(LeafInputFile leafInputFile, LeafInputStatusType status, string description = null)
		{
			leafInputFile.CurrentStatus = status;
			var leafInputFileStatus = new LeafInputFileStatus
			{
				Status = status,
				DateTime = DateTime.Now,
				Description = description,
				LeafInputFile = leafInputFile
			};
			if (leafInputFile.StatusHistory == null)
				leafInputFile.StatusHistory = new List<LeafInputFileStatus>();
			leafInputFile.StatusHistory.Add(leafInputFileStatus);
		}

		public void SetLeafInputFileStatus(LeafInputFile leafInputFile, LeafInputStatusType status, string description = null)
		{
			SetLeafInputFileStatusNoUpdate(leafInputFile, status, description);
			UpdateLeafInputFile(leafInputFile);
		}

		#endregion

		#region Photosynthesis Types

		public IQueryable<PhotosynthesisType> GetPhotosynthesisTypes()
		{
			return _db.PhotosynthesisTypes.OrderBy(pt => pt.SortOrder);
		}

		public PhotosynthesisType GetPhotosynthesisType(string id)
		{
			return _db.PhotosynthesisTypes.Find(id);
		}

		#endregion

		#region LeafOutputFile

		public void AddLeafOutputFile(LeafOutputFile leafOutput)
		{
			_db.LeafOutputFiles.Add(leafOutput);
			_db.SaveChanges();
		}

		public IQueryable<LeafOutputFile> GetLeafOutputFiles()
		{
			return _db.LeafOutputFiles;
		}

		public LeafOutputFile GetLeafOutputFile(int id)
		{
			return _db.LeafOutputFiles.Find(id);
		}

		#endregion
	}
}
