import 'package:intl/intl.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart';
import 'package:staff_home/src/domain/repositories/home_repository.dart';

class HomeRepositoryImpl
    implements HomeRepository {
  HomeRepositoryImpl() : _service = DataConnectService.instance;

  final DataConnectService _service;

  @override
  Future<List<Shift>> getTodayShifts() async {
    return _getShiftsForDate(DateTime.now());
  }

  @override
  Future<List<Shift>> getTomorrowShifts() async {
    return _getShiftsForDate(DateTime.now().add(const Duration(days: 1)));
  }

  Future<List<Shift>> _getShiftsForDate(DateTime date) async {
    return _service.run(() async {
      final staffId = await _service.getStaffId();

      // Create start and end timestamps for the target date
      final DateTime start = DateTime(date.year, date.month, date.day);
      final DateTime end =
          DateTime(date.year, date.month, date.day, 23, 59, 59, 999);

      final response = await _service.run(() => _service.connector
          .getApplicationsByStaffId(staffId: staffId)
          .dayStart(_service.toTimestamp(start))
          .dayEnd(_service.toTimestamp(end))
          .execute());

      // Filter for CONFIRMED applications (same logic as shifts_repository_impl)
      final apps = response.data.applications.where((app) =>
          (app.status is Known &&
              (app.status as Known).value == ApplicationStatus.CONFIRMED));

      final List<Shift> shifts = [];
      for (final app in apps) {
        shifts.add(_mapApplicationToShift(app));
      }

      return shifts;
    });
  }

  @override
  Future<List<Shift>> getRecommendedShifts() async {
    // Logic: List ALL open shifts (simple recommendation engine)
    // Limitation: listShifts might return ALL shifts. We should ideally filter by status=PUBLISHED.
    return _service.run(() async {
      final response =
          await _service.run(() => _service.connector.listShifts().execute());

      return response.data.shifts
          .where((s) {
            final isOpen = s.status is Known &&
                (s.status as Known).value == ShiftStatus.OPEN;
            if (!isOpen) return false;

            final start = _service.toDateTime(s.startTime);
            if (start == null) return false;

            return start.isAfter(DateTime.now());
          })
          .take(10)
          .map((s) => _mapConnectorShiftToDomain(s))
          .toList();
    });
  }

  @override
  Future<String?> getStaffName() async {
    final session = StaffSessionStore.instance.session;
    return session?.staff?.name;
  }

  // Mappers specific to Home's Domain Entity 'Shift'
  // Note: Home's 'Shift' entity might differ slightly from 'StaffPayment' Shift.

  Shift _mapApplicationToShift(GetApplicationsByStaffIdApplications app) {
    final s = app.shift;
    final r = app.shiftRole;

    return ShiftAdapter.fromApplicationData(
      shiftId: s.id,
      roleId: r.roleId,
      roleName: r.role.name,
      businessName: s.order.business.businessName,
      companyLogoUrl: s.order.business.companyLogoUrl,
      costPerHour: r.role.costPerHour,
      shiftLocation: s.location,
      teamHubName: s.order.teamHub.hubName,
      shiftDate: _service.toDateTime(s.date),
      startTime: _service.toDateTime(r.startTime),
      endTime: _service.toDateTime(r.endTime),
      createdAt: _service.toDateTime(app.createdAt),
      status: 'confirmed',
      description: s.description,
      durationDays: s.durationDays,
      count: r.count,
      assigned: r.assigned,
      eventName: s.order.eventName,
      hasApplied: true,
    );
  }

  Shift _mapConnectorShiftToDomain(ListShiftsShifts s) {
    return Shift(
      id: s.id,
      title: s.title,
      clientName: s.order.business.businessName,
      hourlyRate: s.cost ?? 0.0,
      location: s.location ?? 'Unknown',
      locationAddress: s.locationAddress ?? '',
      date: _service.toDateTime(s.date)?.toIso8601String() ?? '',
      startTime: DateFormat('HH:mm')
          .format(_service.toDateTime(s.startTime) ?? DateTime.now()),
      endTime: DateFormat('HH:mm')
          .format(_service.toDateTime(s.endTime) ?? DateTime.now()),
      createdDate: _service.toDateTime(s.createdAt)?.toIso8601String() ?? '',
      tipsAvailable: false,
      mealProvided: false,
      managers: [],
      description: s.description,
    );
  }
}
