import 'dart:async';

import 'package:diplomaticquarterapp/pages/conference/web_rtc/widgets/cam_view_widget.dart';
import 'package:diplomaticquarterapp/pages/conference/widgets/noise_box.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webrtc/flutter_webrtc.dart';

import '../conference_button_bar.dart';

class CallHomePage extends StatefulWidget {
  @override
  _CallHomePageState createState() => _CallHomePageState();
}

class _CallHomePageState extends State<CallHomePage> {
  bool showNoise = false;
  RTCVideoRenderer _localRenderer = RTCVideoRenderer();
  RTCVideoRenderer _remoteRenderer = RTCVideoRenderer();

  final StreamController<bool> _audioButton = StreamController<bool>.broadcast();
  final StreamController<bool> _videoButton = StreamController<bool>.broadcast();
  final StreamController<bool> _onButtonBarVisibleStreamController = StreamController<bool>.broadcast();
  final StreamController<double> _onButtonBarHeightStreamController = StreamController<double>.broadcast();

  //Stream to enable video
  MediaStream stream;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _localRenderer.initialize();
    _remoteRenderer.initialize();

    enableVideo();
  }

  enableVideo() async {
    //Stream to enable video
    stream = await navigator.mediaDevices.getUserMedia({'video': true, 'audio': true});
    // _audioButton.add(false);
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _localRenderer.dispose();
    _remoteRenderer.dispose();
    _audioButton.close();
    _videoButton.close();
    stream.dispose();
    _disposeStreamsAndSubscriptions();
  }

  Future<void> _disposeStreamsAndSubscriptions() async {
    if (_onButtonBarVisibleStreamController != null) await _onButtonBarVisibleStreamController.close();
    if (_onButtonBarHeightStreamController != null) await _onButtonBarHeightStreamController.close();
  }

  @override
  Widget build(BuildContext context) {
    // return WillPopScope(
    //   onWillPop: () async => false,
    //   child: Scaffold(
    //     backgroundColor: Colors.black,
    //     // body: ,
    //   ),
    // );

    return Scaffold(
      backgroundColor: Colors.white,
      body: showNoise ? _buildNoiseBox() : buildLayout(),
    );
  }

  LayoutBuilder buildLayout() {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        return Stack(
          children: [
            CamViewWidget(
              localRenderer: _localRenderer,
              remoteRenderer: _remoteRenderer,
              stream: stream,
              constraints: constraints,
              onButtonBarVisibleStreamController: _onButtonBarVisibleStreamController,
              onButtonBarHeightStreamController: _onButtonBarHeightStreamController,
            ),
            ConferenceButtonBar(
              audioEnabled: _audioButton.stream,
              videoEnabled: _videoButton.stream,
              onAudioEnabled: _onAudioEnable,
              onVideoEnabled: _onVideoEnabled,
              onSwitchCamera: _onSwitchCamera,
              onHangup: _onHangup,
              onPersonAdd: () {},
              onPersonRemove: () {},
              onHeight: _onHeightBar,
              onShow: _onShowBar,
              onHide: _onHideBar,
            ),
          ],
        );
      },
    );
  }

  NoiseBox _buildNoiseBox() {
    return NoiseBox(
      density: NoiseBoxDensity.xLow,
      backgroundColor: Colors.grey.shade900,
      child: Center(
        child: Container(
          color: Colors.black54,
          width: double.infinity,
          height: 40,
          child: Center(
            child: Text(
              'Waiting for another participant to connect to the call...',
              key: Key('text-wait'),
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.white),
            ),
          ),
        ),
      ),
    );
  }

  Function _onAudioEnable() {
    bool enabled = stream.getAudioTracks()[0].enabled;
    stream.getAudioTracks()[0].enabled = !enabled;
    _audioButton.add(!enabled);
  }

  Function _onVideoEnabled() {
    bool enabled = stream.getVideoTracks()[0].enabled;
    stream.getVideoTracks()[0].enabled = !enabled;
    _videoButton.add(!enabled);
  }

  Function _onSwitchCamera() {
    // stream.getAudioTracks()[0].enabled = false;
    // stream.getVideoTracks()[0].enabled = false;
    Helper.switchCamera(stream.getVideoTracks()[0]);
  }

  void _onShowBar() {
    setState(() {
      SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom, SystemUiOverlay.top]);
    });
    _onButtonBarVisibleStreamController.add(true);
  }

  void _onHeightBar(double height) {
    _onButtonBarHeightStreamController.add(height);
  }

  void _onHideBar() {
    setState(() {
      SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
    });
    _onButtonBarVisibleStreamController.add(false);
  }

  Future<void> _onHangup() async {
    print('onHangup');
    Navigator.of(context).pop();
  }
}
