using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;

public class RectangleMeasureGroup : MeasureGroup
{
    private PolygonMeasureGroupInfoPopup polygonMeasureGroupInfoPopup;

    public override void AddPoint(Vector3 pos)
    {
        if(points.Count >= 3) 
            return;

        points.Add(pos);

        switch (points.Count)
        {
            case 1:
                AddFirstPoint(pos);
                break;
            case 2:
                AddSecondPoint(pos);
                break;
            case 3:
                AddThirdPoint(pos);
                break;  
        }
    }

    private void AddFirstPoint(Vector3 pos)
    {
        if (!polygonMeasureGroupInfoPopup)
        {
            polygonMeasureGroupInfoPopup = Instantiate(polygonInfoPopupPrefab).GetComponent<PolygonMeasureGroupInfoPopup>();
            polygonMeasureGroupInfoPopup.InitUI(infoPopupRoot);
            polygonMeasureGroupInfoPopup.transform.position = pos + new Vector3(20, 0, 20);
        }

        GameObject label = Instantiate(labelPrefab, pos, Quaternion.identity, labelRoot);
        labels.Add(label);
    }

    private void AddSecondPoint(Vector3 pos)
    {
        while (labels.Count < 4)
        {
            GameObject label = Instantiate(labelPrefab, pos, Quaternion.identity, labelRoot);
            labels.Add(label);
        }
    }

    private void AddThirdPoint(Vector3 pos)
    {
        deleteButton = Instantiate(deleteButtonPrefab, points[0], Quaternion.identity, infoPopupRoot);
        deleteButton.GetComponentInChildren<Button>().onClick.AddListener(() => DestroyAll());
        deleteButton.transform.position = points[0] + new Vector3(-20, 0, 20);

        FindAnyObjectByType<MeasureManager>().isMeasuring = false;
    }

    public override void EndMeasure()
    {
        DestroyAll();
        FindAnyObjectByType<MeasureManager>().isMeasuring = false;
    }

    public override void DestroyAll()
    {
        base.DestroyAll();
        Destroy(polygonMeasureGroupInfoPopup.gameObject);
        Destroy(this);
    }

    public override void LateUpdate()
    {
        base.LateUpdate();
        if (polygonMeasureGroupInfoPopup)
        {
            polygonMeasureGroupInfoPopup.transform.LookAt(polygonMeasureGroupInfoPopup.transform.position + cam.transform.forward);

            float heightDiff = Mathf.Abs(cam.transform.position.y - polygonMeasureGroupInfoPopup.transform.position.y);
            polygonMeasureGroupInfoPopup.transform.localScale = Vector3.one * (heightDiff * lineScaleMultiplier);
        }
    }

    public override void UpdatePreviewLine(Vector3 mousePos)
    {
        if (line == null) 
                return;

        if (points.Count == 1 && labels.Count == 1)
        {
            line.positionCount = 2;
            line.SetPosition(0, points[0]);
            line.SetPosition(1, mousePos);

            Vector3 mid = (points[0] + mousePos) * 0.5f;
            labels[0].transform.position = mid;

            // 거리 계산
            double3 llh_a = GeoUtils.GetLonLatHeight(cesiumGeoreference, points[0]);
            double3 llh_b = GeoUtils.GetLonLatHeight(cesiumGeoreference, mousePos);
            double dist = GeoUtils.Haversine(llh_a.x, llh_a.y, llh_b.x, llh_b.y);

            labels[0].GetComponentInChildren<TextMeshProUGUI>().text = $"{dist:F1} m";
            polygonMeasureGroupInfoPopup?.UpdateInfo("(없음)", llh_b.x, llh_b.y, dist, 0);
        }
        else if (points.Count == 2)
        {
            Vector3 a = points[0];
            Vector3 b = points[1];
            Vector3 ab = b - a;

            // 직각 백터
            Vector3 perp = new Vector3(-ab.z, 0, ab.x).normalized;

            // 높이
            Vector3 ac = mousePos - a;
            float length = Vector3.Dot(ac, perp);

            Vector3 c = b + perp * length;
            Vector3 d = a + (c - b);

            // 라인 업데이트
            line.positionCount = 5;
            line.SetPositions(new Vector3[] { a, b, c, d, a });

            double totalDistance = 0;
            double width = 0, height = 0;

            Vector3[] corners = { a, b, c, d };
            for (int i = 0; i < 4; i++)
            {
                int j = (i + 1) % 4;
                Vector3 mid = (corners[i] + corners[j]) * 0.5f;

                labels[i].transform.position = mid;

                double3 llh_a = GeoUtils.GetLonLatHeight(cesiumGeoreference, corners[i]);
                double3 llh_b = GeoUtils.GetLonLatHeight(cesiumGeoreference, corners[j]);
                double dist = GeoUtils.Haversine(llh_a.x, llh_a.y, llh_b.x, llh_b.y);

                labels[i].GetComponentInChildren<TextMeshProUGUI>().text = $"{dist:F1} m";
                totalDistance += dist;

                if (i == 0) width = dist;  
                if (i == 1) height = dist;  
            }

            double area = width * height;

            double3 llh_c = GeoUtils.GetLonLatHeight(cesiumGeoreference, c);
            polygonMeasureGroupInfoPopup?.UpdateInfo("(없음)", llh_c.x, llh_c.y, totalDistance, area);
        }
    }
}
