package de.assecutor.votianlt.repository;

import de.assecutor.votianlt.model.Job;
import de.assecutor.votianlt.model.JobStatus;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface JobRepository extends MongoRepository<Job, ObjectId> {

    /**
     * Findet einen Auftrag anhand der Auftragsnummer
     */
    Optional<Job> findByJobNumber(String jobNumber);

    /**
     * Findet alle Aufträge eines bestimmten Status
     */
    List<Job> findByStatus(JobStatus status);

    /**
     * Findet alle Aufträge, die von einem bestimmten Benutzer erstellt wurden
     */
    List<Job> findByCreatedBy(String createdBy);

    /**
     * Findet alle Aufträge in einem bestimmten Zeitraum
     */
    List<Job> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

    /**
     * Findet alle Aufträge mit einer bestimmten Abholstadt
     */
    List<Job> findByPickupCity(String pickupCity);

    /**
     * Findet alle Aufträge mit einer bestimmten Lieferstadt
     */
    List<Job> findByDeliveryCity(String deliveryCity);

    /**
     * Findet alle Aufträge mit digitaler Abwicklung
     */
    List<Job> findByDigitalProcessingTrue();

    /**
     * Zählt Aufträge nach Status
     */
    long countByStatus(JobStatus status);

    /**
     * Findet die neuesten Aufträge (sortiert nach Erstellungsdatum)
     */
    @Query(value = "{}", sort = "{ 'created_at' : -1 }")
    List<Job> findLatestJobs();

    /**
     * Findet Aufträge anhand einer Kundenauswahl
     */
    List<Job> findByCustomerSelection(String customerSelection);

    /**
     * Findet Aufträge anhand einer Kundenauswahl (case-insensitive)
     */
    @Query("{ 'customerSelection': { $regex: ?0, $options: 'i' } }")
    List<Job> findByCustomerSelectionIgnoreCase(String customerSelection);

    /**
     * Prüft, ob eine Auftragsnummer bereits existiert
     */
    boolean existsByJobNumber(String jobNumber);

    /**
     * Findet alle Entwürfe eines Benutzers
     */
    List<Job> findByCreatedByAndIsDraftTrue(String createdBy);

    /**
     * Findet alle finalen Aufträge (keine Entwürfe)
     */
    List<Job> findByIsDraftFalse();

    /**
     * Zählt alle Entwürfe
     */
    long countByIsDraftTrue();

    /**
     * Findet alle nicht abgeschlossenen Aufträge, die einem bestimmten App-Nutzer
     * zugewiesen sind. Excludes jobs with status COMPLETED or CANCELLED. Uses
     * explicit query because @Field("app_user") annotation is not always respected
     * by Spring Data MongoDB query derivation.
     */
    @Query("{'app_user': ?0, 'status': {'$nin': ['COMPLETED', 'CANCELLED']}}")
    List<Job> findByAppUser(String appUser);

    @Query("{'delivery_stations.station_id': ?0}")
    Optional<Job> findByDeliveryStationsStationId(ObjectId stationId);

    /**
     * Findet Aufträge anhand einer partiellen Auftragsnummer (case-insensitive)
     */
    @Query("{'jobNumber': {'$regex': ?0, '$options': 'i'}}")
    List<Job> findByJobNumberContainingIgnoreCase(String jobNumber);

    /**
     * Erweiterte Suche: Zeitraum, Auftragsnummer und Status kombiniert
     */
    @Query("{'createdAt': {'$gte': ?0, '$lte': ?1}, " + "'jobNumber': {'$regex': ?2, '$options': 'i'}, "
            + "'status': {'$in': ?3}}")
    List<Job> findWithFilters(LocalDateTime startDate, LocalDateTime endDate, String jobNumberPattern,
            List<JobStatus> statusList);

    /**
     * Erweiterte Suche mit Benutzerfilter: Zeitraum, Auftragsnummer, Status und
     * Ersteller
     */
    @Query("{'created_by': ?0, 'createdAt': {'$gte': ?1, '$lte': ?2}, "
            + "'jobNumber': {'$regex': ?3, '$options': 'i'}, " + "'status': {'$in': ?4}}")
    List<Job> findWithFiltersByCreatedBy(String createdBy, LocalDateTime startDate, LocalDateTime endDate,
            String jobNumberPattern, List<JobStatus> statusList);
}
