using UnityEngine;

/// <summary>
/// CollectBagAction — Navigate to nearest unclaimed available/dropped cash box.
/// Prioritizes hot-drop boxes (bonus value) and closer boxes.
/// Respects TeamBlackboard claims to prevent clustering.
/// </summary>
public class CollectBagAction : AIAction
{
    public override string Name => "CollectBag";

    public override float Score(AIBlackboard bb, TeamBlackboard tb)
    {
        // Can't collect if dead or already full
        if (bb.isDead) return 0f;
        if (bb.carriedBagCount >= 3) return 0f;

        // No bags nearby
        int totalNearby = bb.nearbyAvailableBags.Count + bb.nearbyDroppedBags.Count;
        if (totalNearby == 0) return 0f;

        float score = 0.5f; // Base desire to collect

        // Bonus for hot-drop bags (time-sensitive)
        for (int i = 0; i < bb.nearbyDroppedBags.Count; i++)
        {
            if (bb.nearbyDroppedBags[i].IsHotDrop)
            {
                score += 0.2f;
                break;
            }
        }

        // Distance factor — closer bags = higher score
        float distanceFactor = InverseCurve(bb.nearestBagDistance, 25f);
        score *= (0.5f + distanceFactor * 0.5f);

        // Less desire to collect when already carrying (deposit instead)
        if (bb.carriedBagCount >= 2)
            score *= 0.3f;
        else if (bb.carriedBagCount >= 1)
            score *= 0.6f;

        // Reduce if nearby enemies (risky to collect)
        if (bb.nearbyEnemyCount > 0 && bb.nearestEnemyDistance < 8f)
            score *= 0.6f;

        // Low health = less collecting
        score *= (0.3f + bb.healthPercent * 0.7f);

        return Mathf.Clamp01(score);
    }

    public override void Execute(AIBrain brain, AIBlackboard bb, TeamBlackboard tb)
    {
        // Find best bag (prefer dropped hot-drops, then closest available)
        CashBag bestBag = null;
        float bestScore = float.MinValue;

        // Check dropped bags first (higher priority)
        for (int i = 0; i < bb.nearbyDroppedBags.Count; i++)
        {
            CashBag bag = bb.nearbyDroppedBags[i];
            if (bag == null || bag.IsCarried) continue;
            if (tb.IsBagClaimed(bag, brain)) continue;

            float dist = Vector3.Distance(brain.transform.position, bag.transform.position);
            float bagScore = bag.GetEffectiveValue() / Mathf.Max(dist, 1f);
            if (bag.IsHotDrop) bagScore *= 2f; // Big bonus for hot drops

            if (bagScore > bestScore) { bestScore = bagScore; bestBag = bag; }
        }

        // Then available bags
        if (bestBag == null)
        {
            for (int i = 0; i < bb.nearbyAvailableBags.Count; i++)
            {
                CashBag bag = bb.nearbyAvailableBags[i];
                if (bag == null || bag.IsCarried) continue;
                if (tb.IsBagClaimed(bag, brain)) continue;

                float dist = Vector3.Distance(brain.transform.position, bag.transform.position);
                float bagScore = bag.Value / Mathf.Max(dist, 1f);

                if (bagScore > bestScore) { bestScore = bagScore; bestBag = bag; }
            }
        }

        if (bestBag == null)
        {
            // No unclaimed bags, go idle
            return;
        }

        // Claim and navigate
        tb.TryClaimBag(bestBag, brain);
        bb.targetBag = bestBag;
        brain.NavigateTo(bestBag.transform.position);
    }

    public override void OnExit(AIBrain brain, AIBlackboard bb, TeamBlackboard tb)
    {
        tb.ReleaseBagClaim(brain);
        bb.targetBag = null;
    }
}
