import 'package:firebase_auth/firebase_auth.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:yumi/app/routes/sc_routes.dart';
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
import 'package:yumi/shared/tools/sc_google_auth_utils.dart';
import 'package:yumi/shared/tools/sc_loading_manager.dart';
import 'package:yumi/shared/tools/sc_version_utils.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
import 'package:yumi/ui_kit/components/sc_tts.dart';
import 'package:provider/provider.dart';
import 'package:yumi/services/audio/rtc_manager.dart';
import 'package:yumi/services/audio/rtm_manager.dart';

import '../../shared/data_sources/models/enum/sc_auth_type.dart';

class SocialChatAuthenticationManager extends ChangeNotifier {
  String authType = "";
  String uid = "";
  User? _user;

  User? get user => _user;

  bool get isSignedIn => _user != null;

  SocialChatAuthenticationManager() {
    _initializeAuthentication();
  }

  Future<void> _initializeAuthentication() async {
    await SCGoogleAuthService.initialize();
    await _verifyExistingSession();
  }

  Future<void> _verifyExistingSession() async {
    final user = await SCGoogleAuthService.signInSilently();
    _user = user;
    notifyListeners();
  }

  Future<void> authenticateUser(BuildContext context, String authType) async {
    if (authType == SCAuthType.GOOGLE.name) {
      this.authType = authType;
      try {
        _user ??= await SCGoogleAuthService.signInWithGoogle();
        if (_user == null) {
          return;
        }
        uid = _user!.uid;
        SCLoadingManager.show();
        if (uid.isNotEmpty) {
          final res = await Future.wait([
            SCAccountRepository().loginForChannel(authType, uid),
            SCVersionUtils.checkReview(),
          ]);
          var user = (res[0] as SocialChatLoginRes);
          if (!context.mounted) {
            return;
          }
          await Provider.of<RtcProvider>(
            context,
            listen: false,
          ).resetLocalRoomState(
            fallbackRtmProvider: Provider.of<RtmProvider>(
              context,
              listen: false,
            ),
          );
          if (!context.mounted) {
            return;
          }
          AccountStorage().setCurrentUser(user);
          SCLoadingManager.hide();
          notifyListeners();
          SCNavigatorUtils.push(context, SCRoutes.home, replace: true);
        }
      } catch (e) {
        SCLoadingManager.hide();
        _showAuthError(e);
      }
    } else if (authType == SCAuthType.APPLE.name) {
      this.authType = authType;
      try {
        final appleCredential = await SignInWithApple.getAppleIDCredential(
          scopes: [
            AppleIDAuthorizationScopes.fullName, // 请求姓名权限
          ],
        );
        uid = appleCredential.userIdentifier ?? "";
        SCLoadingManager.show();
        if (uid.isNotEmpty) {
          final res = await Future.wait([
            SCAccountRepository().loginForChannel(authType, uid),
            SCVersionUtils.checkReview(),
          ]);
          var user = (res[0] as SocialChatLoginRes);
          if (!context.mounted) {
            return;
          }
          await Provider.of<RtcProvider>(
            context,
            listen: false,
          ).resetLocalRoomState(
            fallbackRtmProvider: Provider.of<RtmProvider>(
              context,
              listen: false,
            ),
          );
          if (!context.mounted) {
            return;
          }
          AccountStorage().setCurrentUser(user);
          SCLoadingManager.hide();
          notifyListeners();
          SCNavigatorUtils.push(context, SCRoutes.home, replace: true);
        }
      } catch (e) {
        SCLoadingManager.hide();
        _showAuthError(e);
      }
    }
  }

  Future<void> logoutUser() async {
    await SCGoogleAuthService.signOut();
    _user = null;
    notifyListeners();
  }

  void _showAuthError(Object error) {
    debugPrint("authenticateUser error: $error");

    if (error is DioException) {
      return;
    }

    final message = error.toString().replaceFirst("Exception: ", "").trim();
    if (message.isNotEmpty) {
      SCTts.show(message);
    }
  }
}
