import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:krow_domain/krow_domain.dart' as domain;

import '../../domain/repositories/certificates_repository.dart';

/// Implementation of [CertificatesRepository] using Data Connect.
///
/// This class handles the communication with the backend via [DataConnectService].
/// It maps raw generated data types to clean [domain.StaffDocument] entities.
class CertificatesRepositoryImpl
    implements CertificatesRepository {
  /// The Data Connect service instance.
  final DataConnectService _service;

  /// Creates a [CertificatesRepositoryImpl].
  CertificatesRepositoryImpl() : _service = DataConnectService.instance;

  @override
  Future<List<domain.StaffDocument>> getCertificates() async {
    return _service.run(() async {
      final String staffId = await _service.getStaffId();

      // Execute the query via DataConnect generated SDK
      final result =
          await _service.connector
              .listStaffDocumentsByStaffId(staffId: staffId)
              .execute();

      // Map the generated SDK types to pure Domain entities
      return result.data.staffDocuments
          .map((ListStaffDocumentsByStaffIdStaffDocuments doc) =>
              _mapToDomain(doc))
          .toList();
    });
  }

  /// Maps the Data Connect [ListStaffDocumentsByStaffIdStaffDocuments] to a domain [domain.StaffDocument].
  domain.StaffDocument _mapToDomain(
    ListStaffDocumentsByStaffIdStaffDocuments doc,
  ) {
    return domain.StaffDocument(
      id: doc.id,
      staffId: doc.staffId,
      documentId: doc.documentId,
      name: doc.document.name,
      description: null, // Description not available in this query response
      status: _mapStatus(doc.status),
      documentUrl: doc.documentUrl,
      expiryDate: doc.expiryDate == null
          ? null
          : DateTimeUtils.toDeviceTime(doc.expiryDate!.toDateTime()),
    );
  }

  /// Maps the Data Connect [DocumentStatus] enum to the domain [domain.DocumentStatus].
  domain.DocumentStatus _mapStatus(EnumValue<DocumentStatus> status) {
    if (status is Known<DocumentStatus>) {
      switch (status.value) {
        case DocumentStatus.VERIFIED:
          return domain.DocumentStatus.verified;
        case DocumentStatus.PENDING:
          return domain.DocumentStatus.pending;
        case DocumentStatus.MISSING:
          return domain.DocumentStatus.missing;
        case DocumentStatus.UPLOADED:
          return domain.DocumentStatus.pending;
        case DocumentStatus.EXPIRING:
          // 'EXPIRING' in backend is treated as 'verified' in domain, 
          // as the document is strictly valid until the expiry date.
          return domain.DocumentStatus.verified;
      }
    }
    // Fallback for unknown status
    return domain.DocumentStatus.pending;
  }
}
