import 'package:flyinsono/lab/pages/lab_image/widgets/image_measure_overlay/controller.dart';
import 'package:get/get.dart';
import 'package:fis_measure/interfaces/date_types/rect_region.dart';
import 'package:fis_measure/interfaces/date_types/point.dart';
import 'package:fis_measure/view/gesture/cross_position_indicator.dart';
import 'package:fis_measure/view/gesture/mouse_gesture.dart';
import 'package:fis_measure/values/colors.dart';
import 'package:fis_measure/view/cursor.dart';
import 'package:flutter/material.dart';
import 'package:fis_measure/view/gesture/positioned_cursor.dart';

// 鼠标指示器
class MouseGestureArea extends StatefulWidget {
  const MouseGestureArea(
      {super.key,
      this.onMouseDown,
      this.onMouseMove,
      this.ifContainerTissueTM = false,
      this.tissueTMPixelRegion = const RectRegion(),
      required this.tabHashCode,
      required this.isLeftRight});

  final ValueChanged<Offset>? onMouseDown;
  final ValueChanged<Offset>? onMouseMove;
  final bool ifContainerTissueTM;
  final RectRegion tissueTMPixelRegion;
  final bool isLeftRight;

  final String tabHashCode;

  @override
  State<MouseGestureArea> createState() => _MouseGestureAreaState();
}

class _MouseGestureAreaState extends State<MouseGestureArea> {
  Offset? cursorPosition;
  CursorDisplayType displayType = CursorDisplayType.none;
  bool onRightArea = false;

  final mouseState = Get.find<IMouseState>();

  @override
  void initState() {
    mouseState.cursorSizeChanged.addListener(onCursorSizeChanged);
    mouseState.cursorScaleRatioChanged.addListener(onCursorScaleRatioChanged);
    mouseState.cursorTypeChanged.addListener(cursorTypeChanged);
    mouseState.mousePositionChanged.addListener(mousePositionChanged);
    super.initState();
  }

  @override
  void dispose() {
    mouseState.cursorSizeChanged.removeListener(onCursorSizeChanged);
    mouseState.cursorScaleRatioChanged
        .removeListener(onCursorScaleRatioChanged);
    mouseState.cursorTypeChanged.removeListener(cursorTypeChanged);
    mouseState.mousePositionChanged.removeListener(mousePositionChanged);
    super.dispose();
  }

  void onCursorSizeChanged(Object sender, dynamic e) {
    onUpdate();
  }

  void onCursorScaleRatioChanged(Object sender, dynamic e) {
    onUpdate();
  }

  void cursorTypeChanged(Object sender, dynamic e) {
    onUpdate();
  }

  void mousePositionChanged(Object sender, dynamic e) {
    onUpdate();
  }

  void onUpdate() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return GetBuilder<ImageMeasureOverlayController>(
      tag: widget.tabHashCode,
      builder: (context) {
        return Row(
          children: [
            Expanded(
              child: buildGestureArea(),
            ),
            if (widget.isLeftRight)
              Expanded(
                child: buildGestureArea(rightArea: true),
              ),
          ],
        );
      },
    );
  }

  Widget buildGestureArea({bool rightArea = false}) {
    return GestureDetector(
      onTapDown: (details) {
        widget.onMouseDown?.call(details.localPosition);
      },
      onPanUpdate: (details) {
        setState(() {
          cursorPosition = details.localPosition;
        });
        widget.onMouseMove?.call(details.localPosition);
      },
      child: MouseRegion(
        cursor: SystemMouseCursors.none,
        onHover: (event) {
          setState(() {
            cursorPosition = event.localPosition;
          });
          widget.onMouseMove?.call(event.localPosition);
          _handleAreaChange(event.localPosition);
        },
        onEnter: (e) {
          setState(() {
            displayType = CursorDisplayType.normal;
          });
          if (rightArea) {
            onRightArea = true;
          } else {
            onRightArea = false;
          }
        },
        onExit: (e) {
          setState(() {
            displayType = CursorDisplayType.none;
          });
          if (rightArea) {
            onRightArea = false;
          } else {
            onRightArea = true;
          }
        },
        child: Stack(
          children: [
            if (rightArea == onRightArea) _buildCursor(),
          ],
        ),
      ),
    );
  }

  Widget _buildCursor() {
    switch (displayType) {
      case CursorDisplayType.none:
        return Container();
      case CursorDisplayType.normal:
        return _buildPositionedCursor(cursorPosition);
      case CursorDisplayType.cross:
        return CrossIndicator(
          areaRegion: Rect.fromLTRB(
            widget.tissueTMPixelRegion.left,
            widget.tissueTMPixelRegion.top,
            widget.tissueTMPixelRegion.right,
            widget.tissueTMPixelRegion.bottom,
          ),
        );
    }
  }

  Widget _buildPositionedCursor(Offset? cursorPosition) {
    if (cursorPosition == null) return Container();
    final offset = mouseState.cursorScaleRatio * mouseState.cursorSize / 2;
    final dx = cursorPosition.dx - offset;
    final dy = cursorPosition.dy - offset;

    return Positioned(
      left: dx,
      top: dy,
      child: MeasureCursor(
        type: mouseState.cursorType,
        size: mouseState.cursorSize * mouseState.cursorScaleRatio,
        color: MeasureColors.Primary,
      ),
    );
  }

  void _handleAreaChange(Offset pointerOffset) {
    if (widget.ifContainerTissueTM) {
      if (widget.tissueTMPixelRegion
          .containsPoint(DPoint.parseOffset(pointerOffset))) {
        if (displayType != CursorDisplayType.cross) {
          setState(() {
            displayType = CursorDisplayType.cross;
          });
        }
      } else {
        if (displayType != CursorDisplayType.normal) {
          setState(() {
            displayType = CursorDisplayType.normal;
          });
        }
      }
    }
  }
}
