// Assets/_Project/Scripts/Gameplay/TowerPlacementSettings.cs
using UnityEngine;

namespace TD.Gameplay
{
    /// <summary>
    /// Project-wide settings for the tower placement system. One asset shared across all
    /// tower types — assign it to <see cref="TowerPlacementController"/> in the scene.
    /// </summary>
    /// <remarks>
    /// <para><b>Why not on TowerDefinition?</b> Ghost materials and rejection messages are
    /// identical for every tower type. Putting them on TowerDefinition would mean 100+
    /// assets each holding two redundant material references that must be kept in sync.
    /// A single shared settings asset is easier to maintain and impossible to accidentally
    /// de-sync.</para>
    ///
    /// <para><b>Rejection messages.</b> These are the strings shown on screen when the
    /// server rejects a placement. Kept here so designers can tune the wording without
    /// touching code.</para>
    ///
    /// <para><b>Note on build-site visuals.</b> The green queued-ghost material and the
    /// constructing-stage material live on the <c>BuildSiteVisual</c> prefab, not here.
    /// Those materials are prefab-local (the build-site visual prefab references them
    /// directly), so promoting them to a shared settings asset would just add an
    /// indirection without simplifying anything.</para>
    /// </remarks>
    [CreateAssetMenu(fileName = "TowerPlacementSettings",
                     menuName = "TD/Tower Placement Settings",
                     order = 3)]
    public class TowerPlacementSettings : ScriptableObject
    {
        // ----- Cursor ghost visuals ---------------------------------------

        [Header("Cursor Ghost Materials")]
        [Tooltip("Material applied to the cursor placement ghost when placement is valid. " +
                 "Should be a transparent/unlit white material so the tower mesh is " +
                 "recognizable but clearly distinct from a placed tower.")]
        public Material GhostValidMaterial;

        [Tooltip("Material applied to the cursor placement ghost when placement is invalid. " +
                 "Should be a transparent/unlit red material.")]
        public Material GhostInvalidMaterial;

        // ----- Rejection messages -----------------------------------------

        [Header("Rejection Messages")]
        [Tooltip("Shown when the server rejects a placement because tiles belong to " +
                 "another player's zone.")]
        public string MessageWrongOwner = "You can only place towers in your own zone.";

        [Tooltip("Shown when the server rejects because one or more tiles are " +
                 "Restricted or Outside the map.")]
        public string MessageTileNotBuildable = "That location is not buildable.";

        [Tooltip("Shown when the server rejects because a tile is already occupied " +
                 "by an existing tower or by a queued/constructing build job.")]
        public string MessageTileOccupied = "A tower is already there or queued there.";

        [Tooltip("Shown when the server rejects because the player cannot afford " +
                 "the tower.")]
        public string MessageInsufficientGold = "Not enough gold.";

        [Tooltip("Shown when the server rejects because the builder is too far away " +
                 "from the requested location.")]
        public string MessageOutOfRange = "Your builder is too far away.";

        [Tooltip("Shown when the server rejects because placing the tower would block " +
                 "all valid paths through the player's zone.")]
        public string MessageBlocksPath = "That placement would block the path.";

        [Tooltip("Shown when the server rejects because the builder's queue is full. " +
                 "Player must cancel pending jobs or wait for one to complete.")]
        public string MessageJobLimitReached = "Builder queue is full.";

        [Tooltip("Shown when the player tries to place a tower they haven't unlocked in " +
                 "their deck yet. Draft it first.")]
        public string MessageTowerNotInDeck = "You haven't unlocked that tower yet.";

        [Tooltip("Shown for unexpected server-side errors (invalid tower type, etc.). " +
                 "Should rarely appear in normal play.")]
        public string MessageServerError = "Placement failed. Please try again.";

        // ----- Helpers -----------------------------------------------------

        /// <summary>
        /// Returns the human-readable rejection message for the given reason.
        /// </summary>
        public string GetRejectionMessage(PlacementRejectionReason reason)
        {
            switch (reason)
            {
                case PlacementRejectionReason.WrongOwner: return MessageWrongOwner;
                case PlacementRejectionReason.TileNotBuildable: return MessageTileNotBuildable;
                case PlacementRejectionReason.TileOccupied: return MessageTileOccupied;
                case PlacementRejectionReason.InsufficientGold: return MessageInsufficientGold;
                case PlacementRejectionReason.OutOfRange: return MessageOutOfRange;
                case PlacementRejectionReason.BlocksPath: return MessageBlocksPath;
                case PlacementRejectionReason.JobLimitReached: return MessageJobLimitReached;
                case PlacementRejectionReason.TowerNotInDeck: return MessageTowerNotInDeck;
                case PlacementRejectionReason.InvalidTowerType:
                case PlacementRejectionReason.ServerError:
                default: return MessageServerError;
            }
        }
    }
}