using System;

namespace Minesweeper.Commands
{
    public sealed class GameCommandDispatcher : IGameCommandDispatcher
    {
        private readonly SelectFieldCommandHandler selectFieldHandler;
        private readonly StartGameCommandHandler startGameHandler;
        private readonly OpenCellCommandHandler openCellHandler;
        private readonly ToggleFlagCommandHandler toggleFlagHandler;
        private readonly RestartCommandHandler restartHandler;
        private readonly PauseCommandHandler pauseHandler;
        private readonly ResumeCommandHandler resumeHandler;
        private readonly GoToMenuCommandHandler goToMenuHandler;

        public GameCommandDispatcher(
            SelectFieldCommandHandler selectFieldHandler,
            StartGameCommandHandler startGameHandler,
            OpenCellCommandHandler openCellHandler,
            ToggleFlagCommandHandler toggleFlagHandler,
            RestartCommandHandler restartHandler,
            PauseCommandHandler pauseHandler,
            ResumeCommandHandler resumeHandler,
            GoToMenuCommandHandler goToMenuHandler)
        {
            this.selectFieldHandler = selectFieldHandler;
            this.startGameHandler = startGameHandler;
            this.openCellHandler = openCellHandler;
            this.toggleFlagHandler = toggleFlagHandler;
            this.restartHandler = restartHandler;
            this.pauseHandler = pauseHandler;
            this.resumeHandler = resumeHandler;
            this.goToMenuHandler = goToMenuHandler;
        }

        public void Dispatch<TCommand>(TCommand command) where TCommand : IGameCommand
        {
            switch (command)
            {
                case SelectFieldCommand selectFieldCommand:
                    selectFieldHandler.Handle(selectFieldCommand);
                    return;
                case StartGameCommand startGameCommand:
                    startGameHandler.Handle(startGameCommand);
                    return;
                case OpenCellCommand openCellCommand:
                    openCellHandler.Handle(openCellCommand);
                    return;
                case ToggleFlagCommand toggleFlagCommand:
                    toggleFlagHandler.Handle(toggleFlagCommand);
                    return;
                case RestartCommand restartCommand:
                    restartHandler.Handle(restartCommand);
                    return;
                case PauseCommand pauseCommand:
                    pauseHandler.Handle(pauseCommand);
                    return;
                case ResumeCommand resumeCommand:
                    resumeHandler.Handle(resumeCommand);
                    return;
                case GoToMenuCommand goToMenuCommand:
                    goToMenuHandler.Handle(goToMenuCommand);
                    return;
                default:
                    throw new InvalidOperationException($"No handler registered for command {typeof(TCommand).Name}.");
            }
        }
    }
}
