import 'package:flutter/foundation.dart';
import 'package:krow/features/shifts/data/models/cancellation_reason.dart';
import 'package:krow/features/shifts/data/models/event.dart';
import 'package:krow/features/shifts/data/models/event_tag.dart';
import 'package:krow/features/shifts/data/models/staff_shift.dart';

@immutable
class ShiftEntity {
  final String id;
  final String imageUrl;
  final String skillName;
  final String businessName;
  final DateTime assignedDate;
  final DateTime startDate;
  final DateTime endDate;
  final DateTime? clockIn;
  final DateTime? clockOut;
  final String locationName;
  final double locationLat;
  final double locationLon;
  final EventShiftRoleStaffStatus status;
  final String? rate;
  final List<EventTag>? tags;
  final StaffRating? rating;
  final int? planingBreakTime;
  final int? totalBreakTime;
  final int? paymentStatus;
  final int? canceledReason;
  final List<Addon>? additionalData;
  final List<ShiftManager> managers;
  final String? additionalInfo;
  final String? cursor;
  final CancellationReason? cancellationReason;
  final String eventId;
  final String eventName;

  const ShiftEntity({
    required this.id,
    required this.skillName,
    required this.businessName,
    required this.locationName,
    required this.locationLat,
    required this.locationLon,
    required this.status,
    required this.rate,
    required this.imageUrl,
    required this.assignedDate,
    required this.startDate,
    required this.endDate,
    required this.clockIn,
    required this.clockOut,
    required this.tags,
    required this.planingBreakTime,
    required this.totalBreakTime,
    required this.paymentStatus,
    required this.canceledReason,
    required this.additionalData,
    required this.managers,
    required this.rating,
    required this.additionalInfo,
    required this.eventId,
    required this.eventName,
    this.cancellationReason,
    this.cursor,
  });

  ShiftEntity copyWith({
    String? id,
    String? imageUrl,
    String? skillName,
    String? businessName,
    DateTime? assignedDate,
    DateTime? startDate,
    DateTime? endDate,
    DateTime? clockIn,
    DateTime? clockOut,
    String? locationName,
    double? locationLat,
    double? locationLon,
    EventShiftRoleStaffStatus? status,
    String? rate,
    List<EventTag>? tags,
    StaffRating? rating,
    int? planingBreakTime,
    int? totalBreakTime,
    int? paymentStatus,
    int? canceledReason,
    List<Addon>? additionalData,
    List<ShiftManager>? managers,
    String? additionalInfo,
    String? eventId,
    String? eventName,
    String? cursor,
  }) =>
      ShiftEntity(
        id: id ?? this.id,
        imageUrl: imageUrl ?? this.imageUrl,
        skillName: skillName ?? this.skillName,
        businessName: businessName ?? this.businessName,
        locationName: locationName ?? this.locationName,
        locationLat: locationLat ?? this.locationLat,
        locationLon: locationLon ?? this.locationLon,
        status: status ?? this.status,
        rate: rate ?? this.rate,
        assignedDate: assignedDate ?? this.assignedDate,
        startDate: startDate ?? this.startDate,
        endDate: endDate ?? this.endDate,
        clockIn: clockIn ?? this.clockIn,
        clockOut: clockOut ?? this.clockOut,
        tags: tags ?? this.tags,
        planingBreakTime: planingBreakTime ?? this.planingBreakTime,
        totalBreakTime: totalBreakTime ?? this.totalBreakTime,
        paymentStatus: paymentStatus ?? this.paymentStatus,
        canceledReason: canceledReason ?? this.canceledReason,
        additionalData: additionalData ?? this.additionalData,
        managers: managers ?? this.managers,
        rating: rating ?? this.rating,
        additionalInfo: additionalInfo ?? this.additionalInfo,
        cancellationReason: cancellationReason,
        eventId: eventId ?? this.eventId,
        eventName: eventName ?? this.eventName,
        cursor: cursor ?? this.cursor,
      );

  static ShiftEntity empty = ShiftEntity(
    id: '',
    skillName: '',
    businessName: '',
    locationName: '',
    locationLat: .0,
    locationLon: .0,
    status: EventShiftRoleStaffStatus.assigned,
    rate: '',
    imageUrl: '',
    assignedDate: DateTime.now(),
    clockIn: null,
    clockOut: null,
    startDate: DateTime.now(),
    endDate: DateTime.now(),
    tags: [],
    planingBreakTime: 0,
    totalBreakTime: 0,
    paymentStatus: 0,
    canceledReason: 0,
    rating: StaffRating(id: '0', rating: 0),
    additionalData: [],
    managers: [],
    eventId: '',
    eventName: '',
    additionalInfo: null,
  );

  static ShiftEntity fromStaffShift(
    StaffShift shift, {
    required String? cursor,
  }) {
    return ShiftEntity(
      id: shift.id,
      eventId: shift.position?.shift?.event?.id ?? '',
      eventName: shift.position?.shift?.event?.name ?? '',
      cursor: cursor,
      skillName: shift.position?.businessSkill?.skill?.name ?? '',
      businessName: shift.position?.shift?.event?.business?.name ?? '',
      locationName: shift.position?.shift?.fullAddress?.formattedAddress ?? '',
      locationLat: shift.position?.shift?.fullAddress?.latitude ?? 0,
      locationLon: shift.position?.shift?.fullAddress?.longitude ?? 0,
      status: shift.status,
      rate: shift.position?.rate?.toStringAsFixed(2) ?? '0',
      imageUrl: shift.position?.shift?.event?.business?.avatar ?? '',
      additionalInfo: shift.position?.shift?.event?.additionalInfo,
      assignedDate: shift.statusUpdatedAt ?? DateTime.now(),
      clockIn: shift.clockIn,
      clockOut: shift.clockOut,
      startDate: shift.startAt ?? DateTime.now(),
      endDate: shift.endAt ?? DateTime.now(),
      tags: shift.position?.shift?.event?.tags,
      planingBreakTime: shift.position?.breakMinutes ?? 0,
      totalBreakTime: shift.breakOut
              ?.difference(shift.breakIn ?? DateTime.now())
              .inMinutes ??
          0,
      paymentStatus: 0,
      canceledReason: 0,
      rating: shift.rating,
      cancellationReason: shift.cancelReason?.firstOrNull?.reason,
      additionalData: shift.position?.shift?.event?.addons ?? [],
      managers: [
        for (final contact in shift.position?.shift?.contacts ?? [])
          ShiftManager(
            id: contact.id,
            name: '${contact.firstName} ${contact.lastName}',
            imageUrl: contact.avatar ?? '',
            phoneNumber: contact.authInfo.phone,
          )
      ],
    );
  }
}

@immutable
class ShiftManager {
  final String id;
  final String name;
  final String imageUrl;
  final String phoneNumber;

  const ShiftManager({
    required this.id,
    required this.name,
    required this.imageUrl,
    required this.phoneNumber,
  });
}
