import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import '../capturer/index.dart';
import '../channel.dart';
import '../client_getter_mixin.dart';

class TrtcRemoteMergedViewSub extends StatefulWidget {
  final TrtcPlayChannel channel;
  final bool isNeedScaleY;
  const TrtcRemoteMergedViewSub(this.channel,
      {super.key, this.isNeedScaleY = false});

  @override
  State<TrtcRemoteMergedViewSub> createState() =>
      _TrtcRemoteMergedViewSubState();
}

class _TrtcRemoteMergedViewSubState extends State<TrtcRemoteMergedViewSub>
    with TrtcClientGetterMixin {
  bool isPlaying = false;
  int _textureId = 0;
  int _mainViewId = -1;
  int _subViewId = -1;

  @override
  void initState() {
    widget.channel.playStateChanged.addListener(_onPlayingChanged);
    widget.channel.onTextureIdChanged.addListener(_onTextureIdChanged);
    widget.channel.onViewIdChanged.addListener(_onViewIdChanged);
    _textureId = widget.channel.textureId;
    super.initState();
  }

  @override
  void dispose() {
    widget.channel.playStateChanged.removeListener(_onPlayingChanged);
    widget.channel.onTextureIdChanged.removeListener(_onTextureIdChanged);
    widget.channel.onViewIdChanged.removeListener(_onViewIdChanged);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (_, constraints) {
      return kIsWeb ? _buildSubViewInWeb() : Texture(textureId: _textureId);
    });
  }

  void _onPlayingChanged(Object _, bool e) {
    if (mounted) {
      setState(() {
        isPlaying = e;
      });
    }
  }

  void _onTextureIdChanged(Object _, int newTextureId) {
    if (mounted) {
      setState(() {
        _textureId = newTextureId;
      });
    } else {
      _textureId = newTextureId;
    }
  }

  /// 当主画面ViewId变化时，通知子画面更新
  void _onViewIdChanged(Object _, int newMainViewId) {
    _mainViewId = newMainViewId;
    _copyMainViewToSubView();
  }

  void _copyMainViewToSubView() {
    _mainViewId = widget.channel.viewId;
    if (_subViewId == -1 || _mainViewId == -1) {
      return;
    }

    WebTrtcUtil.copyMainViewToSubView(
        _mainViewId.toString(), _subViewId.toString());

    if (widget.isNeedScaleY) {
      /// 用于对老版合图方式进行拉伸兼容
      WebTrtcUtil.setTRTCPlatformViewScaleY(_subViewId.toString(), 3);
    }
  }

  Widget _buildSubViewInWeb() {
    return PlatformViewLink(
      viewType: 'trtcCloudChannelView',
      surfaceFactory:
          (BuildContext context, PlatformViewController controller) {
        return PlatformViewSurface(
          controller: controller,
          hitTestBehavior: PlatformViewHitTestBehavior.transparent,
          gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
        );
      },
      onCreatePlatformView: (PlatformViewCreationParams params) {
        final controller =
            _HtmlElementViewController(params.id, params.viewType);
        controller._initialize().then((_) {
          params.onPlatformViewCreated(params.id);
          _subViewId = params.id;
          _copyMainViewToSubView();
        });
        return controller;
      },
    );
  }
}

class _HtmlElementViewController extends PlatformViewController
    with WidgetsBindingObserver {
  _HtmlElementViewController(
    this.viewId,
    this.viewType,
  );

  @override
  final int viewId;

  /// The unique identifier for the HTML view type to be embedded by this widget.
  ///
  /// A PlatformViewFactory for this type must have been registered.
  final String viewType;

  bool _initialized = false;

  Future<void> _initialize() async {
    final args = <String, dynamic>{
      'id': viewId,
      'viewType': viewType,
    };
    await SystemChannels.platform_views.invokeMethod<void>('create', args);
    _initialized = true;
  }

  @override
  Future<void> clearFocus() async {
    // Currently this does nothing on Flutter Web.
    // Implement this. See https://github.com/flutter/flutter/issues/39496
  }

  @override
  Future<void> dispatchPointerEvent(PointerEvent event) async {
    // We do not dispatch pointer events to HTML views because they may contain
    // cross-origin iframes, which only accept user-generated events.
  }

  @override
  Future<void> dispose() async {
    if (_initialized) {
      await SystemChannels.platform_views.invokeMethod<void>('dispose', viewId);
    }
  }
}
