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

import 'package:chat/data/constants.dart';
import 'package:chat/generated/i18n.dart';
import 'package:chat/photo/ui/dialog/not_permission_dialog.dart';
import 'package:chat/utils/screen.dart';
import 'package:chat/utils/sound_util.dart';
import 'package:flutter/material.dart';
import 'package:flutter_audio_recorder/flutter_audio_recorder.dart';
import 'package:oktoast/oktoast.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'package:permission_handler/permission_handler.dart';

const int soundSizeLimit = 61;
const double RecorderRadius = 30;

class RecordView extends StatefulWidget {
  final double keyboardHeight;
  final Function sendMsg;

  RecordView({this.keyboardHeight, this.sendMsg});
  @override
  _RecordViewState createState() => _RecordViewState();
}

class _RecordViewState extends State<RecordView> {
  Timer counter;
  int totalCount = 0;
  bool _isRecording = false;
  Timer recordTimer;
  FlutterAudioRecorder recorder;

  bool isCancelState = false;
  bool _isCounting = false;

  bool hasPermission = false; //录音权限
  bool isTaped = false;

  @override
  void initState() {
    super.initState();
  }

  void hide() {
    counter.cancel();
    counter = null;
  }

  @override
  void deactivate() {
    super.deactivate();

    cancelRecorder();
  }

  @override
  void dispose() {
    print('record view dispose');
    anchorKey = null;
    counter?.cancel();
    super.dispose();
  }

  _timeCounter() {
    if (!_isCounting) {
      return Container(
        height: 40,
      );
    }
    int h = totalCount ~/ 3600;
    int m = (totalCount % 3600) ~/ 60;
    int s = totalCount % 60;

    var hStr = h >= 10 ? h.toString() : '0' + h.toString();
    var mStr = m >= 10 ? h.toString() : '0' + m.toString();
    var sStr = s >= 10 ? s.toString() : '0' + s.toString();
    return Container(
        height: 40,
        alignment: Alignment.center,
        child: Text('$hStr:$mStr:$sStr',
            textScaleFactor: 1.0,
            style: TextStyle(color: Colors.black, fontSize: 30)));
  }

  _startTimer() {
    totalCount = 0;
    _isCounting = true;
    setState(() {});
    counter?.cancel();
    counter = Timer.periodic(Duration(seconds: 1), (Timer timer) {
      totalCount += 1;
      setState(() {});
    });
  }

  _stopTimer() {
    _isCounting = false;
    if (mounted) {
      setState(() {});
    }

    counter?.cancel();
  }

  askRecordPermission() async {
    final PermissionStatus statusFirst = await PermissionHandler()
        .checkPermissionStatus(PermissionGroup.microphone);

    print('录音权限 $statusFirst');

    final PermissionStatus storageStatus = await PermissionHandler()
        .checkPermissionStatus(PermissionGroup.storage);

    print('storage权限 $storageStatus');
    if (statusFirst == PermissionStatus.granted &&
        storageStatus == PermissionStatus.granted) {
      hasPermission = true;
    } else {

      cancelRecorder();
      if(statusFirst == PermissionStatus.unknown || (statusFirst == PermissionStatus.denied && Platform.isAndroid)){
        Map<PermissionGroup, PermissionStatus> permissionRequestResult =
        await PermissionHandler().requestPermissions(
            [PermissionGroup.microphone, PermissionGroup.storage]);
        var status = permissionRequestResult[PermissionGroup.microphone];
        var storageStatus = permissionRequestResult[PermissionGroup.storage];
        if (status == PermissionStatus.granted &&
            storageStatus == PermissionStatus.granted) {
          hasPermission = true;
        }

      }else{
        
        var result = await showDialog(
          context: context,
          builder: (ctx) => NotPermissionDialog(I18n.of(context).video_permission),
        );
        if (result == true) {
          PermissionHandler().openAppSettings();
        }
      }
    }
  }

  double tempX;
  double tempY;
  GlobalKey anchorKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    var tipStr;
    if (_isRecording) {
      if (isCancelState) {
        tipStr = I18n.of(context).cancel;
      } else {
        tipStr = I18n.of(context).voice_tips2;
      }
    } else {
      tipStr = I18n.of(context).voice_tips;
    }

