import 'package:dio/dio.dart';
import '../../../../core/error/exceptions.dart';
import '../../domain/repositories/auth_repository.dart';
import '../datasources/auth_remote_datasource.dart';
import '../datasources/auth_local_datasource.dart';
import '../models/user_model.dart';

class AuthRepositoryImpl implements AuthRepository {
  final AuthRemoteDatasource remote;
  final AuthLocalDatasource local;

  AuthRepositoryImpl({required this.remote, required this.local});

  @override
  Future<UserModel> login(String email, String password) async {
    try {
      final result = await remote.login(email, password);
      await local.saveToken(result.token);
      return result.user;
    } on DioException catch (e) {
      throw _unwrap(e);
    }
  }

  @override
  Future<UserModel> register(
      String username, String email, String password) async {
    try {
      final result = await remote.register(username, email, password);
      await local.saveToken(result.token);
      return result.user;
    } on DioException catch (e) {
      throw _unwrap(e);
    }
  }

  @override
  Future<UserModel?> checkAuth() async {
    final hasToken = await local.hasToken();
    if (!hasToken) return null;

    try {
      return await remote.getMe();
    } on DioException catch (_) {
      await local.clearToken();
      return null;
    } catch (_) {
      await local.clearToken();
      return null;
    }
  }

  @override
  Future<void> logout() async {
    await remote.logout();
    await local.clearToken();
  }

  Exception _unwrap(DioException e) {
    final error = e.error;
    if (error is AuthException) return error;
    if (error is ConflictException) return error;
    if (error is NetworkException) return error;
    if (error is ServerException) return error;
    return ServerException(e.message ?? 'An unknown error occurred');
  }
}