@using ImageBoardServerApp.Auth
@using ImageBoardServerApp.Data.Repository
@using ImageBoardServerApp.Util
@using System.Text.RegularExpressions
@using System.ComponentModel.DataAnnotations
@inject AuthenticationStateProvider authStateProvider
<div class="comment">
    <div class="threadHeader">
    <span>[</span>
    <a class="toggleOpened" onclick="@ToggleOpened">@toggleText</a>
    <span>]</span>
    <span class="name">@comment.Username</span>
    @if (@role != "User")
    {
        <span class="@role" >##@role</span>
    }
    <span class="date">@getTimeFromUnix(comment.CreatedAt)</span>
    <span class="post-id">No.@comment.GET</span>
</div>
@if (opened) 
{
    <div class="threadContent">
        @if (image != null)
        {
            string isActiveClass = isActive ? "active" : "";
            <div class="threadImage">
                    <img @onclick="() => isActive = !isActive" class="@isActiveClass" src="@($"{@image.ImageLocation}?size=258x258")" alt="No Image found" />
            </div>
        }
        <div class="threadTextContainer">
            @for (var y = 0; y < comment.Content.Split("\n").Length; y++)
            {
                var s = comment.Content.Split("\n")[y];
                var className = "";

                @if (s.StartsWith(">") && !Regex.IsMatch(s, "^>{2,}"))
                {
                    className = "greenText";
                }
                <span class='threadText @className'>
                    @for (var x = 0; x < s.Split(" ").Length; x++)
                    { 
                        var line = s.Split(" ")[x];
                        @if (@Regex.IsMatch(line, ">>\\d+"))
                        {
                            var className2 = "";
                            var x1 = x;
                            var y1 = y;
                            var commentNumber = int.Parse(Regex.Match(s, ">>(\\d+)").Value.Substring(2));
                            className2 = "redText";
                            <span
                                @onmouseenter="() => onHover(x1, y1, commentNumber)"
                                @onmouseleave="() => onHover(x1, y1, -1)" class="threadMsg @className2"
                            >
                                @line
                            </span>
                            @if (hoveringOver.p != -1 && hoveringOver == (x, y, commentNumber) && (hoverComment.ContainsKey(commentNumber) || hoverPost.ContainsKey(commentNumber)))
                            {
                                @if (isComment[commentNumber])
                                {
                                    <div>
                                        <CommentHover comment="hoverComment[commentNumber]"/>
                                    </div>
                                }
                                else
                                {
                                    <div>
                                        <Post post="hoverPost[commentNumber]" showOpenThread="false"/>
                                    </div>
                                }
                            }
                        }
                        else
                        {
                            <span class="threadMsg">
                                @line
                            </span>
                        }
                        <span>&nbsp;</span>

                    }
                </span>
            }
        </div>
    </div>
    <div class="threadFooter">
        <span>[</span>
        <a class="repButton" href="@reportURL" target="_blank">Report</a>
        @if (canDel)
        {
            <button class="delButton" onclick="@deletePost">Delete</button>
        }
        <span>]</span>
    </div>
}
</div>



@code {
    private string reportURL { get; set; }
    
    private bool isActive { get; set; } = false;

    private (int x, int y, int p) hoveringOver { get; set; } = (-1, -1, -1);
    private Dictionary<int, bool> isComment{ get; set; }
    private Dictionary<int, CommentData> hoverComment { get; set; }
    private Dictionary<int, PostData> hoverPost { get; set; }
    private Dictionary<int, int> nrToGet { get; set; }

    private void onHover(int x, int y, int p)
    {
        if (hoverComment.ContainsKey(p) || hoverPost.ContainsKey(p))
        {
            hoveringOver= (x, y, -1);
        }
        hoveringOver = (x, y, p);
    }

    public bool canDel { get; set; }
    
    private async Task deletePost()
    {
        var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider;
        var user = await cauthStateProvder.GetAuthenticationStateAsync();
        var usr = user.User;
        UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
        if (foundusr.Role != "User" || comment.UserID == foundusr.UserID)
        {
            await TheManager.deleteComment(comment);
        }
    }
    
    
    private static DateTime getTimeFromUnix(double javaTimeStamp)
    {
        var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
        dateTime = dateTime.AddMilliseconds( javaTimeStamp ).ToLocalTime();
        return dateTime;
    }

    private ImageData image;
    private string role;

    protected override async Task OnParametersSetAsync()
    {
        await base.OnParametersSetAsync();
        var cauthStateProvder = (CustomAuthenticationStateProvider)authStateProvider;
        var user = await cauthStateProvder.GetAuthenticationStateAsync();
        var usr = user.User;
        UserData foundusr = await UsersRepository.getUserByEmailAsync(usr.Identity.Name);
        if (foundusr != null && (foundusr.Role != "User" || comment.UserID == foundusr.UserID))
        {
            canDel = true;
        }
        else
        {
            canDel = false;
        }

        
        hoverComment = new Dictionary<int, CommentData>();
        hoverPost = new Dictionary<int, PostData>();
        nrToGet = new Dictionary<int, int>();
        isComment = new Dictionary<int, bool>();

        foreach (string s in comment.Content.Split("\n"))
        {
            @foreach (string line in s.Split(" "))
            {
                @if (Regex.IsMatch(line, ">>\\d+"))
                {
                    var commentNumber = int.Parse(Regex.Match(s, ">>(\\d+)").Value.Substring(2));
                    string board = comment.Board;
                    if (await TheManager.isGETComment(board, commentNumber))
                    {
                        CommentData c = await CommentsRepository.getCommentByGETAsync(board, commentNumber);
                        if (c == null)
                            continue;
                        hoverComment[commentNumber] = c;
                        nrToGet[commentNumber] = c.GET;
                        isComment[commentNumber] = true;
                    }
                    else
                    {
                        PostData p = await PostsRepository.getPostByGETAsync(board, commentNumber);
                        if (p == null)
                            continue;
                        hoverPost[commentNumber] = p;
                        nrToGet[commentNumber] = p.GET;
                        isComment[commentNumber] = false;
                    }
                }
            }
        }
        reportURL = $"/sys/report/comment/{comment.Board}/{comment.CommentID}";
    }

    protected override async Task OnInitializedAsync()
    {
        int i;
        try
        {
            i = (int)comment.ImageID;
        }
        catch (InvalidOperationException ioe)
        {
            i = -1;
        }
        if (i != null)
        {
            image = await ImagesRepository.getImageByIdAsync(i);
        }

        var cmt = await CommentsRepository.getCommentByIdAsync(comment.CommentID);
        role = cmt.User.Role;
    }
    
    private bool opened = true;

    private string toggleText = "-";

    private void ToggleOpened()
    {
        opened = !opened;
        toggleText = opened ? "-" : "+";
    }

    private string toggleText2 = "-";
    private bool showHover = false;
    private void ToggleHovered(MouseEventArgs e, string id)
    {
        showHover = !showHover;
        toggleText2 = showHover ? "-" : "+";
    }

    [Parameter]
    [Required]
    public CommentData comment { get; set; }
}