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

extension TimestampExt on Timestamp {
  DateTime toDate() {
    return DateTimeUtils.toDeviceTime(toDateTime());
  }
}


class HomeRepositoryImpl implements HomeRepository {
  HomeRepositoryImpl();

  String get _currentStaffId {
    final session = StaffSessionStore.instance.session;
    if (session?.staff?.id == null) throw Exception('User not logged in');
    return session!.staff!.id;
  }

  @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 {
    try {
      final response = await ExampleConnector.instance
          .getApplicationsByStaffId(staffId: _currentStaffId)
          .execute();
      
      final targetYmd = DateFormat('yyyy-MM-dd').format(date);

      return response.data.applications
          .where((app) {
             final shiftDate = app.shift.date?.toDate(); 
             if (shiftDate == null) return false;
             
             final isDateMatch = DateFormat('yyyy-MM-dd').format(shiftDate) == targetYmd;
             final isAssigned = app.status is Known && (app.status as Known).value == ApplicationStatus.ACCEPTED;
             
             return isDateMatch && isAssigned;
          })
          .map((app) => _mapApplicationToShift(app))
          .toList();
    } catch (e) {
      return [];
    }
  }

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

      return response.data.shifts
          .where((s) => s.status is Known && (s.status as Known).value == ShiftStatus.OPEN) 
          .take(10)
          .map((s) => _mapConnectorShiftToDomain(s))
          .toList();
    } catch (e) {
      return [];
    }
  }

  // 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 Shift(
      id: s.id,
      title: r.role.name,
      clientName: s.order.business.businessName,
      hourlyRate: r.role.costPerHour,
      location: s.location ?? 'Unknown',
      locationAddress: s.location ?? '',
      date: s.date?.toDate().toIso8601String() ?? '',
      startTime: DateFormat('HH:mm').format(r.startTime?.toDate() ?? DateTime.now()),
      endTime: DateFormat('HH:mm').format(r.endTime?.toDate() ?? DateTime.now()),
      createdDate: app.createdAt?.toDate().toIso8601String() ?? '',
      tipsAvailable: false, // Not in API
      mealProvided: false, // Not in API
      managers: [], // Not in this query
      description: null,
    );
  }

  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: s.date?.toDate().toIso8601String() ?? '',
      startTime: DateFormat('HH:mm').format(s.startTime?.toDate() ?? DateTime.now()),
      endTime: DateFormat('HH:mm').format(s.endTime?.toDate() ?? DateTime.now()),
      createdDate: s.createdAt?.toDate().toIso8601String() ?? '',
      tipsAvailable: false,
      mealProvided: false,
      managers: [],
      description: s.description,
    );
  }
}

