using System;
using NeonScripting;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;

public class Script
{
    public bool Run(INeonScriptHost host)
    {
        var pictureFolder = host.RemoteCalls.SelectFolder("Select folder where album pictures are stored. Click cancel if you only want to scan album folders.");
        var pictureFiles = new List<string>();
        if (!string.IsNullOrEmpty(pictureFolder))
        {
            foreach (var filename in Directory.GetFiles(pictureFolder, "*.*", SearchOption.AllDirectories))
            {
                var ext = Path.GetExtension(filename)?.ToLowerInvariant();
                if (ext == ".jpg" || ext == ".jpeg" || ext == ".png")
                {
                    pictureFiles.Add(filename);
                }
            }
        }

        var idx = 1;
        var albums = host.Database.Albums;
        var foundPictures = 0;
        var neonScriptAlbums = albums.ToList();
        foreach (var album in neonScriptAlbums)
        {
            host.UpdateProgress($"Album {idx} of {neonScriptAlbums.Count()} ({foundPictures} pictures found so far)");

            var albumName = $"{album.AlbumArtist} - {album.AggregatedAlbumName}";
            var regex = $"[{Regex.Escape(new string(Path.GetInvalidFileNameChars()))}]";
            var removeInvalidChars = new Regex(regex, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant);
            albumName = removeInvalidChars.Replace(albumName, "_");

            var searchResult = pictureFiles.FirstOrDefault(x =>
            {
                var pathWithoutExtension = Path.GetFileNameWithoutExtension(x);
                return pathWithoutExtension != null && pathWithoutExtension.Equals(albumName, StringComparison.InvariantCultureIgnoreCase);
            });
            var foundPic = searchResult ?? "";

            if (string.IsNullOrEmpty(foundPic))
            {
                var pictures = new List<string>();
                if (Directory.Exists(album.AlbumPath))
                {
                    foreach (var filename in Directory.GetFiles(album.AlbumPath, "*.*", SearchOption.AllDirectories))
                    {
                        var ext = Path.GetExtension(filename)?.ToLowerInvariant();
                        if (ext == ".jpg" || ext == ".jpeg" || ext == ".png")
                        {
                            pictures.Add(filename);
                        }
                    }
                }
                if (pictures.Any())
                {
                    var picturesWithoutExtensions = pictures.Select(Path.GetFileNameWithoutExtension).ToList();
                    if(picturesWithoutExtensions.Exists(match => match.Equals(albumName, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        foundPic = picturesWithoutExtensions.First(match => match.Equals(albumName, StringComparison.InvariantCultureIgnoreCase));
                    }
                    if (picturesWithoutExtensions.Exists(match => match.Equals("Folder", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        foundPic = picturesWithoutExtensions.First(match => match.Equals("Folder", StringComparison.InvariantCultureIgnoreCase));
                    }
                    if (picturesWithoutExtensions.Exists(match => match.Equals("Cover", StringComparison.InvariantCultureIgnoreCase)))
                    {
                        foundPic = picturesWithoutExtensions.First(match => match.Equals("Cover", StringComparison.InvariantCultureIgnoreCase));
                    }
                    else
                    {
                        foundPic = pictures.First();
                    }
                }
            }

            if (!string.IsNullOrEmpty(foundPic))
            {
                foundPictures++;
                host.Database.UpdateAlbumPicture(album, foundPic);
            }
            idx++;
        }

        return true;
    }
}
