using ExtensiblePortfolioSite.SDK.Git;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace GithubPlugin
{
    public class GithubRepo : IRepository
    {
        [JsonPropertyName("name")]
        public string Name { get; private set; }

        [JsonPropertyName("description")]
        public string Description { get; private set; }

        [JsonIgnore]
        public IUser Owner { get; internal set; }

        [JsonIgnore]
        public IGitProvider Provider { get; internal set; }

        public ICommit? GetCommit(uint HeadOffset = 0)
        {
            var response = Provider.GetAPIResource($"repos/{Owner.Name}/{Name}/commits");
            if(response.IsSuccessStatusCode)
            {
                JsonDocument json = JsonDocument.Parse(response.Content.ReadAsStream());
                JsonElement commitObject = json.RootElement.EnumerateArray().Skip((int)HeadOffset).First();
                GithubCommit commit = JsonSerializer.Deserialize<GithubCommit>(commitObject.GetProperty("commit"))!;
                commit.Provider = Provider;
                commit.Repository = this;
                List<string> tempFiles = new List<string>();
                JsonElement files = commitObject.GetProperty("files");
                foreach(JsonElement file in files.EnumerateArray())
                {
                    tempFiles.Add(file.GetProperty("filename").GetString()!);
                }
                commit.ModifiedFiles = tempFiles;
                return commit;
            } else
            {
                return null;
            }
        }

        public ICommit? GetCommitByRef(string reference)
        {
            var response = Provider.GetAPIResource($"repos/{Owner.Name}/{Name}/commits/{reference}");
            if (response.IsSuccessStatusCode)
            {
                JsonDocument json = JsonDocument.Parse(response.Content.ReadAsStream());
                JsonElement commitObject = json.RootElement;
                GithubCommit commit = JsonSerializer.Deserialize<GithubCommit>(commitObject.GetProperty("commit"))!;
                commit.Provider = Provider;
                commit.Repository = this;
                List<string> tempFiles = new List<string>();
                JsonElement files = commitObject.GetProperty("files");
                foreach (JsonElement file in files.EnumerateArray())
                {
                    tempFiles.Add(file.GetProperty("filename").GetString()!);
                }
                commit.ModifiedFiles = tempFiles;
                return commit;
            }
            else
            {
                return null;
            }
        }

        public GitReference GetReference()
        {
            return new GitReference(GitReferenceKind.Repository, $"{Owner}/{Name}");
        }

        public bool TryGetCommit(uint HeadOffset, out ICommit? Commit)
        {
            var commit = GetCommit(HeadOffset);
            if (commit != null)
            {
                Commit = commit;
                return true;
            }

            Commit = null;
            return false;
        }

        public bool TryGetCommitByRef(string Reference, out ICommit? Commit)
        {
            var commit = GetCommitByRef(Reference);
            if (commit != null)
            {
                Commit = commit;
                return true;
            }

            Commit = null;
            return false;
        }
    }
}
