using Dapper;
using Newtonsoft.Json.Linq;
using Yuna.Website.Server.Model;

namespace Yuna.Website.Server.Storage.Repositories.User
{
    public class UserRepository : IUserRepository
    {
        private readonly DapperContext _context;

        public UserRepository(DapperContext context)
        {
            _context = context;
        }
        public async Task<Model.User?> Create(Model.User? user)
        {
            var query =
               $@"INSERT INTO ""Yuna_Users""
                (""Username"", ""HashedPassword"", ""IsAdmin"")
                VALUES
                (@{nameof(Model.User.UserName)}, @{nameof(Model.User.HashedPassword)}, @{nameof(Model.User.IsAdmin)})
                RETURNING *
            ";

            var result = await _context.Connection.QuerySingleAsync<Model.User?>(query, user);
            return result;
        }

        public Task<Model.User?> Delete(long id)
        {
            throw new NotImplementedException();
        }

        public async Task<Model.User?> GetById(long id)
        {
            var query =
                $@"SELECT 
                    u.""Id"" as {nameof(Model.User.Id)}, 
                    u.""Username"" as {nameof(Model.User.UserName)}, 
                    u.""HashedPassword"" as {nameof(Model.User.HashedPassword)},
                    u.""IsAdmin"" as {nameof(Model.User.IsAdmin)}
                    FROM ""Yuna_Users"" u
                    WHERE u.""Id"" = {id}
                    LIMIT 1";

            var result = await _context.Connection.QuerySingleAsync<Model.User>(query);
            return result;
        }

        public async Task<Model.User?> GetByUsername(string username)
        {
            var query =
               $@"SELECT 
                    u.""Id"" as {nameof(Model.User.Id)}, 
                    u.""Username"" as {nameof(Model.User.UserName)}, 
                    u.""HashedPassword"" as {nameof(Model.User.HashedPassword)},
                    u.""IsAdmin"" as {nameof(Model.User.IsAdmin)}
                    FROM ""Yuna_Users"" u
                    WHERE LOWER(u.""Username"") = '{username.ToLower()}'
                    LIMIT 1";

            var result = await _context.Connection.QuerySingleOrDefaultAsync<Model.User>(query);
            return result;
        }

        public async Task<IReadOnlyList<Model.User>> GetList()
        {
            var query = 
            $@"SELECT 
                    u.""Id"" as {nameof(Model.User.Id)}, 
                    u.""Username"" as {nameof(Model.User.UserName)}, 
                    u.""HashedPassword"" as {nameof(Model.User.HashedPassword)},
                    u.""IsAdmin"" as {nameof(Model.User.IsAdmin)}
                    FROM ""Yuna_Users"" u";

            var result = await _context.Connection.QueryAsync<Model.User>(query);
            return result.ToList();
        }

        public async Task<Model.User?> Update(Model.User? user)
        {
            var query = $@"
                        UPDATE ""Yuna_Users""
                        SET 
                        ""Username"" = @{nameof(Model.User.UserName)},
                        ""HashedPassword"" = @{nameof(Model.User.HashedPassword)},
                        ""IsAdmin"" = {nameof(Model.User.IsAdmin)}
                        ""WHERE Id"" = @{nameof(Model.User.Id)}
                        RETURNING *
                        ";

            var result = await _context.Connection.QuerySingleOrDefaultAsync<Model.User>(query, user);
            return result;
        }
    }
}