using Minesweeper.Core;
using Minesweeper.ECS;

namespace Minesweeper.Commands
{
    public sealed class SelectFieldCommandHandler : IGameCommandHandler<SelectFieldCommand>
    {
        private readonly IGameStateService gameStateService;

        public SelectFieldCommandHandler(IGameStateService gameStateService)
        {
            this.gameStateService = gameStateService;
        }

        public void Handle(SelectFieldCommand command)
        {
            gameStateService.SetState(GameState.FieldSelection);
        }
    }

    public sealed class StartGameCommandHandler : IGameCommandHandler<StartGameCommand>
    {
        private readonly IBoardEcsSyncService boardEcsSyncService;
        private readonly IBoardService boardService;
        private readonly IGameStateService gameStateService;

        public StartGameCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService)
        {
            this.boardService = boardService;
            this.boardEcsSyncService = boardEcsSyncService;
            this.gameStateService = gameStateService;
        }

        public void Handle(StartGameCommand command)
        {
            boardService.InitializeEmptyBoard();
            gameStateService.SetState(GameState.Preparing);
            boardEcsSyncService.SyncBoard(boardService);
            boardEcsSyncService.SyncGameState(gameStateService.Current, false);
        }
    }

    public sealed class OpenCellCommandHandler : IGameCommandHandler<OpenCellCommand>
    {
        private readonly IBoardEcsSyncService boardEcsSyncService;
        private readonly IBoardService boardService;
        private readonly IGameStateService gameStateService;

        public OpenCellCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService)
        {
            this.boardService = boardService;
            this.boardEcsSyncService = boardEcsSyncService;
            this.gameStateService = gameStateService;
        }

        public void Handle(OpenCellCommand command)
        {
            if (gameStateService.Current != GameState.Preparing)
            {
                return;
            }

            if (!boardService.GenerateAfterFirstClick(command.X, command.Y))
            {
                return;
            }

            gameStateService.SetState(GameState.Playing);
            boardEcsSyncService.SyncBoard(boardService);
            boardEcsSyncService.SyncGameState(gameStateService.Current, true);
        }
    }

    public sealed class ToggleFlagCommandHandler : IGameCommandHandler<ToggleFlagCommand>
    {
        public void Handle(ToggleFlagCommand command)
        {
        }
    }

    public sealed class RestartCommandHandler : IGameCommandHandler<RestartCommand>
    {
        private readonly IBoardEcsSyncService boardEcsSyncService;
        private readonly IBoardService boardService;
        private readonly IGameStateService gameStateService;

        public RestartCommandHandler(IBoardService boardService, IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService)
        {
            this.boardService = boardService;
            this.boardEcsSyncService = boardEcsSyncService;
            this.gameStateService = gameStateService;
        }

        public void Handle(RestartCommand command)
        {
            boardService.InitializeEmptyBoard();
            gameStateService.SetState(GameState.Preparing);
            boardEcsSyncService.SyncBoard(boardService);
            boardEcsSyncService.SyncGameState(gameStateService.Current, false);
        }
    }

    public sealed class PauseCommandHandler : IGameCommandHandler<PauseCommand>
    {
        public void Handle(PauseCommand command)
        {
        }
    }

    public sealed class ResumeCommandHandler : IGameCommandHandler<ResumeCommand>
    {
        public void Handle(ResumeCommand command)
        {
        }
    }

    public sealed class GoToMenuCommandHandler : IGameCommandHandler<GoToMenuCommand>
    {
        private readonly IBoardEcsSyncService boardEcsSyncService;
        private readonly IGameStateService gameStateService;

        public GoToMenuCommandHandler(IBoardEcsSyncService boardEcsSyncService, IGameStateService gameStateService)
        {
            this.boardEcsSyncService = boardEcsSyncService;
            this.gameStateService = gameStateService;
        }

        public void Handle(GoToMenuCommand command)
        {
            gameStateService.SetState(GameState.FieldSelection);
            boardEcsSyncService.SyncGameState(gameStateService.Current, false);
        }
    }
}
