import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'session_service.dart';

/// Service for handling Firebase Authentication
class AuthService {
  static final FirebaseAuth _auth = FirebaseAuth.instance;
  static final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  /// Get current user
  static User? get currentUser {
    return _auth.currentUser;
  }

  /// Criar documento do usuário na Firestore após signup
  static Future<void> createUserRole(
    String uid,
    String role, {
    String? classId,
    String? schoolClassId,
    String? displayName,
  }) async {
    try {
      print('DEBUG: Criando documento users/$uid com role: $role');
      final Map<String, dynamic> data = {
        'role': role,
        'createdAt': FieldValue.serverTimestamp(),
      };
      if (classId != null && classId.isNotEmpty) {
        data['classId'] = classId;
      }
      if (schoolClassId != null && schoolClassId.isNotEmpty) {
        data['schoolClassId'] = schoolClassId;
      }
      if (displayName != null && displayName.isNotEmpty) {
        data['displayName'] = displayName;
      }
      await _firestore.collection('users').doc(uid).set(data);
      print('DEBUG: Documento criado com sucesso');
    } catch (e) {
      print('DEBUG: Erro ao criar documento: $e');
      throw Exception('Erro ao criar perfil do usuário');
    }
  }

  /// Criar inscrição do aluno na turma escolhida
  static Future<void> createEnrollment({
    required String studentId,
    required String classId,
    required String studentName,
  }) async {
    try {
      print(
        'DEBUG: Criando enrollment para student=$studentId, class=$classId',
      );
      final existing = await _firestore
          .collection('enrollments')
          .where('studentId', isEqualTo: studentId)
          .where('classId', isEqualTo: classId)
          .limit(1)
          .get();
      if (existing.docs.isNotEmpty) {
        print('DEBUG: Enrollment já existe, ignorando');
        return;
      }
      await _firestore.collection('enrollments').add({
        'classId': classId,
        'studentId': studentId,
        'studentName': studentName,
        'joinedAt': FieldValue.serverTimestamp(),
      });
      print('DEBUG: Enrollment criado com sucesso');
    } catch (e) {
      print('DEBUG: Erro ao criar enrollment: $e');
      throw Exception('Erro ao associar aluno à turma');
    }
  }

  /// Ler classId do aluno na Firestore
  static Future<String?> getStudentClassId(String uid) async {
    try {
      final doc = await _firestore.collection('users').doc(uid).get();
      if (doc.exists) {
        return doc.data()?['classId'] as String?;
      }
      return null;
    } catch (e) {
      print('DEBUG: Erro ao ler classId: $e');
      return null;
    }
  }

  /// Ler schoolClassId do aluno na Firestore (turma escolar definida no registo)
  static Future<String?> getStudentSchoolClassId(String uid) async {
    try {
      final doc = await _firestore.collection('users').doc(uid).get();
      if (doc.exists) {
        return doc.data()?['schoolClassId'] as String?;
      }
      return null;
    } catch (e) {
      print('DEBUG: Erro ao ler schoolClassId: $e');
      return null;
    }
  }

  /// Ler role do usuário na Firestore
  static Future<String?> getUserRole(String uid) async {
    try {
      print('DEBUG: Lendo documento users/$uid');
      final doc = await _firestore.collection('users').doc(uid).get();
      if (doc.exists) {
        final role = doc.data()?['role'] as String?;
        print('DEBUG: Role encontrado: $role');
        return role;
      }
      print('DEBUG: Documento não existe');
      return null;
    } catch (e) {
      print('DEBUG: Erro ao ler documento: $e');
      return null;
    }
  }

  /// Get auth state changes stream
  static Stream<User?> get authStateChanges {
    return _auth.authStateChanges();
  }

