package de.cannamanage.service;

import de.cannamanage.domain.enums.NotificationType;
import de.cannamanage.domain.enums.RsvpStatus;
import de.cannamanage.service.repository.ClubEventRepository;
import de.cannamanage.service.repository.EventRsvpRepository;
import de.cannamanage.service.repository.MemberRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * Scheduler that sends event reminders ~24h before an event starts.
 * Runs every hour, finds events in the 24-25h window, sends notifications to ACCEPTED/MAYBE attendees.
 */
@Service
public class EventReminderScheduler {

    private static final Logger log = LoggerFactory.getLogger(EventReminderScheduler.class);

    private final ClubEventRepository eventRepository;
    private final EventRsvpRepository rsvpRepository;
    private final MemberRepository memberRepository;
    private final NotificationService notificationService;

    public EventReminderScheduler(ClubEventRepository eventRepository,
                                  EventRsvpRepository rsvpRepository,
                                  MemberRepository memberRepository,
                                  NotificationService notificationService) {
        this.eventRepository = eventRepository;
        this.rsvpRepository = rsvpRepository;
        this.memberRepository = memberRepository;
        this.notificationService = notificationService;
    }

    @Scheduled(fixedRate = 3600000) // Every hour
    @Transactional
    public void sendUpcomingEventReminders() {
        var now = Instant.now();
        var in24h = now.plus(24, ChronoUnit.HOURS);
        var in25h = now.plus(25, ChronoUnit.HOURS);

        var upcomingEvents = eventRepository.findByStartAtBetweenAndReminderSentFalse(in24h, in25h);

        for (var event : upcomingEvents) {
            var attendees = rsvpRepository.findByEventIdAndStatusIn(
                    event.getId(), List.of(RsvpStatus.ACCEPTED, RsvpStatus.MAYBE));

            for (var rsvp : attendees) {
                var member = memberRepository.findById(rsvp.getMemberId());
                member.ifPresent(m -> {
                    if (m.getUserId() != null) {
                        notificationService.sendNotification(
                                m.getUserId(),
                                NotificationType.EVENT_REMINDER,
                                "Erinnerung: " + event.getTitle(),
                                "Morgen um " + formatTime(event.getStartAt()) +
                                        (event.getLocation() != null ? " — " + event.getLocation() : ""),
                                "/portal/events/" + event.getId()
                        );
                    }
                });
            }

            // Mark reminder as sent
            event.setReminderSent(true);
            eventRepository.save(event);
            log.info("Sent {} reminders for event '{}'", attendees.size(), event.getTitle());
        }
    }

    private String formatTime(Instant instant) {
        return DateTimeFormatter.ofPattern("HH:mm")
                .format(instant.atZone(ZoneId.of("Europe/Berlin")));
    }
}
