import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';

import 'window_chrome.dart';

final _windowControlsBinding = _WindowControlsBinding();

class WindowControls extends StatefulWidget {
  final Brightness? brightness;

  const WindowControls({super.key, this.brightness});


  const WindowControls.forShellOverlay({super.key}) : brightness = null;


  const WindowControls.forDarkSurface({super.key})
    : brightness = Brightness.dark;

  @override
  State<WindowControls> createState() => _WindowControlsState();
}

class _WindowControlsState extends State<WindowControls> {
  @override
  void initState() {
    super.initState();
    unawaited(_windowControlsBinding.ensureInitialized());
  }

  Future<void> _toggleMaximize() async {
    if (_windowControlsBinding.isMaximized.value) {
      await windowManager.unmaximize();
      return;
    }
    await windowManager.maximize();
  }

  @override
  Widget build(BuildContext context) {
    if (!Platform.isWindows && !Platform.isMacOS) {
      return const SizedBox.shrink();
    }

    final resolvedBrightness =
        widget.brightness ?? Theme.of(context).brightness;
    final isLight = resolvedBrightness == Brightness.light;

    return ValueListenableBuilder<bool>(
      valueListenable: _windowControlsBinding.isMaximized,
      builder: (context, isMaximized, _) {
        final backgroundColor = isLight
            ? Colors.black.withValues(alpha: 0.14)
            : const Color(0xFF08090c).withValues(alpha: 0.72);
        final iconColor = isLight
            ? Colors.black.withValues(alpha: 0.65)
            : Colors.white.withValues(alpha: 0.85);
        final defaultHoverColor = isLight
            ? Colors.black.withValues(alpha: 0.10)
            : Colors.white.withValues(alpha: 0.15);
        const containerHeight = WindowChrome.controlsHeight;
        const containerRadius = 20.0;
        const buttonWidth = WindowChrome.buttonWidth;
        const iconSize = 16.0;

        return Container(
          height: containerHeight,
          decoration: BoxDecoration(
            color: backgroundColor,
            borderRadius: BorderRadius.circular(containerRadius),
            boxShadow: isLight
                ? null
                : const [
                    BoxShadow(
                      color: Color(0x2E000000),
                      blurRadius: 8,
                      offset: Offset(0, 2),
                    ),
                  ],
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              _ControlButton(
                icon: Icons.remove_rounded,
                tooltip: '最小化',
                iconColor: iconColor,
                defaultHoverColor: defaultHoverColor,
                width: buttonWidth,
                height: containerHeight,
                iconSize: iconSize,
                borderRadius: containerRadius,
                onTap: windowManager.minimize,
              ),
              _ControlButton(
                icon: isMaximized
                    ? Icons.filter_none_rounded
                    : Icons.crop_square_rounded,
                tooltip: isMaximized ? '还原' : '最大化',
                iconColor: iconColor,
                defaultHoverColor: defaultHoverColor,
                width: buttonWidth,
                height: containerHeight,
                iconSize: iconSize,
                borderRadius: containerRadius,
                onTap: _toggleMaximize,
              ),
              _ControlButton(
                icon: Icons.close_rounded,
                tooltip: '关闭',
                iconColor: iconColor,
                defaultHoverColor: defaultHoverColor,
                hoverColor: const Color(0xFFE81123),
                pressedColor: const Color(0xFFC50F1F),
                width: buttonWidth,
                height: containerHeight,
                iconSize: iconSize,
                borderRadius: containerRadius,
                onTap: windowManager.close,
              ),
            ],
          ),
        );
      },
    );
  }
}

class _WindowControlsBinding with WindowListener {
  final ValueNotifier<bool> isMaximized = ValueNotifier(false);

  Future<void> ensureInitialized() async {
    if (!windowManager.listeners.contains(this)) {
      windowManager.addListener(this);
    }
    try {
      isMaximized.value = await windowManager.isMaximized();
    } catch (_) {}
  }

  @override
  void onWindowMaximize() {
    isMaximized.value = true;
  }

  @override
  void onWindowUnmaximize() {
    isMaximized.value = false;
  }

  void reset() {
    if (windowManager.listeners.contains(this)) {
      windowManager.removeListener(this);
    }
    isMaximized.value = false;
  }
}

class _ControlButton extends StatefulWidget {
  final IconData icon;
  final String tooltip;
  final Color iconColor;
  final Color defaultHoverColor;
  final Color? hoverColor;
  final Color? pressedColor;
  final double width;
  final double height;
  final double iconSize;
  final double borderRadius;
  final VoidCallback onTap;

  const _ControlButton({
    required this.icon,
    required this.tooltip,
    required this.iconColor,
    required this.defaultHoverColor,
    this.hoverColor,
    this.pressedColor,
    this.width = 36,
    this.height = 30,
    this.iconSize = 16,
    this.borderRadius = 20,
    required this.onTap,
  });

  @override
  State<_ControlButton> createState() => _ControlButtonState();
}

class _ControlButtonState extends State<_ControlButton> {
  bool _hovering = false;
  bool _pressing = false;
  bool _focused = false;
  late final FocusNode _focusNode;

  @override
  void initState() {
    super.initState();
    _focusNode = FocusNode();
    _focusNode.addListener(_onFocusChange);
  }

  @override
  void dispose() {
    _focusNode.removeListener(_onFocusChange);
    _focusNode.dispose();
    super.dispose();
  }

  void _onFocusChange() {
    setState(() => _focused = _focusNode.hasFocus);
  }

  bool get _active => _hovering || _focused;

  @override
  Widget build(BuildContext context) {
    final hoverBg = widget.hoverColor ?? widget.defaultHoverColor;
    final pressedBg =
        widget.pressedColor ??
        widget.defaultHoverColor.withValues(
          alpha: widget.defaultHoverColor.a * 1.8,
        );

    final Color bg;
    if (_pressing) {
      bg = widget.hoverColor != null
          ? (widget.pressedColor ?? hoverBg)
          : pressedBg;
    } else if (_active) {
      bg = hoverBg;
    } else {
      bg = Colors.transparent;
    }

    final bool useBrightIcon =
        (_active || _pressing) && widget.hoverColor != null;

    return Tooltip(
      message: widget.tooltip,
      child: Focus(
        focusNode: _focusNode,
        child: MouseRegion(
          onEnter: (_) => setState(() => _hovering = true),
          onExit: (_) => setState(() {
            _hovering = false;
            _pressing = false;
          }),
          child: GestureDetector(
            onTap: widget.onTap,
            onTapDown: (_) => setState(() => _pressing = true),
            onTapUp: (_) => setState(() => _pressing = false),
            onTapCancel: () => setState(() => _pressing = false),
            child: Container(
              width: widget.width,
              height: widget.height,
              decoration: BoxDecoration(
                color: bg,
                borderRadius: BorderRadius.circular(widget.borderRadius),
              ),
              alignment: Alignment.center,
              child: Icon(
                widget.icon,
                size: widget.iconSize,
                color: useBrightIcon ? Colors.white : widget.iconColor,
              ),
            ),
          ),
        ),
      ),
    );
  }
}
