import '../../domain/models/attendance_login_request.dart';
import '../../domain/models/attendance_logout_request.dart';
import '../../domain/models/attendance_response_model.dart';
import '../../domain/models/attendance_model.dart';
import '../../domain/models/overtime_model.dart';
import '../../domain/models/extra_payment_model.dart';
import '../../domain/models/salary_model.dart';
import '../../domain/repositories/attendance_repository.dart';
import '../datasources/attendance_remote_data_source.dart';

class AttendanceRepositoryImpl implements AttendanceRepository {
  final AttendanceRemoteDataSource remoteDataSource;

  AttendanceRepositoryImpl({required this.remoteDataSource});

  @override
  Future<AttendanceResponseModel> login(AttendanceLoginRequest request) async {
    final dto = await remoteDataSource.login(
      employeeId: request.employeeId,
      faceImage: request.faceImage,
    );

    return AttendanceResponseModel(
      id: dto.id,
      employeeId: dto.employeeId,
      login: dto.login,
    );
  }

  @override
  Future<AttendanceResponseModel> logout(
    AttendanceLogoutRequest request,
  ) async {
    final dto = await remoteDataSource.logout(
      employeeId: request.employeeId,
      faceImage: request.faceImage,
    );

    return AttendanceResponseModel(
      id: dto.id,
      employeeId: dto.employeeId,
      logout: dto.logout,
    );
  }

  @override
  Future<List<AttendanceModel>> getAttendanceRecords({
    required String employeeId,
  }) async {
    final dtos = await remoteDataSource.getAttendanceRecords(
      employeeId: employeeId,
    );

    return dtos.map((dto) {
      int? hours;
      if (dto.login != null && dto.logout != null) {
        hours = dto.logout!.difference(dto.login!).inHours;
      }

      return AttendanceModel(
        id: dto.id,
        employeeId: dto.employeeId,
        date: dto.createdAt ?? dto.login,
        loginTime: dto.login,
        logoutTime: dto.logout,
        workHours: hours,
        createdAt: dto.createdAt ?? dto.login,
        reason: dto.reason,
        isDeleted: dto.isDeleted,
      );
    }).toList();
  }

  @override
  Future<List<OvertimeModel>> getExtraHours({
    required String employeeId,
  }) async {
    final dtos = await remoteDataSource.getExtraHours(employeeId: employeeId);

    return dtos
        .map(
          (dto) => OvertimeModel(
            id: dto.id,
            employeeId: dto.employeeId,
            date: dto.date,
            hours: dto.hours,
            hourlyRateAtTheTime: dto.hourlyRateAtTheTime,
            totalAmount: dto.hours * dto.hourlyRateAtTheTime,
          ),
        )
        .toList();
  }

  @override
  Future<List<ExtraPaymentModel>> getRewards({
    required String employeeId,
  }) async {
    final dtos = await remoteDataSource.getRewards(employeeId: employeeId);

    return dtos
        .map(
          (dto) => ExtraPaymentModel(
            id: dto.id,
            employeeId: dto.employeeId,
            date: dto.date,
            amount: dto.amount,
            reason: dto.reason,
            note: dto.note,
            isPenalty: false,
          ),
        )
        .toList();
  }

  @override
  Future<List<ExtraPaymentModel>> getPunishments({
    required String employeeId,
  }) async {
    final dtos = await remoteDataSource.getPunishments(employeeId: employeeId);

    return dtos
        .map(
          (dto) => ExtraPaymentModel(
            id: dto.id,
            employeeId: dto.employeeId,
            date: dto.date,
            amount: dto.amount,
            reason: dto.reason,
            note: dto.note,
            isPenalty: true,
          ),
        )
        .toList();
  }

  @override
  Future<SalaryModel> calculateSalary({
    required String employeeId,
    required int month,
    required int year,
  }) async {
    final dto = await remoteDataSource.calculateSalary(
      employeeId: employeeId,
      month: month,
      year: year,
    );

    return SalaryModel(netAmount: dto.data?.netAmount ?? 0.0);
  }
}
