// Assets/Scripts/Services/Interfaces/IBombService.cs
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Enums;
using Models.Interfaces;
using UnityEngine;

namespace Services.Interfaces
{
    public interface IBombService {
        /// <summary>
        /// Caches last swap action.
        /// </summary>
        /// <param name="from">
        /// Original location of the gem.
        /// </param>
        /// <param name="to">
        /// Destination location of the gem.
        /// </param>
        void SetLastSwap(Vector2Int from, Vector2Int to);

        /// <summary>
        /// Try to spawn a bomb at the last swap location.
        /// </summary>
        /// <param name="currentMatches">
        /// List of current matches.
        /// </param>
        void DetectBombSpawnFromLastSwap(HashSet<Gem> currentMatches);
        List<Vector2Int> ApplyPendingBombSpawns(Action<Vector2Int, GemType, bool> spawnGem);
        
        /// <summary>
        /// Get a List of bombs that we will detonate.
        /// </summary>
        /// <param name="protectedPositions">
        /// Protected positions, bombs that we don't want to destroy.
        /// </param>
        /// <param name="bombCandidates">
        /// Possible bombs.
        /// </param>
        /// <returns>
        /// List of Bombs.
        /// </returns>
        UniTask<List<Vector2Int>> GetInitialBombs(List<Vector2Int> protectedPositions, HashSet<Vector2Int> bombCandidates);
        
        /// <summary>
        /// Detonate the bomb(s) part of the match. If there are other bombs within the radius, they will be detonated too sequentially.
        /// </summary>
        /// <param name="initialBombs">
        /// List of bombs to detonate.
        /// </param>
        /// <param name="destroyAtAsync">
        /// Destroy function reference.
        /// </param>
        UniTask DetonateChainAsync(
            IReadOnlyList<Vector2Int> initialBombs,
            Func<Vector2Int, UniTask> destroyAtAsync);
    }
}