import 'dart:math' as math;
import 'package:fis_measure/interfaces/date_types/int_size.dart';
import 'package:fis_measure/interfaces/process/player/play_controller.dart';
import 'package:fis_measure/interfaces/process/workspace/application.dart';
import 'package:fis_measure/view/player/enums.dart';
import 'package:fis_vid/data_host/data_host.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../canvas/active_canvas.dart';
import '../canvas/records_canvas.dart';
import '../gesture/mouse_gesture.dart';
import '../player/controller.dart';
import '../player/events.dart';
import '../player/player.dart';
import '../result/results_panel.dart';

class MeasureMainView extends StatefulWidget {
  const MeasureMainView({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _MeasureMainViewState();
}

class _MeasureMainViewState extends State<MeasureMainView> {
  late final application = Get.find<IApplication>();

  late final playerController = Get.find<IPlayerController>();

  late bool canMeasure = application.canMeasure;

  IntSize get frameSize {
    if (application.frameData == null) return IntSize.empty;

    return IntSize.fill(
      application.frameData!.width,
      application.frameData!.height,
    );
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
      onCanMeasureChanged(this, application.canMeasure);
      application.canMeasureChanged.addListener(onCanMeasureChanged);
    });
  }

  @override
  void dispose() {
    application.canMeasureChanged.removeListener(onCanMeasureChanged);
    super.dispose();
  }

  void onCanMeasureChanged(Object sender, bool e) {
    if (e != canMeasure) {
      setState(() {
        canMeasure = e;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.black,
      child: CustomMultiChildLayout(
        delegate: _LayerLayoutDelegate(imageSize: frameSize),
        children: [
          LayoutId(
            id: _LayerLayoutIds.player,
            child: Container(
              decoration: BoxDecoration(
                  // border: Border.all(color: Colors.white),
                  ),
              child: VidPlayer(playerController as VidPlayerController),
            ),
          ),
          if (canMeasure) ...[
            LayoutId(
              id: _LayerLayoutIds.recordsCanvas,
              child: const MeasureRecordsCanvasPanel(),
            ),
            LayoutId(
              id: _LayerLayoutIds.result,
              child: const MeasureResultPanel(),
            ),
            LayoutId(
              id: _LayerLayoutIds.activeCanvas,
              child: const MeasureActiveCanvasPanel(),
            ),
            LayoutId(
              id: _LayerLayoutIds.gesture,
              child: const MeasureMouseGesturePanel(),
            ),
          ],
        ],
      ),
    );
  }
}

class _LayerLayoutDelegate extends MultiChildLayoutDelegate {
  final IntSize? imageSize;
  Offset? layoutOffset;
  Size? layoutSize;

  _LayerLayoutDelegate({required this.imageSize});

  @override
  void performLayout(Size size) {
    if (imageSize == null) return;
    if (!hasChild(_LayerLayoutIds.player)) return;

    /// 以Contain方式填充布局，计算定位偏移量
    calcSize(size);
    final offset = layoutOffset!;
    final renderSize = layoutSize!;

    Get.find<IApplication>().displaySize = renderSize;

    layoutLayer(_LayerLayoutIds.player, offset, renderSize);

    /// 其他层按播放器尺寸位置层叠布局
    layoutLayer(_LayerLayoutIds.recordsCanvas, offset, renderSize);
    layoutLayer(_LayerLayoutIds.result, offset, renderSize);
    layoutLayer(_LayerLayoutIds.activeCanvas, offset, renderSize);
    layoutLayer(_LayerLayoutIds.gesture, offset, renderSize);
  }

  void layoutLayer(_LayerLayoutIds layoutId, Offset offset, Size size) {
    if (hasChild(layoutId)) {
      layoutChild(
        layoutId,
        BoxConstraints.loose(size),
      );
      positionChild(layoutId, offset);
    }
  }

  void calcSize(Size size) {
    final parentWHRatio = size.width / size.height;
    final imageWHRatio = imageSize!.width / imageSize!.height;
    if (imageWHRatio < parentWHRatio) {
      // 高度撑满
      final layoutWidth = size.height * imageWHRatio;
      final layoutHeight = size.height;
      final offsetX = (size.width - layoutWidth) / 2;
      layoutOffset = Offset(offsetX, 0);
      layoutSize = Size(layoutWidth, layoutHeight);
    } else if (imageWHRatio > parentWHRatio) {
      // 宽度撑满
      final layoutWidth = size.width;
      final layoutHeight = size.width / imageWHRatio;
      final offsetY = (size.height - layoutHeight) / 2;
      layoutOffset = Offset(0, offsetY);
      layoutSize = Size(layoutWidth, layoutHeight);
    } else {
      layoutOffset = Offset.zero;
      layoutSize = size;
    }
    // final widthRatio = imageSize!.width / size.width;
    // final heightRatio = imageSize!.height / size.height;
    // if (widthRatio < heightRatio) {
    //   final layoutWidth = size.width * heightRatio;
    //   final layoutHeight = size.height;
    //   final offsetX = (size.width - layoutWidth) / 2;
    //   layoutOffset = Offset(offsetX, 0);
    //   layoutSize = Size(layoutWidth, layoutHeight);
    // } else if (widthRatio > heightRatio) {
    //   final layoutWidth = size.width;
    //   final layoutHeight = size.height * widthRatio;
    //   final offsetY = (size.height - layoutHeight) / 2;
    //   layoutOffset = Offset(0, offsetY);
    //   layoutSize = Size(layoutWidth, layoutHeight);
    // } else {
    //   layoutOffset = Offset.zero;
    //   layoutSize = size;
    // }
  }

  @override
  bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) {
    return false;
  }
}

enum _LayerLayoutIds {
  /// 播放器
  player,

  /// 测量记录画板
  recordsCanvas,

  /// 活动测量画板
  activeCanvas,

  /// 结果面板
  result,

  /// 手势面板
  gesture,
}
