using DbController;
using Tabletop.Core.Models;

namespace Tabletop.Core.Services
{
    public class LayoutService : IModelService<Layout, int>
    {
        public async Task CreateAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
        {
            string sql = $@"INSERT INTO Layouts
                (
                GamemodeId,
                Teams,
                Width,
                Height
                )
                VALUES
                (
                @GAMEMODE_ID
                @TEAMS,
                @WIDTH,
                @HEIGHT
                ); {dbController.GetLastIdSql()}";

            input.LayoutId = await dbController.GetFirstAsync<int>(sql, input.GetParameters(), cancellationToken);
        }

        public async Task DeleteAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
        {
            string sql = "DELETE FROM Layouts WHERE LayoutId = @LAYOUT_ID";

            await dbController.QueryAsync(sql, new
            {
                LAYOUT_ID = input.LayoutId
            }, cancellationToken);
        }

        public static async Task<List<SetupZone>> GetSetupZonesAsync(int layoutId, IDbController dbController, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            string sql = @"
                SELECT sz.SetupZoneId, sz.LayoutId, z.*
                FROM SetupZones sz
                INNER JOIN Zones z ON (z.ZoneId = sz.ZoneId)
                WHERE sz.LayoutId = @LAYOUT_ID";

            var list = await dbController.SelectDataAsync<SetupZone>(sql, new
            {
                LAYOUT_ID = layoutId
            }, cancellationToken);

            return list;
        }

        public static async Task<List<CaptureZone>> GetCaptureZonesAsync(int layoutId, IDbController dbController, CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();
            string sql = @"
                SELECT cz.CaptureZoneId, cz.LayoutId, z.*
                FROM CaptureZones cz
                INNER JOIN Zones z ON (z.ZoneId = cz.ZoneId)
                WHERE cz.LayoutId = @LAYOUT_ID";

            var list = await dbController.SelectDataAsync<CaptureZone>(sql, new
            {
                LAYOUT_ID = layoutId
            }, cancellationToken);

            return list;
        }

        public static async Task<List<Layout>> GetAllAsync(IDbController dbController, CancellationToken cancellationToken = default)
        {
            string sql = "SELECT * FROM Layouts";

            var list = await dbController.SelectDataAsync<Layout>(sql, cancellationToken: cancellationToken);

            foreach(var layout in list)
            {
                layout.SetupZones = await GetSetupZonesAsync(layout.LayoutId, dbController, cancellationToken);
                layout.CaptureZones = await GetCaptureZonesAsync(layout.LayoutId, dbController, cancellationToken);
            }

            return list;
        }

        public Task<Layout?> GetAsync(int battlegroundId, IDbController dbController, CancellationToken cancellationToken = default)
        {
            throw new NotImplementedException();
        }

        public Task UpdateAsync(Layout input, IDbController dbController, CancellationToken cancellationToken = default)
        {
            throw new NotImplementedException();
        }
    }
}
