package mk.ukim.finki.it.reservengo.model.domain;

import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import mk.ukim.finki.it.reservengo.config.listeners.Auditable;
import mk.ukim.finki.it.reservengo.model.enumerations.Service;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

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


@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "local_")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Local extends Auditable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String description;

    private String address;

    private String workingHours;

    @Enumerated(EnumType.STRING)
    @ElementCollection
    private List<Service> availableServices;

    @ElementCollection
    @MapKeyColumn(name = "customer_id")
    private Map<Long, Integer> ratings;

    @OneToMany(mappedBy = "local", cascade = CascadeType.ALL)
    private List<Event> events;

    @ElementCollection
    private List<String> localPhotos;

    private String menuPhoto;

    private String menuLink;

    @Embedded
    private Contact contact;

    @OneToMany(mappedBy = "local", cascade = CascadeType.ALL)
    private List<Reservation> reservations;

    @OneToMany(mappedBy = "local")
    private List<LocalWorker> workers;

    private String logoUrl;

    public Local(String name, String description, String address, String workingHours, List<Service> availableServices, Map<Long, Integer> ratings, List<Event> events, String logoUrl, List<String> localPhotos, String menuPhoto, String menuLink, Contact contact, List<Reservation> reservations, List<LocalWorker> workers) {
        this.name = name;
        this.description = description;
        this.address = address;
        this.workingHours = workingHours;
        this.availableServices = availableServices;
        this.ratings = ratings;
        this.events = events;
        this.logoUrl = logoUrl;
        this.localPhotos = localPhotos;
        this.menuPhoto = menuPhoto;
        this.menuLink = menuLink;
        this.contact = contact;
        this.reservations = reservations;
        this.workers = workers;
    }

    public Local(String name) {
        this.name = name;
    }

    public double getAverageRating() {
        if (ratings == null || ratings.isEmpty()) {
            return 0;
        }

        return ratings.values().stream()
                .mapToInt(Integer::intValue)
                .average()
                .orElse(0.0);
    }
}