  /// Sign up with email and password
  static Future<UserCredential?> signUpWithEmailAndPassword({
    required String email,
    required String password,
    String? displayName,
    String? role,
    String? classId,
    String? schoolClassId,
  }) async {
    try {
      print('DEBUG: Tentando criar conta para email: $email');
      print('DEBUG: Password length: ${password.length}');

      UserCredential result = await _auth.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );

      print('DEBUG: Conta criada com sucesso para: ${result.user?.email}');
      print('DEBUG: User ID: ${result.user?.uid}');
      print('DEBUG: Email verified: ${result.user?.emailVerified}');

      // Update user profile with display name
      if (displayName != null && displayName.isNotEmpty) {
        await result.user?.updateDisplayName(displayName);
        print('DEBUG: Display name atualizado para: $displayName');
      }

      // Criar documento na Firestore com role (e classId se aluno)
      if (role != null && result.user != null) {
        await createUserRole(
          result.user!.uid,
          role,
          classId: classId,
          schoolClassId: schoolClassId,
          displayName: displayName,
        );
      }

      // Verificar se o email foi verificado
      if (result.user != null && !result.user!.emailVerified) {
        print('DEBUG: Email não verificado, tentando enviar verificação...');
        await result.user!.sendEmailVerification();
        print('DEBUG: Email de verificação enviado');
      }

      return result;
    } on FirebaseAuthException catch (e) {
      print('DEBUG: Erro Firebase ao criar conta: ${e.code} - ${e.message}');
      String errorMessage = _getErrorMessage(e.code);
      print('DEBUG: Mensagem de erro: $errorMessage');
      throw Exception(errorMessage);
    } catch (e) {
      print('DEBUG: Erro genérico ao criar conta: $e');
      throw Exception('Ocorreu um problema. Tente novamente');
    }
  }

  /// Sign in with email and password
  static Future<UserCredential?> signInWithEmailAndPassword({
    required String email,
    required String password,
  }) async {
    try {
      print('DEBUG: Tentando login para email: $email');
      print('DEBUG: Password length: ${password.length}');

      // Verificar se há usuário atual
      User? currentUser = _auth.currentUser;
      print('DEBUG: Usuário atual: ${currentUser?.email}');

      UserCredential result = await _auth.signInWithEmailAndPassword(
        email: email,
        password: password,
      );

      print('DEBUG: Login realizado com sucesso para: ${result.user?.email}');
      print('DEBUG: User ID: ${result.user?.uid}');
      print('DEBUG: Email verified: ${result.user?.emailVerified}');
      print('DEBUG: Display name: ${result.user?.displayName}');

      // Reload user data to ensure we have the latest information
      await result.user?.reload();
      print('DEBUG: User data reloaded');
      print('DEBUG: Display name after reload: ${result.user?.displayName}');

      return result;
    } on FirebaseAuthException catch (e) {
      print('DEBUG: Erro Firebase ao fazer login: ${e.code} - ${e.message}');
      String errorMessage = _getErrorMessage(e.code);
      print('DEBUG: Mensagem de erro: $errorMessage');
      throw Exception(errorMessage);
    } catch (e) {
      print('DEBUG: Erro genérico ao fazer login: $e');
      throw Exception('Ocorreu um problema. Tente novamente');
    }
  }

  /// Sign out
  static Future<void> signOut() async {
    try {
      print('DEBUG: Tentando fazer logout');
      await _auth.signOut();

      // Clear saved session
      await SessionService.clearSession();

      print('DEBUG: Logout e limpeza de sessão realizados com sucesso');
    } catch (e) {
      print('DEBUG: Erro ao fazer logout: $e');
    }
  }

  /// Attempt auto-login with saved credentials
  static Future<bool> attemptAutoLogin() async {
    try {
      final sessionData = await SessionService.shouldAutoLogin();

      if (sessionData['shouldAutoLogin'] == true) {
        final email = sessionData['email'];
        print('DEBUG: Attempting auto-login for: $email');

        // Note: For security reasons, we cannot auto-login without password
        // This method just checks if auto-login is available
        // The actual login still requires user to enter password
        return true;
      }

      return false;
    } catch (e) {
      print('DEBUG: Error in auto-login attempt: $e');
      return false;
    }
  }

  /// Get user-friendly error message
  static String _getErrorMessage(String code) {
    print('DEBUG: Processando código de erro: $code');

    switch (code) {
      case 'weak-password':
        return 'A palavra-passe é muito fraca. Use pelo menos 8 caracteres.';
      case 'invalid-email':
        return 'O email fornecido é inválido. Verifique o formato.';
      case 'user-disabled':
        return 'Esta conta foi desativada. Contacte o suporte.';
      case 'user-not-found':
        return 'Nenhum utilizador encontrado com este email. Verifique os dados.';
      case 'wrong-password':
        return 'Palavra-passe incorreta. Tente novamente.';
      case 'email-already-in-use':
        return 'O email inserido já se encontra registrado';
      case 'operation-not-allowed':
        return 'Operação não permitida. Tente novamente.';
      case 'invalid-credential':
        return 'Credenciais inválidos. Verifique email e palavra-passe.';
      case 'too-many-requests':
        return 'Muitas tentativas. Aguarde alguns minutos antes de tentar novamente.';
      case 'network-request-failed':
        return 'Falha de conexão. Verifique sua internet e tente novamente.';
      default:
        return 'Ocorreu um problema. Tente novamente';
    }
  }
}
