import 'dart:collection';

import 'package:daniulive/controllers/publish_controller.dart';
import 'package:daniulive/entities/publish_profile.dart';
import 'package:fis_common/env/env.dart';
import 'package:fis_lib_media_rt/base/index.dart';
import 'package:fis_lib_media_rt/implementations/nt_rtmp/members.dart';
import 'package:fis_lib_media_rt/implementations/nt_rtmp/shell_api.dart';
import 'package:fis_lib_media_rt/interface/publisher.dart';
import 'package:fis_lib_media_rt/interface/channel.dart';
import 'package:flutter/foundation.dart';

import 'channel/channel.dart';
import 'native_share.dart';
import 'room.dart';

class NTPublisher extends BasePublisher {
  late final NTRtmpRoom _rtmpRoom;
  bool _hasInit = false;
  PublisherProfile? _profile;

  NTPublisher({required super.room}) {
    _rtmpRoom = room as NTRtmpRoom;
    _buildPreviewChannel();
  }

  NTPublishChannel? get _channel =>
      room.localMember.channels.first as NTPublishChannel;

  @override
  UnmodifiableListView<IPublishChannel> get channels => UnmodifiableListView(
      room.localMember.channels.map((e) => e as IPublishChannel));

  @override
  Future<void> setProfile(PublisherProfile profile) async {
    _profile = profile;
    await _init();

    //TODO: make local channel ready
    (channels.first as NTPublishChannel).viewId = 10010;
  }

  @override
  Future<void> startLocal() async {
    await _init();

    if (kIsWeb) {
      if (!FPlatform.isPureWeb) {
        await ShellApi.startRtmpPublish();
      }
    } else {
      await NTNativeShare.instance.startLocal();
    }
    _channel!.isPreviewing = true;
  }

  @override
  Future<void> stopLocal() async {
    if (!_hasInit) return;

    if (kIsWeb) {
      if (!FPlatform.isPureWeb) {
        await ShellApi.stopRtmpPublish();
      }
    } else {
      await NTNativeShare.instance.stopLocal();
    }
    _channel!.isPreviewing = false;
    _hasInit = false;
  }

  void _buildPreviewChannel() {
    if (channels.isEmpty) {
      final channel = NTPublishChannel(member: room.localMember);
      room.localMember.addChannel(channel);
    }
  }

  Future<void> _init() async {
    if (_hasInit) return;

    final member = _rtmpRoom.localMember as NTLocalMember;
    final pushUrl = member.memberInfo.liveInfo?.pushUrl;

    if (pushUrl == null || pushUrl.isEmpty) {
      throw ArgumentError.notNull("Publish url of Local member");
    }

    if (kIsWeb) {
      if (FPlatform.isPureWeb) {
        await Future.delayed(const Duration(milliseconds: 100));
      } else {
        await ShellApi.initRtmpPublisher(
          RtmpPublishProfile(
            url: pushUrl,
            frameRate: _profile!.frameRate,
            cameraName: _profile!.idealCameraName,
            microphoneName: _profile!.idealMicrophoneName,
          ),
        );
      }
    } else {
      await NTNativeShare.instance.initLocal(PublishProfile(url: pushUrl));
      NTNativeShare.publishController = PublishController(pushUrl);
    }

    _hasInit = true;
  }
}
