import 'package:firebase_data_connect/firebase_data_connect.dart' as fdc;
import 'package:intl/intl.dart';
import 'package:krow_data_connect/krow_data_connect.dart' as dc;
import 'package:krow_domain/krow_domain.dart';
// ignore: implementation_imports
import 'package:krow_domain/src/adapters/financial/time_card_adapter.dart';
import '../../domain/repositories/time_card_repository.dart';

/// Implementation of [TimeCardRepository] using Firebase Data Connect.
class TimeCardRepositoryImpl implements TimeCardRepository {
  final dc.DataConnectService _service;

  /// Creates a [TimeCardRepositoryImpl].
  TimeCardRepositoryImpl({dc.DataConnectService? service})
      : _service = service ?? dc.DataConnectService.instance;

  @override
  Future<List<TimeCard>> getTimeCards(DateTime month) async {
    return _service.run(() async {
      final String staffId = await _service.getStaffId();
      // Fetch applications. Limit can be adjusted, assuming 100 is safe for now.
      final fdc.QueryResult<dc.GetApplicationsByStaffIdData,
              dc.GetApplicationsByStaffIdVariables> result =
          await _service.connector
              .getApplicationsByStaffId(staffId: staffId)
              .limit(100)
              .execute();

      return result.data.applications
          .where((dc.GetApplicationsByStaffIdApplications app) {
            final DateTime? shiftDate = _service.toDateTime(app.shift.date);
            if (shiftDate == null) return false;
            return shiftDate.year == month.year &&
                shiftDate.month == month.month;
          })
          .map((dc.GetApplicationsByStaffIdApplications app) {
            final DateTime shiftDate = _service.toDateTime(app.shift.date)!;
            final String startTime = _formatTime(app.checkInTime) ??
                _formatTime(app.shift.startTime) ??
                '';
            final String endTime = _formatTime(app.checkOutTime) ??
                _formatTime(app.shift.endTime) ??
                '';

            // Prefer shiftRole values for pay/hours
            final double hours = app.shiftRole.hours ?? 0.0;
            final double rate = app.shiftRole.role.costPerHour;
            final double pay = app.shiftRole.totalValue ?? 0.0;

            return TimeCardAdapter.fromPrimitives(
              id: app.id,
              shiftTitle: app.shift.title,
              clientName: app.shift.order.business.businessName,
              date: shiftDate,
              startTime: startTime,
              endTime: endTime,
              totalHours: hours,
              hourlyRate: rate,
              totalPay: pay,
              status: app.status.stringValue,
              location: app.shift.location,
            );
          })
          .toList();
    });
  }

  String? _formatTime(fdc.Timestamp? timestamp) {
    if (timestamp == null) return null;
    final DateTime? dt = _service.toDateTime(timestamp);
    if (dt == null) return null;
    return DateFormat('HH:mm').format(dt);
  }
}
