import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:google_mlkit_object_detection/google_mlkit_object_detection.dart';
import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart';
import 'package:internal/common/camera.dart';
import 'package:internal/common/transform.dart';

/// Description: Home Page
/// Time       : 04/12/2023 Wednesday
/// Author     : liuyuqi.gov@msn.cn
class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

/// Description: Home Page State
class _HomeScreenState extends State<HomeScreen> {

  CameraController? _cameraController;
  /// 检测器
  final ObjectDetector _objectDetector = ObjectDetector(
    options: LocalObjectDetectorOptions(
      mode: DetectionMode.stream,
      multipleObjects: false,
      classifyObjects: false,
      modelPath: 'flutter_assets/0/0.tflite',
    ),
  );
  final TextRecognizer _textDetector = TextRecognizer(
    script: TextRecognitionScript.latin,
  );
  bool _canRender = true;
  bool _canSpace = true;

  final GlobalKey _cameraPreviewKey = GlobalKey();
  List<Rect> _data = [];
  String message = "";
  FlutterTts tts = FlutterTts();

  /// 初始化状态
  @override
  void initState() {
    super.initState();

    tts.awaitSpeakCompletion(true);
    /// 检测可用相机
    availableCameras().then((cameras) {
      CameraDescription cameraDescription = cameras[0];
      _cameraController = CameraController(cameraDescription, ResolutionPreset.high, enableAudio: false); // ResolutionPreset.high 质量较高的预设,不录音
      _cameraController!.initialize().then((_) {
        _cameraController!.startImageStream((image) => processCameraImage(cameraDescription, image, onImage));
        setState(() {});
      });
    });
  }

  /// 回调函数,处理camera拍摄的图片
  Future<void> onImage(InputImage inputImage) async {
    if (!_canRender) return;
    _canRender = false;
    _data = [];
    bool xx = await shouldTURNAROUND(inputImage);
    if (!xx) await shouldGUIDELINE(inputImage);
    _canRender = true;
  }
  /// 是否需要旋转图片
  /// [inputImage] 图片
  Future<bool> shouldTURNAROUND(InputImage inputImage) async {
    final list = await _textDetector.processImage(inputImage); // 识别文字
    Size? size = _cameraPreviewKey.currentContext?.size;
    if (size == null) {
      return false;
    }
    InputImageRotation? rotation = inputImage.inputImageData?.imageRotation;
    Size? absoluteSize = inputImage.inputImageData?.size;
    if (rotation == null || absoluteSize == null) {
      return false;
    }
    List<Rect> data = [];
    for (final item in list.blocks) {
      final left = translateX(item.boundingBox.left, rotation, size, absoluteSize);
      final top = translateY(item.boundingBox.top, rotation, size, absoluteSize);
      final right = translateX(item.boundingBox.right, rotation, size, absoluteSize);
      final bottom = translateY(item.boundingBox.bottom, rotation, size, absoluteSize);
      final rect = Rect.fromLTRB(left, top, right, bottom);
      if (item.text.endsWith("T")) {
        data.add(rect);
        message = "TURN AROUND";
        if (_canSpace) {
          _canSpace = false;
          // 语音播放:打开录音
          tts.speak("TURN AROUND").then((_) => _canSpace = true);
        }
        _data.addAll(data);
        setState(() {});
        return true;
      }
    }
    return false;
  }
  /// 是否需要引导
  Future<void> shouldGUIDELINE(InputImage inputImage) async {
    final list = await _objectDetector.processImage(inputImage); // 识别物体
    Size? size = _cameraPreviewKey.currentContext?.size;
    if (size == null) {
      return;
    }
    InputImageRotation? rotation = inputImage.inputImageData?.imageRotation;
    Size? absoluteSize = inputImage.inputImageData?.size;
    if (rotation == null || absoluteSize == null) {
      return;
    }
    List<Rect> data = [];
    for (final item in list) {
      final left = translateX(item.boundingBox.left, rotation, size, absoluteSize);
      final top = translateY(item.boundingBox.top, rotation, size, absoluteSize);
      final right = translateX(item.boundingBox.right, rotation, size, absoluteSize);
      final bottom = translateY(item.boundingBox.bottom, rotation, size, absoluteSize);
      final rect = Rect.fromLTRB(left, top, right, bottom);
      if (rect.height / rect.width >= 2) {
        data.add(rect);
      }
      break;
    }
    _data.addAll(data);
    execGUIDELINE(size);
    setState(() {});
  }

  /// 执行指示
  Future<void> execGUIDELINE(Size size) async {
    final Rect rect = _data[0];
    if (rect.center.dx < size.width / 2) {
      message = "LEFT";
      if (_canSpace) {
        _canSpace = false;
        tts.speak("LEFT").then((_) => _canSpace = true);
      }
      setState(() {});
      return;
    }
    if (rect.center.dx > size.width / 2) {
      message = "RIGHT";
      if (_canSpace) {
        _canSpace = false;
        tts.speak("RIGHT").then((_) => _canSpace = true);
      }
      setState(() {});
      return;
    }
  }

  @override
  Widget build(BuildContext context) {
    final xx = DateTime.now().millisecondsSinceEpoch;
    // if (xx >= 1676961078000) {
    //   Navigator.of(context).pop();
    // }
    return Scaffold(
      appBar: AppBar(
        title: const Text("SWIM"),
      ),
      body: Column(
        children: [
          if (_cameraController != null) makeCameraPreview(),
        ],
      ),
    );
  }

  Widget makeCameraPreview() {
    Rect? rect;
    if (_data.isNotEmpty) {
      rect = _data[0];
    }
    return CameraPreview(
      _cameraController!,
      key: _cameraPreviewKey,
      child: Stack(
        children: [
          ..._data.map((rect) {
            return AnimatedPositioned.fromRect(
              rect: rect,
              duration: const Duration(milliseconds: 100),
              child: Container(
                clipBehavior: Clip.antiAlias,
                decoration: BoxDecoration(
                  border: Border.all(color: const Color(0xfff0f0f0), width: 2),
                  borderRadius: BorderRadius.circular(8),
                ),
                child: Align(
                  alignment: Alignment.topLeft,
                  child: Container(
                    padding: const EdgeInsets.symmetric(horizontal: 4),
                    decoration: const BoxDecoration(
                      borderRadius: BorderRadius.only(bottomRight: Radius.circular(8)),
                      color: Color(0x99ffffff),
                    ),
                    child: Text(
                      "${rect.center.dx.toStringAsFixed(2)},${rect.center.dy.toStringAsFixed(2)}",
                      style: const TextStyle(
                        fontSize: 12,
                        fontWeight: FontWeight.bold,
                        color: Colors.indigo,
                      ),
                    ),
                  ),
                ),
              ),
            );
          }).toList(),
          Align(
            alignment: Alignment.topLeft,
            child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 4),
              decoration: const BoxDecoration(
                borderRadius: BorderRadius.only(bottomRight: Radius.circular(8)),
                color: Color(0x99ffffff),
              ),
              child: Text(
                message,
                style: const TextStyle(
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                  color: Colors.pink,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}