using UnityEngine;
using UnityEditor;
using UnityRawInput;
using System.Collections.Generic;
using System.Linq;
using Unity.Cinemachine;

[CustomEditor(typeof(CameraManager))]
public class CameraManagerEditor : Editor
{
    private HashSet<KeyCode> currentKeys = new HashSet<KeyCode>();
    private bool isApplicationPlaying;
    private bool isListening = false;

    private void OnEnable()
    {
        isApplicationPlaying = Application.isPlaying;
    }

    private void OnDisable()
    {
        StopListening();
    }

    private void StartListening()
    {
        if (!isApplicationPlaying)
        {
            currentKeys.Clear();
            isListening = true;
            Debug.Log("키보드 입력 감지 시작");
        }
    }

    private void StopListening()
    {
        isListening = false;
    }

    public override void OnInspectorGUI()
    {
        CameraManager manager = (CameraManager)target;
        EditorGUILayout.Space(10);

        EditorGUILayout.BeginVertical(EditorStyles.helpBox);
        EditorGUILayout.LabelField("카메라 프리셋 관리", EditorStyles.boldLabel);
        EditorGUILayout.Space(5);

        // 프리셋 추가 버튼
        if (GUILayout.Button("새 프리셋 추가", GUILayout.Height(30)))
        {
            // Scene에 있는 CinemachineCamera 컴포넌트를 가져와서 새 프리셋 생성
            var newCamera = FindFirstObjectByType<CinemachineCamera>();
            if (newCamera != null)
            {
                manager.cameraPresets.Add(new CameraManager.CameraPreset(newCamera));
                EditorUtility.SetDirty(target);
            }
            else
            {
                EditorUtility.DisplayDialog("알림", "Scene에 CinemachineCamera가 없습니다.", "확인");
            }
        }

        EditorGUILayout.Space(10);

        // 프리셋 리스트
        for (int i = 0; i < manager.cameraPresets.Count; i++)
        {
            var preset = manager.cameraPresets[i];
            
            EditorGUILayout.BeginVertical(GUI.skin.box);
            
            // 프리셋 헤더
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField($"프리셋 {i + 1}", EditorStyles.boldLabel, GUILayout.Width(60));
            
            // 프리셋 이름 필드
            preset.presetName = EditorGUILayout.TextField(preset.presetName);
            
            // 삭제 버튼
            if (GUILayout.Button("삭제", GUILayout.Width(50)))
            {
                if (EditorUtility.DisplayDialog("프리셋 삭제", 
                    $"프리셋 {preset.presetName}을(를) 삭제하시겠습니까?", 
                    "삭제", "취소"))
                {
                    manager.cameraPresets.RemoveAt(i);
                    EditorUtility.SetDirty(target);
                    continue;
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space(5);

            // 프리셋 설정
            EditorGUI.indentLevel++;
            
            // 가상 카메라 필드
            preset.virtualCamera = (CinemachineCamera)EditorGUILayout.ObjectField(
                "가상 카메라", preset.virtualCamera, typeof(CinemachineCamera), true);

            // 핫키 설정 UI
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("핫키", GUILayout.Width(100));
            
            if (preset.hotkey.isRecording)
            {
                EditorGUILayout.LabelField("키를 눌렀다 떼면 저장됩니다...", EditorStyles.helpBox);
            }
            else
            {
                EditorGUILayout.LabelField(preset.hotkey.ToString());

                if (GUILayout.Button("레코딩", GUILayout.Width(60)))
                {
                    foreach (var otherPreset in manager.cameraPresets)
                    {
                        otherPreset.hotkey.isRecording = false;
                    }
                    preset.hotkey.isRecording = true;
                    preset.hotkey.rawKeys.Clear();
                    StartListening();
                }
                if (GUILayout.Button("초기화", GUILayout.Width(60)))
                {
                    preset.hotkey.rawKeys.Clear();
                    EditorUtility.SetDirty(target);
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUI.indentLevel--;
            EditorGUILayout.EndVertical();
            EditorGUILayout.Space(5);
        }

        EditorGUILayout.EndVertical();

        // 키 입력 감지 로직
        if (isListening)
        {
            var e = Event.current;
            if (e != null)
            {
                if (e.type == EventType.KeyDown && e.keyCode != KeyCode.None)
                {
                    // 마우스 버튼 제외
                    if (e.keyCode != KeyCode.Mouse0 && e.keyCode != KeyCode.Mouse1 && e.keyCode != KeyCode.Mouse2)
                    {
                        AddKey(e.keyCode);
                        e.Use(); // 이벤트 소비
                    }
                }
                else if (e.type == EventType.KeyUp && currentKeys.Contains(e.keyCode))
                {
                    var recordingPreset = manager.cameraPresets.FirstOrDefault(p => p.hotkey.isRecording);
                    if (recordingPreset != null)
                    {
                        recordingPreset.hotkey.isRecording = false;
                        EditorUtility.SetDirty(target);
                        StopListening();
                        Repaint();
                    }
                    e.Use(); // 이벤트 소비
                }
            }
        }
    }

    private void AddKey(KeyCode keyCode)
    {
        if (!currentKeys.Contains(keyCode))
        {
            currentKeys.Add(keyCode);
            var recordingPreset = ((CameraManager)target).cameraPresets.FirstOrDefault(p => p.hotkey.isRecording);
            if (recordingPreset != null)
            {
                // KeyCode를 RawKey로 변환
                var rawKeys = new List<RawKey>();
                foreach (var key in currentKeys)
                {
                    if (RawKeySetup.KeyMapping.TryGetValue(key, out RawKey rawKey))
                    {
                        rawKeys.Add(rawKey);
                    }
                    else
                    {
                        Debug.LogWarning($"맵핑되지 않은 키: {key}");
                    }
                }
                recordingPreset.hotkey.rawKeys = rawKeys;
                EditorUtility.SetDirty(target);
                Repaint();
            }
        }
    }
}