import 'package:dartz/dartz.dart';
import '../../core/error/exceptions.dart';
import '../../core/error/failures.dart';
import '../datasources/auth_remote_data_source.dart';
import '../datasources/user_local_data_source.dart';
import '../dto/login_dto.dart';
import '../../domain/models/login_request.dart';
import '../../domain/models/login_response_model.dart';
import '../../domain/repositories/auth_repository.dart';

import '../dto/change_password_request_dto.dart';
import '../../domain/models/change_password_request.dart';
import '../../domain/models/general_response_model.dart';

class AuthRepositoryImpl implements AuthRepository {
  final AuthRemoteDataSource remoteDataSource;
  final UserLocalDataSource localDataSource;

  AuthRepositoryImpl({
    required this.remoteDataSource,
    required this.localDataSource,
  });

  @override
  Future<Either<Failure, LoginResponseModel>> login(
    LoginRequest request,
  ) async {
    try {
      final dto = LoginDto(
        phoneNumber: request.phoneNumber,
        password: request.password,
      );

      final responseDto = await remoteDataSource.login(dto);
      print("LOGIN RESPONSE DATA: ${responseDto.toJson()}"); // Debugging Log

      // Cache the token locally
      if (responseDto.data?.token != null) {
        await localDataSource.cacheUserToken(responseDto.data!.token!);
      }
      if (responseDto.data?.employeeId != null) {
        print("AUTH_REPO: Caching EmployeeId: ${responseDto.data!.employeeId}");
        await localDataSource.cacheEmployeeId(responseDto.data!.employeeId!);
      } else {
        print("AUTH_REPO: EmployeeId is NULL in response!");
      }

      // Convert DTO to Model
      final responseModel = LoginResponseModel(
        statusCode: responseDto.statusCode,
        isSuccess: responseDto.isSuccess,
        message: responseDto.message,
        data:
            responseDto.data != null
                ? LoginDataModel(
                  token: responseDto.data!.token,
                  id: responseDto.data!.id,
                  employeeId: responseDto.data!.employeeId,
                  username: responseDto.data!.username,
                  fullName: responseDto.data!.fullName,
                  role: responseDto.data!.role,
                  email: responseDto.data!.email,
                  phoneNumber: responseDto.data!.phoneNumber,
                  permissions: responseDto.data!.permissions,
                )
                : null,
      );

      return Right(responseModel);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure('خطأ غير متوقع: $e'));
    }
  }

  @override
  Future<Either<Failure, GeneralResponseModel>> changePassword(
    ChangePasswordRequest request,
  ) async {
    try {
      final dto = ChangePasswordRequestDto(
        oldPassword: request.oldPassword,
        newPassword: request.newPassword,
      );

      final responseDto = await remoteDataSource.changePassword(dto);

      // Re-cache token and employeeId if provided in response
      if (responseDto.data != null) {
        if (responseDto.data!.token != null) {
          await localDataSource.cacheUserToken(responseDto.data!.token!);
        }
        if (responseDto.data!.employeeId != null) {
          await localDataSource.cacheEmployeeId(responseDto.data!.employeeId!);
        }
      }

      final model = GeneralResponseModel(
        statusCode: responseDto.statusCode,
        isSuccess: responseDto.isSuccess,
        message: responseDto.message,
        data:
            responseDto
                .isSuccess, // Use isSuccess as data for the boolean model
      );

      return Right(model);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException catch (e) {
      return Left(NetworkFailure(e.message));
    } catch (e) {
      return Left(ServerFailure('خطأ غير متوقع: $e'));
    }
  }
}
