using System.Security.Cryptography;
using ImageBoardServerApp.Data;
using ImageBoardServerApp.Data.Repository;

namespace ImageBoardServerApp.Util;

public class TheManager
{
    public static string version = "v1.0.0-rc3";

    private static long getDiff(PostData post)
    {
        return (DateTimeOffset.Now.ToUnixTimeMilliseconds() - post.CreatedAt);
    }

    /// <summary>
    /// Returns the value without a minus, if it exists
    /// </summary>
    /// <param name="num"></param>
    /// <returns></returns>
    private static long getValue(long num)
    {
        return num < 0 ? num * -1 : num;
    }

    public static long getBumpValue(PostData post)
    {
        return (post.IsSticky
            ? 999999999999999999 + getDiff(post)
            : 10 * 60000 - getDiff(post) + (60000 * (post.Comments.Count + 1)));
    }

    public static async Task<List<PostData>> getPostList(string boardTag)
    {
        List<PostData> threads = await PostsRepository.getPostsByBoardAsync(boardTag);
        return threads.OrderBy(getBumpValue).Reverse().ToList();
    }

    public static async Task bumpThreads(BoardData board)
    {
        Console.WriteLine("Bumping..");
        List<PostData> sortedThreads = await getPostList(board.Tag);
        if (sortedThreads.Count > board.maxThreads + 1)
        {
            Console.WriteLine("Pruning..");
            foreach (var pd in sortedThreads.TakeLast(sortedThreads.Count() - board.maxThreads))
            {
                if (pd.IsSticky)
                    continue;
                Console.WriteLine($"Removing Post{pd.PostID}");
                await deleteThread(pd);
            }
        }
    }

    public static async Task deleteThread(PostData post)
    {
        foreach (var c in post.Comments)
        {
            if (c.Image != null)
            {
                await deleteImage(c.Image);
            }
        }

        await deleteImage(post.Image);

        await PostsRepository.deletePostAsync(post.PostID);
    }

    public static async Task deleteComment(CommentData comment)
    {
        if (comment.Image != null)
        {
            await deleteImage(comment.Image);
        }

        await CommentsRepository.deleteCommentAsync(comment.CommentID);
    }

    public static async Task deleteImage(ImageData imageData)
    {
        string path = $"./wwwroot{imageData.ImageLocation}";
        Console.WriteLine(path);
        try
        {
            File.Delete(path);
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("The file was not found.");
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
    }

    public static async Task<bool> isGETComment(string board, int GET)
    {
        return await CommentsRepository.getCommentByGETAsync(board, GET) != null;
    }

    public static string getmd5Hash()
    {
        var bytes = new byte[16];
        using (var rng = new RNGCryptoServiceProvider())
        {
            rng.GetBytes(bytes);
        }

        return BitConverter.ToString(bytes).Replace("-", "").ToLower();
    }

    public static DateTime ConvertToDateTime(long timestamp)
    {
        DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        dateTime = dateTime.AddMilliseconds(timestamp).ToLocalTime();
        return dateTime;
    }
}