import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart';
import 'package:intl/intl.dart';
import 'package:krow/core/application/clients/api/api_exception.dart';
import 'package:krow/core/application/di/injectable.dart';
import 'package:krow/core/data/models/event/event_model.dart';
import 'package:krow/core/entity/event_entity.dart';
import 'package:krow/core/entity/position_entity.dart';
import 'package:krow/core/entity/shift_entity.dart';
import 'package:krow/core/sevices/create_event_service/create_event_service_repository.dart';
import 'package:krow/core/sevices/create_event_service/data/models/create_event_input_model.dart';
import 'package:krow/core/sevices/create_event_service/data/models/create_event_shift_input_model.dart';
import 'package:krow/core/sevices/create_event_service/data/models/create_event_shift_position_input_model.dart';
import 'package:krow/features/events/domain/events_repository.dart';

@lazySingleton
class CreateEventService {
  EventsRepository? _eventsRepository;

  set eventsRepository(EventsRepository eventsRepository) {
    _eventsRepository = eventsRepository;
  }

  Future<String> createEventService(EventEntity entity) async {
    late CreateEventInputModel createEventInputModel;
    try {
      createEventInputModel = createInput(entity);
    } catch (e) {
      debugPrint('Create event model error: $e');
      throw DisplayableException('Field must be filled');
    }

    var id = await getIt<CreateEventServiceRepository>()
        .createEvent(createEventInputModel);

    _eventsRepository?.refreshEvents(EventStatus.draft);
    return id;
  }

  Future<bool> validateEventInfo(EventEntity entity) async {
    return true;
  }

  Future<bool> validateShiftInfo(ShiftEntity entity) async {
    return true;
  }

  Future<bool> validateShiftPositionInfo(PositionEntity entity) async {
    return true;
  }

  Future<void> deleteDraft(EventEntity entity) async {
    if (entity.id.isEmpty) {
      return;
    }
    await getIt<CreateEventServiceRepository>().deleteDraft(entity.id);
    _eventsRepository?.refreshEvents(EventStatus.draft);
  }

  Future<void> publishEvent(EventEntity entity) async {
    var id;
    if (entity.id.isEmpty) {
      id = await createEventService(entity);
    } else {
      await updateEvent(entity);
      id = entity.id;
    }

    try {
      if (entity.status == EventStatus.draft || entity.status == null) {
        await getIt<CreateEventServiceRepository>().publishEvent(id);
       await Future.delayed(const Duration(seconds: 1));

        _eventsRepository?.refreshEvents(EventStatus.draft);
        _eventsRepository?.refreshEvents(EventStatus.pending);
      }
    } catch (e) {
      rethrow;
    }
  }

  Future<void> updateEvent(EventEntity entity) async {
    await getIt<CreateEventServiceRepository>()
        .updateEvent(createInput(entity));
    _eventsRepository?.refreshEvents(entity.status ?? EventStatus.draft);
  }

  CreateEventInputModel createInput(EventEntity entity) {
    return CreateEventInputModel(
      id: entity.id.isEmpty ? null : entity.id,
      name: entity.name,
      date: DateFormat('yyyy-MM-dd').format(entity.startDate ?? DateTime.now()),
      hubId: entity.hub!.id,
      // contractId: entity.contractNumber,
      purchaseOrder: entity.poNumber,
      contractType: EventContractType.purchaseOrder,
      additionalInfo: entity.additionalInfo,
      tags: entity.tags?.map((e) => e.id).toList(),
      addons: entity.addons?.map((e) => e.id).toList(),
      shifts: entity.shifts?.indexed.map((e) {
        var (index, shiftState) = e;
        return CreateEventShiftInputModel(
            name: 'Shift #${index + 1}',
            address: shiftState.fullAddress!,
            contacts: shiftState.managers.map((e) => e.id).toList(),
            positions: shiftState.positions.map((roleEntity) {
              return CreateEventShiftPositionInputModel(
                businessSkillId: roleEntity.businessSkill!.id!,
                hubDepartmentId: roleEntity.department!.id,
                count: roleEntity.count!,
                startTime: DateFormat('HH:mm').format(roleEntity.startTime!),
                endTime: DateFormat('HH:mm').format(roleEntity.endTime!),
                rate: roleEntity.businessSkill!.skill!.price!,
                breakDuration: roleEntity.breakDuration!,
              );
            }).toList());
      }).toList(),
    );
  }
}
