using System.Collections.Generic;
using UnityEngine;

namespace ServiceSim
{
    /// <summary>
    /// ロボットがいま引いている道を、床の上に細い線で出す（依頼 v9 の 6 章）。
    ///
    /// 色は仕事で変える:
    ///   料理を載せているとき（卓へ向かっている）… だいだい
    ///   空で戻るとき・待機 … 水色
    ///
    /// 見た目だけ。当たりも NavMesh も持たないので、
    /// ロボットのセンサー・人のよけ方・道探しには入らない。
    /// RobotSpec.showPathLine を外すと出さない（測る回でも出してよいが、切れるようにする）。
    ///
    /// 置き場所: ロボットの prefab には足さない。ロボットが自分で子として作る
    /// （材料も prefab も要らないようにして、シーンの組み立てを変えないため）。
    /// </summary>
    [RequireComponent(typeof(LineRenderer))]
    public class RobotPathLine : MonoBehaviour
    {
        /// <summary>この部品を置く子の名前</summary>
        public const string RootName = "PathLine";

        static readonly Color CarryColor = new Color(1f, 0.55f, 0.1f, 0.9f);   // 料理を載せている
        static readonly Color EmptyColor = new Color(0.25f, 0.75f, 1f, 0.9f);  // 空で戻る

        LineRenderer _line;
        readonly List<Vector3> _points = new List<Vector3>();

        /// <summary>
        /// ロボットの下に線を作る（無ければ）。材料はその場で作るので、
        /// prefab や .asset をいじらなくていい。URP でも読める shader を順に試す
        /// </summary>
        public static RobotPathLine Attach(Transform robot, float widthM)
        {
            if (robot == null) return null;
            Transform t = robot.Find(RootName);
            GameObject go;
            if (t != null) go = t.gameObject;
            else
            {
                go = new GameObject(RootName);
                go.transform.SetParent(robot, false);
            }

            if (go.GetComponent<LineRenderer>() == null) go.AddComponent<LineRenderer>();
            RobotPathLine p = go.GetComponent<RobotPathLine>();
            if (p == null) p = go.AddComponent<RobotPathLine>();
            p.Setup(widthM);
            return p;
        }

        void Setup(float widthM)
        {
            if (_line == null) _line = GetComponent<LineRenderer>();
            _line.useWorldSpace = true;          // 親が回っても線は曲がらない
            _line.alignment = LineAlignment.View;
            _line.textureMode = LineTextureMode.Stretch;
            _line.numCapVertices = 2;
            _line.numCornerVertices = 2;
            _line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
            _line.receiveShadows = false;
            _line.widthMultiplier = Mathf.Max(0.005f, widthM);
            _line.positionCount = 0;

            if (_line.sharedMaterial == null)
            {
                Shader s = Shader.Find("Universal Render Pipeline/Unlit");
                if (s == null) s = Shader.Find("Sprites/Default");
                if (s == null) s = Shader.Find("Unlit/Color");
                if (s != null)
                {
                    Material m = new Material(s);
                    m.name = "Mat_RobotPathLine";
                    _line.sharedMaterial = m;
                }
            }
        }

        /// <summary>
        /// 線を出し直す。points は道の曲がり角（世界の座標）。
        /// carrying は料理を載せているか。heightM は床から浮かせる高さ。
        /// </summary>
        public void Show(IReadOnlyList<Vector3> points, int fromIndex, Vector3 here,
                         bool carrying, float heightM)
        {
            if (_line == null) _line = GetComponent<LineRenderer>();

            _points.Clear();
            _points.Add(new Vector3(here.x, heightM, here.z));
            if (points != null)
                for (int i = Mathf.Max(0, fromIndex); i < points.Count; i++)
                    _points.Add(new Vector3(points[i].x, heightM, points[i].z));

            if (_points.Count < 2)
            {
                _line.positionCount = 0;
                return;
            }

            _line.positionCount = _points.Count;
            for (int i = 0; i < _points.Count; i++) _line.SetPosition(i, _points[i]);

            Color c = carrying ? CarryColor : EmptyColor;
            _line.startColor = c;
            _line.endColor = new Color(c.r, c.g, c.b, c.a * 0.35f);
            if (_line.sharedMaterial != null && _line.sharedMaterial.HasProperty("_BaseColor"))
                _line.sharedMaterial.SetColor("_BaseColor", c);
        }

        /// <summary>線を消す</summary>
        public void Hide()
        {
            if (_line == null) _line = GetComponent<LineRenderer>();
            _line.positionCount = 0;
        }
    }
}
