using TMPro;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public static class MyUIUtil
{
    static string path_whitebg = "Assets/ResWork/UI_Image/Common/whitebg.png";

    static void SetLayerRecursively(GameObject obj, string newLayer = "UI")
    {
        obj.layer = LayerMask.NameToLayer(newLayer);

        foreach (Transform child in obj.transform)
            SetLayerRecursively(child.gameObject, newLayer); // 재귀 호출로 자식까지 처리
    }

    [MenuItem("GameObject/UI/New Image &i")] // &i는 Alt + I를 의미
    static void CreateUIImage()
    {
        GameObject imageObject = new GameObject("New Image", typeof(Image));

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(imageObject, "New Image");

        var img = imageObject.GetComponent<Image>();
        img.raycastTarget = false;
        img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);

        if (Selection.activeGameObject != null)
        {
            imageObject.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(imageObject);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = imageObject;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/Text Only &t")] // &t는 Alt + T를 의미
    static void CreateUITextMeshPro()
    {
        GameObject textObject = new GameObject("New TMP", typeof(TextMeshProUGUI));

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(textObject, "New TMP");

        var tm = textObject.GetComponent<TextMeshProUGUI>();
        tm.raycastTarget = false;
        tm.alignment = TextAlignmentOptions.Midline;
        tm.textWrappingMode = TextWrappingModes.NoWrap;
        if (Selection.activeGameObject != null)
        {
            textObject.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(textObject);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = textObject;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }
    [MenuItem("GameObject/UI/Text - Local &y")]
    static void CreateUITextMeshProWithLocal()
    {
        GameObject textObject = new GameObject("Local TMP", typeof(TextMeshProUGUI));

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(textObject, "Local TMP");

        var tm = textObject.GetComponent<TextMeshProUGUI>();
        tm.raycastTarget = false;
        tm.alignment = TextAlignmentOptions.Midline;
        tm.textWrappingMode = TextWrappingModes.NoWrap;
        if (Selection.activeGameObject != null)
        {
            textObject.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(textObject);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = textObject;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/Button &b")] // Alt + B: Button 생성 (Image, Button, PlayClickSound_Only 추가)
    static void CreateUIButton()
    {
        // 버튼 오브젝트 생성 (Image, Button 컴포넌트 포함)
        GameObject buttonObject = new GameObject("btn_");

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(buttonObject, "btn_");

        buttonObject.AddComponent<Image>().sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        buttonObject.AddComponent<Button>();

        // TextMeshPro-UGUI 생성 및 설정
        GameObject textObject = new GameObject("btnName", typeof(TextMeshProUGUI));
        TextMeshProUGUI tmp = textObject.GetComponent<TextMeshProUGUI>();
        tmp.text = "Button";
        tmp.alignment = TextAlignmentOptions.Midline;
        tmp.raycastTarget = false;

        // Text 객체를 Button의 자식으로 설정
        textObject.transform.SetParent(buttonObject.transform, false);
        RectTransform textRect = textObject.GetComponent<RectTransform>();
        textRect.anchorMin = Vector2.zero;
        textRect.anchorMax = Vector2.one;
        textRect.offsetMin = Vector2.zero;
        textRect.offsetMax = Vector2.zero;

        // 버튼 오브젝트의 부모 설정
        if (Selection.activeGameObject != null)
        {
            buttonObject.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(buttonObject);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = buttonObject;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/My Slider &%#s")] // Alt + Shift + S: Slider 생성
    static void CreateUISlider()
    {
        GameObject sliderObject = new GameObject("Slider_", typeof(Slider));

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(sliderObject, "Slider_");

        sliderObject.GetComponent<RectTransform>().sizeDelta = new Vector2(200f, 20f);
        Slider slider = sliderObject.GetComponent<Slider>();
        slider.value = 0.5f;

        // Slider의 자식 오브젝트로 Background 이미지 추가
        GameObject backgroundObject = new GameObject("Background", typeof(Image));
        backgroundObject.transform.SetParent(sliderObject.transform, false);
        var img = backgroundObject.GetComponent<Image>();
        img.raycastTarget = false;
        img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        RectTransform bgRect = backgroundObject.GetComponent<RectTransform>();
        bgRect.anchorMin = new Vector2(0, 0);
        bgRect.anchorMax = new Vector2(1, 1);
        bgRect.offsetMin = new Vector2(0, 0); // Custom Stretch 적용
        bgRect.offsetMax = new Vector2(0, 0); // Custom Stretch 적용

        // Fill Area 오브젝트 추가
        GameObject fillAreaObject = new GameObject("Fill Area", typeof(RectTransform));
        fillAreaObject.transform.SetParent(sliderObject.transform, false);
        RectTransform fillAreaRect = fillAreaObject.GetComponent<RectTransform>();
        fillAreaRect.anchorMin = new Vector2(0, 0);
        fillAreaRect.anchorMax = new Vector2(1, 1);
        fillAreaRect.offsetMin = new Vector2(0, 0); // Custom Stretch 적용
        fillAreaRect.offsetMax = new Vector2(0, 0); // Custom Stretch 적용

        // Fill Area 자식으로 Fill 이미지 추가
        GameObject fillObject = new GameObject("Fill", typeof(Image));
        fillObject.transform.SetParent(fillAreaObject.transform, false);
        slider.targetGraphic = fillObject.GetComponent<Image>();
        slider.targetGraphic.color = Color.yellow;
        slider.targetGraphic.raycastTarget = false;
        (slider.targetGraphic as Image).sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        RectTransform fillRect = fillObject.GetComponent<RectTransform>();
        fillRect.anchorMin = new Vector2(0, 0);
        fillRect.anchorMax = new Vector2(1, 1);
        fillRect.offsetMin = new Vector2(0, 0);
        fillRect.offsetMax = new Vector2(0, 0); // Stretch left 적용

        // Fill 이미지 설정
        slider.fillRect = fillRect;

        if (Selection.activeGameObject != null)
        {
            sliderObject.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(sliderObject);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = sliderObject;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/My CheckUI &%#c")]
    static void CreateUICheck()
    {
        // 0. "check_" GameObject 생성
        GameObject gocheck = new GameObject("check_");

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(gocheck, "check_");

        gocheck.AddComponent<RectTransform>();

        // 1. 자식으로 크기 27x27 Image 추가
        GameObject imageObject1 = new GameObject("checkbg", typeof(Image));
        imageObject1.GetComponent<Image>().sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        imageObject1.transform.SetParent(gocheck.transform, false); // gocheck의 자식으로 설정
        RectTransform image1Rect = imageObject1.GetComponent<RectTransform>();
        image1Rect.sizeDelta = new Vector2(50, 50); // 크기 설정
        // 버튼 및 버튼음 추가
        imageObject1.AddComponent<Button>();

        // 2. 1 의 자식으로 크기 39x30 Image 추가
        GameObject imageObject2 = new GameObject("check", typeof(Image));
        imageObject2.GetComponent<Image>().sprite = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/ResWork/UI/NewRes/bg/checkmark.png");
        imageObject2.transform.SetParent(imageObject1.transform, false); // imageObject1의 자식으로 설정
        RectTransform image2Rect = imageObject2.GetComponent<RectTransform>();
        image2Rect.sizeDelta = new Vector2(50, 37); // 크기 설정

        // 3. 1의 오른쪽에 1과 같은 깊이로 TMP 추가
        GameObject textObject = new GameObject("checkName", typeof(TextMeshProUGUI));
        textObject.transform.SetParent(gocheck.transform, false); // gocheck의 자식으로 설정
        RectTransform textRect = textObject.GetComponent<RectTransform>();
        textRect.sizeDelta = new Vector2(100, 30); // TMP의 기본 크기 설정
        textRect.anchoredPosition = new Vector2(image1Rect.sizeDelta.x + 50, 0); // Image1의 오른쪽으로 배치

        TextMeshProUGUI tmp = textObject.GetComponent<TextMeshProUGUI>();
        tmp.alignment = TextAlignmentOptions.MidlineLeft;
        tmp.text = "체크 UI";
        tmp.raycastTarget = false;

        // 현재 선택된 오브젝트를 부모로 설정 (선택된 오브젝트가 있을 때만)
        if (Selection.activeGameObject != null)
        {
            gocheck.transform.SetParent(Selection.activeGameObject.transform, false);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = gocheck;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/My Scroll &#v")] // Alt + Shift + V 단축키
    static void CreateUIScrollview()
    {
        // 0. "scrollview_" GameObject 생성
        GameObject go_sv = new GameObject("scrollview_");

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(go_sv, "scrollview_");

        var img = go_sv.AddComponent<Image>();
        img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        var sr = go_sv.AddComponent<ScrollRect>();
        sr.horizontal = false;

        // 1. 자식으로 Viewport 추가
        GameObject go_vp = new GameObject("Viewport", typeof(Image));
        go_vp.AddComponent<Mask>().showMaskGraphic = false;
        go_vp.transform.SetParent(go_sv.transform, false); // 자식으로 설정
        var rt_vp = go_vp.GetComponent<RectTransform>(); // 이미 추가된 RectTransform 가져오기
        rt_vp.anchorMin = Vector2.zero;
        rt_vp.anchorMax = Vector2.one;
        rt_vp.pivot = Vector2.up;
        rt_vp.offsetMin = Vector2.zero; // Left와 Bottom을 0으로 설정
        rt_vp.offsetMax = Vector2.zero; // Right와 Top을 0으로 설정
        var img_vp = go_vp.GetComponent<Image>();
        img_vp.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);

        // ScrollRect의 Viewport를 설정
        sr.viewport = rt_vp;

        // 2. 1의 자식으로 Content 추가
        GameObject go_ct = new GameObject("Content");
        go_ct.transform.SetParent(go_vp.transform, false); // Content를 Viewport의 자식으로 설정
        go_ct.AddComponent<ContentSizeFitter>().verticalFit = ContentSizeFitter.FitMode.PreferredSize; // ContentSizeFitter 설정
        var rt_ct = go_ct.GetComponent<RectTransform>();
        rt_ct.anchorMin = Vector2.up;
        rt_ct.anchorMax = Vector2.one;
        rt_ct.pivot = Vector2.up;
        rt_ct.offsetMin = Vector2.zero; // Left와 Bottom을 0으로 설정
        rt_ct.offsetMax = Vector2.zero; // Right와 Top을 0으로 설정

        // ScrollRect의 content 설정
        sr.content = rt_ct;

        // 현재 선택된 오브젝트를 부모로 설정 (선택된 오브젝트가 있을 때만)
        if (Selection.activeGameObject != null)
        {
            go_sv.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(go_sv);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = go_sv;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }

    [MenuItem("GameObject/UI/TMP InputField &%#i")] // Alt + Ctrl + Shift + i 단축키
    static void CreateTMPInputField()
    {
        // 0. GameObject 생성
        GameObject go_if = new GameObject("inputfield_");

        // 생성된 오브젝트에 대한 Undo 기록 추가
        Undo.RegisterCreatedObjectUndo(go_if, "inputfield_");

        var img = go_if.AddComponent<Image>();
        img.sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path_whitebg);
        img.color = new Color32(175, 175, 175, 255);
        var tmp_if = go_if.AddComponent<TMP_InputField>();
        var rt_if = go_if.GetComponent<RectTransform>();
        rt_if.sizeDelta = new Vector2(160, 50);

        // 1. 자식으로 Text Area 추가
        GameObject go_vp = new GameObject("Text Area", typeof(RectMask2D), typeof(RectTransform));
        go_vp.GetComponent<RectMask2D>().padding = new Vector4(-8, -5, -8, -5);
        go_vp.transform.SetParent(go_if.transform, false); // 자식으로 설정
        var rt_vp = go_vp.GetComponent<RectTransform>();
        Set_RectTransform_CenterStretch(rt_vp);
        tmp_if.textViewport = rt_vp;

        // 2. 1의 자식으로 Placeholder 추가
        GameObject go_ph = new GameObject("Placeholder", typeof(RectTransform));
        go_ph.transform.SetParent(go_vp.transform, false); // 자식으로 설정
        var rt_ph = go_ph.GetComponent<RectTransform>();
        Set_RectTransform_CenterStretch(rt_ph);
        var text_ph = go_ph.AddComponent<TextMeshProUGUI>();
        text_ph.raycastTarget = false;
        text_ph.textWrappingMode = TextWrappingModes.NoWrap;
        text_ph.alignment = TextAlignmentOptions.Midline;
        text_ph.text = "";
        text_ph.color = Color.black;
        text_ph.fontSize = 30;
        tmp_if.placeholder = text_ph;
        go_ph.AddComponent<LayoutElement>().ignoreLayout = true;

        // 3. 1의 자식으로 Text 추가
        GameObject go_txt = new GameObject("Text", typeof(RectTransform));
        go_txt.transform.SetParent(go_vp.transform, false); // 자식으로 설정
        var rt_txt = go_txt.GetComponent<RectTransform>();
        Set_RectTransform_CenterStretch(rt_txt);
        var text_txt = go_txt.AddComponent<TextMeshProUGUI>();
        text_txt.raycastTarget = false;
        text_txt.textWrappingMode = TextWrappingModes.NoWrap;
        text_txt.alignment = TextAlignmentOptions.Midline;
        text_txt.color = Color.black;
        tmp_if.textComponent = text_txt;
        tmp_if.pointSize = 30;

        // 현재 선택된 오브젝트를 부모로 설정 (선택된 오브젝트가 있을 때만)
        if (Selection.activeGameObject != null)
        {
            go_if.transform.SetParent(Selection.activeGameObject.transform, false);
            SetLayerRecursively(go_if);

            // 새로 생성된 오브젝트를 선택
            Selection.activeGameObject = go_if;

            // 씬 뷰에서 해당 오브젝트에 포커스 맞추기
            //SceneView.lastActiveSceneView.FrameSelected();
        }
    }
    static void Set_RectTransform_CenterStretch(RectTransform rtf)
    {
        rtf.anchorMin = Vector2.zero;
        rtf.anchorMax = Vector2.one;
        rtf.pivot = new Vector2(0.5f, 0.5f);
        rtf.offsetMin = Vector2.zero;
        rtf.offsetMax = Vector2.zero;
    }
}