﻿﻿﻿﻿using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;

using Wpf.Ui.Controls;

namespace CamBooth.App.Features.PictureGallery;

public class PictureGalleryService
{
	private readonly AppSettingsService _appSettings;

	private readonly Logger _logger;

	private readonly Dictionary<DateTime, BitmapImage> thumbnails = new();

	private int _newPhotoCount = 0;

	public event EventHandler<int>? NewPhotoCountChanged;


	public PictureGalleryService(AppSettingsService appSettings, Logger logger)
	{
		this._appSettings = appSettings;
		this._logger = logger;
	}


	public List<BitmapImage> ThumbnailsOrderedByNewestDescending =>
		this.thumbnails.OrderByDescending(map => map.Key)
			.Select(ordered => ordered.Value)
			.ToList();

	public int NewPhotoCount => _newPhotoCount;

	public void IncrementNewPhotoCount()
	{
		_newPhotoCount++;
		OnNewPhotoCountChanged(_newPhotoCount);
	}

	public void ResetNewPhotoCount()
	{
		_newPhotoCount = 0;
		OnNewPhotoCountChanged(_newPhotoCount);
	}

	private void OnNewPhotoCountChanged(int count)
	{
		NewPhotoCountChanged?.Invoke(this, count);
	}


	public async Task LoadThumbnailsToCache(int cacheSize = 0)
	{
		this._logger.Info("Start load thumbnails into cache");
		string? pictureLocation = this._appSettings.PictureLocation;
		int loop = 0;

		// Sicherstellen, dass das Verzeichnis existiert
		if (!Directory.Exists(pictureLocation))
		{
			this._logger.Info($"Picture directory does not exist: '{pictureLocation}'. Creating it...");
			try
			{
				Directory.CreateDirectory(pictureLocation);
				this._logger.Info($"Picture directory created: '{pictureLocation}'");
			}
			catch (Exception ex)
			{
				this._logger.Error($"Failed to create picture directory: {ex.Message}");
				return;
			}
		}

		// Filter nur Bilddateien
		string[] imageExtensions = { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
		List<string> picturePaths = Directory.EnumerateFiles(pictureLocation)
			.Where(f => imageExtensions.Contains(Path.GetExtension(f).ToLower()))
			.ToList();

		if (picturePaths.Count == 0)
		{
			this._logger.Info($"No pictures found in directory: '{pictureLocation}'");
			return;
		}

		await Task.Run(
			() =>
			{
				do
				{
					string picturePath = picturePaths[loop];

					DateTime creationTime = File.GetCreationTime(picturePath);

					// add if not exists
					if (!this.thumbnails.ContainsKey(creationTime))
					{
						try
						{
							this.thumbnails.Add(creationTime, PictureGalleryService.CreateThumbnail(picturePath, 244, 0));
							this._logger.Debug($"Thumbnail '{picturePath}' successfully created");
						}
						catch (Exception e)
						{
							this._logger.Error("thumbnail could not created: " + picturePath + " | " + e.Message);
						}
					}

					loop++;
				}
				while ((loop < cacheSize || cacheSize == 0) && loop < picturePaths.Count);
			});
		this._logger.Debug("Loading thumbnails into cache completed");
	}


	public static BitmapImage CreateThumbnail(string filePath, int maxWidth, int maxHeight)
	{
		BitmapImage? bitmap = new();
		bitmap.BeginInit();
		bitmap.UriSource = new Uri(filePath);
		bitmap.DecodePixelWidth = maxWidth; // Größe des ThumbnailsOrderedByNewestDescending direkt beim Dekodieren festlegen
		bitmap.DecodePixelHeight = maxHeight; // Größe des ThumbnailsOrderedByNewestDescending direkt beim Dekodieren festlegen
		bitmap.CacheOption = BitmapCacheOption.OnLoad;
		bitmap.EndInit();
		bitmap.Freeze(); // Threadsicher machen
		return bitmap;
	}
}