import 'package:injectable/injectable.dart';
import 'package:krow/features/earning/data/models/earning_model.dart';
import 'package:krow/features/earning/data/staff_earning_api_provider.dart';
import 'package:krow/features/earning/domain/entities/earning_shift_entity.dart';
import 'package:krow/features/earning/domain/entities/earnings_batch_entity.dart';
import 'package:krow/features/earning/domain/entities/earnings_summary_entity.dart';
import 'package:krow/features/earning/domain/staff_earning_repository.dart';

@Injectable(as: StaffEarningRepository)
class StaffEarningRepositoryImpl implements StaffEarningRepository {
  StaffEarningRepositoryImpl({
    required StaffEarningApiProvider apiProvider,
  }) : _apiProvider = apiProvider;

  final StaffEarningApiProvider _apiProvider;

  EarningShiftEntity _convertEarningModel(EarningModel data) {
    return EarningShiftEntity(
      id: data.id,
      status: EarningStatus.fromString(data.status),
      businessImageUrl: data.businessAvatar,
      skillName: data.businessSkill,
      businessName: data.businessName,
      totalBreakTime: data.breakIn != null
          ? data.breakOut?.difference(data.breakIn!).inSeconds
          : null,
      paymentStatus: 1,
      earned: data.amount,
      clockIn: data.clockInAt,
      clockOut: data.clockOutAt,
      eventName: data.eventName,
      eventDate: data.eventDate,
    );
  }

  @override
  Future<EarningsSummaryEntity> getStaffEarningsData() async {
    final data = await _apiProvider.fetchStaffEarningsSummary();

    return EarningsSummaryEntity(
      totalEarningsByWeek: data.totalEarningsByWeek,
      totalEarningsByMonth: data.totalEarningsByMonth,
      totalWorkedHoursByWeek: data.totalWorkedHoursByWeek,
      totalWorkedHoursByMonth: data.totalWorkedHoursByMonth,
      payoutByWeek: data.payoutByWeek,
      payoutByMonth: data.payoutByMonth,
      startDatePeriod: data.startDatePeriod,
      endDatePeriod: data.endDatePeriod,
      maxEarningInPeriod: data.maxEarningInPeriod,
      minEarningInPeriod: data.minEarningInPeriod,
    );
  }

  @override
  Future<EarningsBatchEntity> getEarningsBatch({
    required String status,
    int limit = 10,
    String? lastEntryCursor,
  }) async {
    final paginationInfo = await _apiProvider.fetchEarnings(
      status: status,
      limit: limit,
      cursor: lastEntryCursor,
    );

    return EarningsBatchEntity(
      batchStatus: status,
      hasNextBatch: paginationInfo.pageInfo?.hasNextPage??false,
      cursor: paginationInfo.pageInfo?.endCursor ??
          paginationInfo.edges.lastOrNull?.cursor,
      earnings: paginationInfo.edges.map(
        (edgeData) {
          return _convertEarningModel(edgeData.node);
        },
      ).toList(),
    );
  }

  @override
  Future<EarningShiftEntity?> confirmStaffEarning({
    required String earningId,
  }) async {
    final result = await _apiProvider.confirmPayment(id: earningId);

    if (result == null) return null;

    return _convertEarningModel(result);
  }

  @override
  Future<EarningShiftEntity?> disputeStaffEarning({
    required String id,
    required String reason,
    String? details,
  }) async {
    final result = await _apiProvider.declinePayment(
      id: id,
      reason: reason,
      details: details,
    );

    if (result == null) return null;

    return _convertEarningModel(result);
  }
}