    return Container(
        width: double.infinity,
        height: double.infinity,
        padding: EdgeInsets.only(top: 10, bottom: 20),
        color: Colors.white,
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _timeCounter(),
            Expanded(
                child: GestureDetector(
                  child: Container(
                    key: anchorKey,
                    width: 100,
                    height: 100,
                    child: Icon(
                        IconData(0xe64f, fontFamily: Constants.IconFontFamily),
                        color: isTaped ? Colors.white : Color(0xFF018DFE),
                        size: 64),
                    decoration: BoxDecoration(
                        color: isTaped ? Color(0xFF018DFE) : Colors.white,
                        shape: BoxShape.circle,
                        border: Border.all(color: Color(0xFF60919F)),
                        boxShadow: [
                          BoxShadow(
                            color: Color(0xFFD0D0D0), //阴影颜色
                            blurRadius: 5.0, //阴影大小
                          ),
                        ]),
                  ),
                  onTap: () {
                    //只是短暂按压,取消发送
                    print('onTap');
                    cancelRecorder();
                  },
                  onTapUp: (TapUpDetails details) {
                    print('onTapUp');
                    isTaped = false;
                    setState(() {});
                  },
                  onTapDown: (TapDownDetails details) {
                    print('onTapDown');
                    isTaped = true;
                    setState(() {});
                    if (!hasPermission) {
                      askRecordPermission();
                    }
                    RenderBox renderBox =
                    anchorKey.currentContext.findRenderObject();
                    var offset = renderBox.localToGlobal(Offset(
                        renderBox.size.width / 2, renderBox.size.height / 2));
                    tempX = offset.dx;
                    tempY = offset.dy;
                  },
                  onLongPressStart: (LongPressStartDetails details) {
                    print('onLongPressStart');
                    if (hasPermission) {
                      if (!_isRecording) {
                        startRecorder(context);
                      }
                    }else
                    {
                       cancelRecorder();
                    }
                  },
                  onLongPressEnd: (LongPressEndDetails details) {
                    print('onLongPressEnd');
                    isTaped = false;
                    setState(() {});
                    if (checkValideArea(details.globalPosition)) {
                      print('在范围内');
                      stopRecorder();
                    } else {
                      print('不在范围内');
                      cancelRecorder();
                    }
                  },
                  onLongPressMoveUpdate: (LongPressMoveUpdateDetails details) {
                    if (!checkValideArea(details.globalPosition)) {
                      if (!isCancelState) {
                        setState(() {
                          isCancelState = true;
                        });
                      }
                    } else {
                      if (isCancelState) {
                        setState(() {
                          isCancelState = false;
                        });
                      }
                    }
                  },
                )),
            SizedBox(height: 10),
            Container(
              height: 40,
              alignment: Alignment.center,
              child: Text(tipStr, textScaleFactor: 1.0,),
            )
          ],
        ));
  }

  checkValideArea(Offset position) {
    double offset = RecorderRadius * Screen.scale;

    return (position.dx - tempX).abs() <= offset &&
        (position.dy - tempY).abs() <= offset;
  }

  void startRecorder(BuildContext context) async {
    if (!hasPermission) {
      return;
    }

    SoundUtils().stop();
    try {
      var directory = await getTemporaryDirectory();
      var curTime = DateTime.now().millisecondsSinceEpoch;
      var path = p.join(directory.path, 'record$curTime.wav');

      recorder = FlutterAudioRecorder(path,
          audioFormat: AudioFormat.WAV,
          sampleRate: 16000); // or AudioFormat.WAV
      await recorder.initialized;

      await recorder.start();
      print('######开始录音');
      _startTimer();
      //60分钟后如果还在录，自动停止

      recordTimer = Timer(Duration(seconds: soundSizeLimit), () {
        stopRecorder();
      });

      this.setState(() {
        this._isRecording = true;
      });
    } catch (err) {
      print('startRecorder error: $err');
    }
  }

  void cancelRecorder() async {
    recordTimer?.cancel();
    isTaped = false;
    await recorder?.stop();
    _isRecording = false;
    _stopTimer();
  }

  void stopRecorder() async {
    if (!hasPermission || !_isRecording) {
      return;
    }

    try {
      var recording = await recorder.stop();

      this._isRecording = false;

      var filePath = recording.path;
      var time = recording.duration.inMilliseconds;
      print("Stop recording: $filePath  time : $time");

      recordTimer?.cancel();
      _stopTimer();

      _sendSound(filePath, time);

      this.setState(() {});
    } catch (err) {

      print('stopRecorder error: $err');
    }
  }

  _sendSound(soundPath, int duration) async {
    var fileData = File(soundPath).readAsBytesSync();

    print('fileData size  ${fileData.length}');
    if (duration < 1000) {
      //小于1秒
      showToast(I18n.of(context).time_little);
      return;
    } else {

      print('发送音频文件${DateTime.now()}');
      widget.sendMsg(soundPath,duration);
    }
  }
}
