use crate::ns_string;
use anyhow::Result;
use cocoa::{
    appkit::NSScreen,
    base::{id, nil},
    foundation::{NSArray, NSDictionary},
};
use core_foundation::base::CFRelease;
use core_foundation::uuid::{CFUUIDGetUUIDBytes, CFUUIDRef};
use core_graphics::display::{CGDirectDisplayID, CGDisplayBounds, CGGetActiveDisplayList};
use objc::{msg_send, sel, sel_impl};
use rgpui::{Bounds, DisplayId, Pixels, PlatformDisplay, point, px, size};
use uuid::Uuid;

/// macOS 显示器封装，包含 `CGDirectDisplayID`。
#[derive(Debug)]
pub(crate) struct MacDisplay(pub(crate) CGDirectDisplayID);

unsafe impl Send for MacDisplay {}

impl MacDisplay {
    /// 根据 [`DisplayId`] 获取对应的显示器。
    pub fn find_by_id(id: DisplayId) -> Option<Self> {
        Self::all().find(|screen| screen.id() == id)
    }

    /// 获取主显示器——包含菜单栏的显示器，
    /// 其左下角位于 AppKit 坐标系的原点。
    pub fn primary() -> Self {
        // 我们不通过 `all()` 遍历所有活动显示器，而是使用第一个
        // NSScreen 并获取其 CGDirectDisplayID，因为我们无法确定 `CGGetActiveDisplayList`
        // 总是返回活动显示器列表（机器可能处于睡眠状态）。
        //
        // 以下是 Chromium 的做法：
        //
        // https://chromium.googlesource.com/chromium/src/+/66.0.3359.158/ui/display/mac/screen_mac.mm#56
        unsafe {
            let screens = NSScreen::screens(nil);
            let screen = cocoa::foundation::NSArray::objectAtIndex(screens, 0);
            let device_description = NSScreen::deviceDescription(screen);
            let screen_number_key: id = ns_string("NSScreenNumber");
            let screen_number = device_description.objectForKey_(screen_number_key);
            let screen_number: CGDirectDisplayID = msg_send![screen_number, unsignedIntegerValue];
            Self(screen_number)
        }
    }

    /// 获取当前所有活动显示器的迭代器。
    pub fn all() -> impl Iterator<Item = Self> {
        unsafe {
            // 我们假设系统连接的显示器不超过 32 个。
            let mut displays = Vec::with_capacity(32);
            let mut display_count = 0;
            let result = CGGetActiveDisplayList(
                displays.capacity() as u32,
                displays.as_mut_ptr(),
                &mut display_count,
            );

            if result == 0 {
                displays.set_len(display_count as usize);
                displays.into_iter().map(MacDisplay)
            } else {
                panic!("Failed to get active display list. Result: {result}");
            }
        }
    }
}

#[link(name = "ApplicationServices", kind = "framework")]
unsafe extern "C" {
    fn CGDisplayCreateUUIDFromDisplayID(display: CGDirectDisplayID) -> CFUUIDRef;
}

impl PlatformDisplay for MacDisplay {
    fn id(&self) -> DisplayId {
        DisplayId::new(self.0 as u64)
    }

    fn uuid(&self) -> Result<Uuid> {
        let cfuuid = unsafe { CGDisplayCreateUUIDFromDisplayID(self.0 as CGDirectDisplayID) };
        anyhow::ensure!(
            !cfuuid.is_null(),
            "AppKit returned a null from CGDisplayCreateUUIDFromDisplayID"
        );

        let bytes = unsafe { CFUUIDGetUUIDBytes(cfuuid) };
        unsafe { CFRelease(cfuuid as _) };
        Ok(Uuid::from_bytes([
            bytes.byte0,
            bytes.byte1,
            bytes.byte2,
            bytes.byte3,
            bytes.byte4,
            bytes.byte5,
            bytes.byte6,
            bytes.byte7,
            bytes.byte8,
            bytes.byte9,
            bytes.byte10,
            bytes.byte11,
            bytes.byte12,
            bytes.byte13,
            bytes.byte14,
            bytes.byte15,
        ]))
    }

    fn bounds(&self) -> Bounds<Pixels> {
        unsafe {
            // CGDisplayBounds 使用「全局显示」坐标系，其中 0 是
            // 主显示器的左上角。
            let bounds = CGDisplayBounds(self.0);

            Bounds {
                origin: Default::default(),
                size: size(px(bounds.size.width as f32), px(bounds.size.height as f32)),
            }
        }
    }

    fn visible_bounds(&self) -> Bounds<Pixels> {
        unsafe {
            let dominated_screen = self.get_nsscreen();

            if dominated_screen == nil {
                return self.bounds();
            }

            let screen_frame = NSScreen::frame(dominated_screen);
            let visible_frame = NSScreen::visibleFrame(dominated_screen);

            // 从左下角原点（AppKit）转换为左上角原点
            let origin_y =
                screen_frame.size.height - visible_frame.origin.y - visible_frame.size.height
                    + screen_frame.origin.y;

            Bounds {
                origin: point(
                    px(visible_frame.origin.x as f32 - screen_frame.origin.x as f32),
                    px(origin_y as f32),
                ),
                size: size(
                    px(visible_frame.size.width as f32),
                    px(visible_frame.size.height as f32),
                ),
            }
        }
    }
}

impl MacDisplay {
    /// 查找与此显示器对应的 NSScreen
    unsafe fn get_nsscreen(&self) -> id {
        let screens = unsafe { NSScreen::screens(nil) };
        let count = unsafe { NSArray::count(screens) };
        let screen_number_key: id = unsafe { ns_string("NSScreenNumber") };

        for i in 0..count {
            let screen = unsafe { NSArray::objectAtIndex(screens, i) };
            let device_description = unsafe { NSScreen::deviceDescription(screen) };
            let screen_number = unsafe { device_description.objectForKey_(screen_number_key) };
            let screen_id: CGDirectDisplayID = msg_send![screen_number, unsignedIntegerValue];
            if screen_id == self.0 {
                return screen;
            }
        }
        nil
    }
}
