using UnityEngine;
using System;
using System.IO;
using TMPro;
using System.Runtime.InteropServices;

#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using Graphics = System.Drawing.Graphics;
#endif

public class TakeScreen : MonoBehaviour
{
    public int selectMonitorIndex = 2;
    public int takeNumber;
    
    [SerializeField] TMP_InputField inputPrefix;
    [SerializeField] TMP_InputField inputResult;
    [SerializeField] DirectorySelect directorySelector;

    // --- Windows 전용 구조체 및 변수 ---
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
    [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left, top, right, bottom; }
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct MONITORINFO
    {
        public int cbSize;
        public RECT rcMonitor;
        public RECT rcWork;
        public int dwFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string szDevice;
    }
    private delegate bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);
    [DllImport("user32.dll")] private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumProc lpfnEnum, IntPtr dwData);
    [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
    [DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hWnd);
    [DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
    [DllImport("gdi32.dll")] private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height);
    [DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
    [DllImport("gdi32.dll")] private static extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
    [DllImport("gdi32.dll")] private static extern bool DeleteObject(IntPtr hObject);
    [DllImport("gdi32.dll")] private static extern bool DeleteDC(IntPtr hdc);
    [DllImport("user32.dll")] private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    MONITORINFO selectMonitor;
    int selectWidth;
    int selectHeight;
    int monitorIndex = 0;
#endif

    private void Start()
    {
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
        EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorCallback, IntPtr.Zero);
#else
        Debug.Log("macOS 환경입니다. 시스템 기본 스크린샷 기능을 사용합니다.");
#endif
    }

#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
    private bool MonitorCallback(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData)
    {
        MONITORINFO mi = new MONITORINFO();
        mi.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
        monitorIndex++;
        if (GetMonitorInfo(hMonitor, ref mi) && monitorIndex == selectMonitorIndex)
        {
            selectMonitor = mi;
            selectWidth = mi.rcMonitor.right - mi.rcMonitor.left;
            selectHeight = mi.rcMonitor.bottom - mi.rcMonitor.top;
        }
        return true;
    }
#endif

    public void Take()
    {
        string fileName = $"{inputPrefix.text}_{takeNumber:D2}.png";
        string savePath = Path.Combine(directorySelector.selectedFolderPath, fileName);

#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
        ShotWin(selectMonitor.rcMonitor.left, selectMonitor.rcMonitor.top, selectWidth, selectHeight, savePath);
#elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
        ShotMac(savePath);
#endif
        inputResult.text = savePath;
        takeNumber++;
    }

    // Windows 캡처 로직
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
    void ShotWin(int x, int y, int width, int height, string savePath)
    {
        IntPtr desktopDC = GetDC(IntPtr.Zero);
        IntPtr memoryDC = CreateCompatibleDC(desktopDC);
        IntPtr bitmap = CreateCompatibleBitmap(desktopDC, width, height);
        IntPtr oldBitmap = SelectObject(memoryDC, bitmap);

        // 0x00CC0020 = SRCCOPY, 0x40000000 = CAPTUREBLT
        BitBlt(memoryDC, 0, 0, width, height, desktopDC, x, y, 0x00CC0020 | 0x40000000);

        using (Bitmap bmp = Image.FromHbitmap(bitmap))
        {
            bmp.Save(savePath, ImageFormat.Png);
        }

        SelectObject(memoryDC, oldBitmap);
        DeleteObject(bitmap);
        DeleteDC(memoryDC);
        ReleaseDC(IntPtr.Zero, desktopDC);
    }
#endif

    // macOS 캡처 로직
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
    void ShotMac(string savePath)
    {
        // macOS는 시스템 명령어를 통해 스크린샷을 찍는 것이 가장 안정적입니다.
        // -x: 소리 없음, -C: 커서 포함(선택)
        // 만약 특정 모니터만 찍어야 한다면 -D 옵션을 사용합니다 (예: -D 1)
        string args = $"-x \"{savePath}\"";
        
        try
        {
            System.Diagnostics.Process.Start("screencapture", args);
            Debug.Log($"macOS 스크린샷 저장 완료: {savePath}");
        }
        catch (Exception e)
        {
            Debug.LogError($"macOS 스크린샷 실패: {e.Message}");
        }
    }
#endif
}