using Dapper;

namespace Yuna.Website.Server.Storage.Repositories.Prop
{
    public class PropRepository : IPropRepository
    {
        private readonly DapperContext _context;

        public PropRepository(DapperContext context)
        {
            _context = context;
        }

        public async Task<Model.Prop?> Create(Model.Prop value)
        {
            var query =
                $@"INSERT INTO ""Yuna_Props""
                (""Name"", ""MeasureName"", ""JsonValueName"", ""Type"" )
                VALUES
                (
                @{nameof(Model.Prop.Name)},
                @{nameof(Model.Prop.MeasureName)},
                @{nameof(Model.Prop.JsonValueName)},
                @{nameof(Model.Prop.Type)})
                RETURNING *";

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

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

        public async Task<Model.Prop?> GetById(long id)
        {
            var query =
                $@"SELECT 
                    p.""Id"" as {nameof(Model.Prop.Id)}, 
                    p.""Name"" as {nameof(Model.Prop.Name)}, 
                    p.""MeasureName"" as {nameof(Model.Prop.MeasureName)},
                    p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)},
                    p.""Type"" as {nameof(Model.Prop.Type)}
                    FROM ""Yuna_Props"" p
                    WHERE p.""Id"" = {id}
                    LIMIT 1";

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

        public async Task<IReadOnlyList<Model.Prop>?> GetByIds(long[] ids)
        {
            var idList = string.Join(", ", ids);
            var query =
                $@"SELECT 
                    p.""Id"" as {nameof(Model.Prop.Id)}, 
                    p.""Name"" as {nameof(Model.Prop.Name)}, 
                    p.""MeasureName"" as {nameof(Model.Prop.MeasureName)},
                    p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)},
                    p.""Type"" as {nameof(Model.Prop.Type)}
                    FROM ""Yuna_Props"" p
                    WHERE p.""Id"" IN ({idList})";

            var result = await _context.Connection.QueryAsync<Model.Prop>(query);
            if (result.Count() != ids.Length) return null;
            return result.ToList();
        }

        public async Task<Model.Prop?> GetByPropName(string value)
        {
            var query =
                $@"SELECT 
                    p.""Id"" as {nameof(Model.Prop.Id)}, 
                    p.""Name"" as {nameof(Model.Prop.Name)}, 
                    p.""MeasureName"" as {nameof(Model.Prop.MeasureName)},
                    p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)},
                    p.""Type"" as {nameof(Model.Prop.Type)}
                    FROM ""Yuna_Props"" p
                    WHERE LOWER(p.""Name"") = '{value.ToLower()}'
                    LIMIT 1";

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

        public async Task<IReadOnlyList<Model.Prop>> GetList()
        {
            var query =
                $@"SELECT 
                    p.""Id"" as {nameof(Model.Prop.Id)}, 
                    p.""Name"" as {nameof(Model.Prop.Name)}, 
                    p.""MeasureName"" as {nameof(Model.Prop.MeasureName)},
                    p.""JsonValueName"" as {nameof(Model.Prop.JsonValueName)},
                    p.""Type"" as {nameof(Model.Prop.Type)}
                    FROM ""Yuna_Props"" p";

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