package com.rit.ems.model;

import com.rit.ems.util.JsonConverter;
import jakarta.persistence.*;
import java.util.List;
import java.util.Map;

@Entity
@Table(name = "ems_events")
public class Event {
    @Id
    private Long id;

    private String title;
    
    @Column(columnDefinition = "TEXT")
    private String description;
    
    @Column(name = "start_date")
    private String startDate;
    
    @Column(name = "end_date")
    private String endDate;
    
    private String location;
    private String category;
    private String type;
    private String institution;
    private String department;

    @Convert(converter = JsonConverter.class)
    @Column(name = "academic_years", columnDefinition = "TEXT")
    private List<String> academicYears;

    private String status;
    
    @Column(name = "guest_name")
    private String guestName;
    
    @Column(name = "guest_social_profile")
    private String guestSocialProfile;

    @Convert(converter = JsonConverter.class)
    @Column(columnDefinition = "TEXT")
    private List<String> requirements;

    @Convert(converter = JsonConverter.class)
    @Column(name = "targeted_sections", columnDefinition = "TEXT")
    private List<String> targetedSections;

    @Convert(converter = JsonConverter.class)
    @Column(name = "target_departments", columnDefinition = "TEXT")
    private List<String> targetDepartments;

    @Column(name = "group_request_id")
    private String groupRequestId;

    @Convert(converter = JsonConverter.class)
    @Column(columnDefinition = "TEXT")
    private List<String> sponsors;

    private Double budget = 0.0;
    
    @Column(name = "has_registration_fee")
    private Boolean hasRegistrationFee = false;
    
    @Column(name = "registration_fee")
    private Double registrationFee = 0.0;
    
    @Column(name = "payment_link")
    private String paymentLink;
    
    @Column(name = "centre_name")
    private String centreName;
    
    @Column(name = "is_public_event")
    private Boolean isPublicEvent = false;
    
    @Column(columnDefinition = "TEXT")
    private String image;
    
    @Column(name = "targeted_batch")
    private String targetedBatch;
    
    @Column(name = "open_to_all")
    private Boolean openToAll = false;
    
    @Column(name = "max_participants")
    private Integer maxParticipants;

    @Column(name = "current_participants")
    private Integer currentParticipants = 0;

    @Embedded
    private ProposerInfo proposer;

    @Convert(converter = JsonConverter.class)
    @Column(name = "day_configs", columnDefinition = "TEXT")
    private List<Object> dayConfigs;

    @Convert(converter = JsonConverter.class)
    @Column(name = "dept_limits", columnDefinition = "TEXT")
    private Map<String, Object> deptLimits;

    @Convert(converter = JsonConverter.class)
    @Column(name = "dept_section_limits", columnDefinition = "TEXT")
    private Map<String, Object> deptSectionLimits;

    @Column(name = "refreshment_expense")
    private Double refreshmentExpense = 0.0;
    
    @Column(name = "transportation_expense")
    private Double transportationExpense = 0.0;
    
    @Column(name = "session_coverage_fee")
    private Double sessionCoverageFee = 0.0;
    
    @Column(name = "total_expense")
    private Double totalExpense = 0.0;
    
    @Column(name = "duration_days")
    private Integer durationDays = 1;

    @Column(name = "rejection_reason")
    private String rejectionReason;

    @Column(name = "conflict_message")
    private String conflictMessage;

    public Event() {}

    public Event(Long id, String title, String description, String startDate, String endDate, String location, String category, String type, String institution, String department, List<String> academicYears, String status, String guestName, String guestSocialProfile, List<String> requirements, List<String> targetedSections, List<String> targetDepartments, String groupRequestId, List<String> sponsors, Double budget, Boolean hasRegistrationFee, Double registrationFee, String paymentLink, String centreName, Boolean isPublicEvent, String image, String targetedBatch, Boolean openToAll, Integer maxParticipants, Integer currentParticipants, ProposerInfo proposer, List<Object> dayConfigs, Map<String, Object> deptLimits, Map<String, Object> deptSectionLimits, Double refreshmentExpense, Double transportationExpense, Double sessionCoverageFee, Double totalExpense, Integer durationDays, String rejectionReason, String conflictMessage) {
        this.id = id;
        this.title = title;
        this.description = description;
        this.startDate = startDate;
        this.endDate = endDate;
        this.location = location;
        this.category = category;
        this.type = type;
        this.institution = institution;
        this.department = department;
        this.academicYears = academicYears;
        this.status = status;
        this.guestName = guestName;
        this.guestSocialProfile = guestSocialProfile;
        this.requirements = requirements;
        this.targetedSections = targetedSections;
        this.targetDepartments = targetDepartments;
        this.groupRequestId = groupRequestId;
        this.sponsors = sponsors;
        this.budget = budget;
        this.hasRegistrationFee = hasRegistrationFee;
        this.registrationFee = registrationFee;
        this.paymentLink = paymentLink;
        this.centreName = centreName;
        this.isPublicEvent = isPublicEvent;
        this.image = image;
        this.targetedBatch = targetedBatch;
        this.openToAll = openToAll;
        this.maxParticipants = maxParticipants;
        this.currentParticipants = currentParticipants;
        this.proposer = proposer;
        this.dayConfigs = dayConfigs;
        this.deptLimits = deptLimits;
        this.deptSectionLimits = deptSectionLimits;
        this.refreshmentExpense = refreshmentExpense;
        this.transportationExpense = transportationExpense;
        this.sessionCoverageFee = sessionCoverageFee;
        this.totalExpense = totalExpense;
        this.durationDays = durationDays;
        this.rejectionReason = rejectionReason;
        this.conflictMessage = conflictMessage;
    }

    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }

    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }

    public String getStartDate() { return startDate; }
    public void setStartDate(String startDate) { this.startDate = startDate; }

    public String getEndDate() { return endDate; }
    public void setEndDate(String endDate) { this.endDate = endDate; }

    public String getLocation() { return location; }
    public void setLocation(String location) { this.location = location; }

    public String getCategory() { return category; }
    public void setCategory(String category) { this.category = category; }

    public String getType() { return type; }
    public void setType(String type) { this.type = type; }

    public String getInstitution() { return institution; }
    public void setInstitution(String institution) { this.institution = institution; }

    public String getDepartment() { return department; }
    public void setDepartment(String department) { this.department = department; }

    public List<String> getAcademicYears() { return academicYears; }
    public void setAcademicYears(List<String> academicYears) { this.academicYears = academicYears; }

    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }

    public String getGuestName() { return guestName; }
    public void setGuestName(String guestName) { this.guestName = guestName; }

    public String getGuestSocialProfile() { return guestSocialProfile; }
    public void setGuestSocialProfile(String guestSocialProfile) { this.guestSocialProfile = guestSocialProfile; }

    public List<String> getRequirements() { return requirements; }
    public void setRequirements(List<String> requirements) { this.requirements = requirements; }

    public List<String> getTargetedSections() { return targetedSections; }
    public void setTargetedSections(List<String> targetedSections) { this.targetedSections = targetedSections; }

    public List<String> getTargetDepartments() { return targetDepartments; }
    public void setTargetDepartments(List<String> targetDepartments) { this.targetDepartments = targetDepartments; }

    public String getGroupRequestId() { return groupRequestId; }
    public void setGroupRequestId(String groupRequestId) { this.groupRequestId = groupRequestId; }

    public List<String> getSponsors() { return sponsors; }
    public void setSponsors(List<String> sponsors) { this.sponsors = sponsors; }

    public Double getBudget() { return budget; }
    public void setBudget(Double budget) { this.budget = budget; }

    public Boolean getHasRegistrationFee() { return hasRegistrationFee; }
    public void setHasRegistrationFee(Boolean hasRegistrationFee) { this.hasRegistrationFee = hasRegistrationFee; }

    public Double getRegistrationFee() { return registrationFee; }
    public void setRegistrationFee(Double registrationFee) { this.registrationFee = registrationFee; }

    public String getPaymentLink() { return paymentLink; }
    public void setPaymentLink(String paymentLink) { this.paymentLink = paymentLink; }

    public String getCentreName() { return centreName; }
    public void setCentreName(String centreName) { this.centreName = centreName; }

    public Boolean getIsPublicEvent() { return isPublicEvent; }
    public void setIsPublicEvent(Boolean isPublicEvent) { this.isPublicEvent = isPublicEvent; }

    public String getImage() { return image; }
    public void setImage(String image) { this.image = image; }

    public String getTargetedBatch() { return targetedBatch; }
    public void setTargetedBatch(String targetedBatch) { this.targetedBatch = targetedBatch; }

    public Boolean getOpenToAll() { return openToAll; }
    public void setOpenToAll(Boolean openToAll) { this.openToAll = openToAll; }

    public Integer getMaxParticipants() { return maxParticipants; }
    public void setMaxParticipants(Integer maxParticipants) { this.maxParticipants = maxParticipants; }

    public Integer getCurrentParticipants() { return currentParticipants; }
    public void setCurrentParticipants(Integer currentParticipants) { this.currentParticipants = currentParticipants; }

    public ProposerInfo getProposer() { return proposer; }
    public void setProposer(ProposerInfo proposer) { this.proposer = proposer; }

    public List<Object> getDayConfigs() { return dayConfigs; }
    public void setDayConfigs(List<Object> dayConfigs) { this.dayConfigs = dayConfigs; }

    public Map<String, Object> getDeptLimits() { return deptLimits; }
    public void setDeptLimits(Map<String, Object> deptLimits) { this.deptLimits = deptLimits; }

    public Map<String, Object> getDeptSectionLimits() { return deptSectionLimits; }
    public void setDeptSectionLimits(Map<String, Object> deptSectionLimits) { this.deptSectionLimits = deptSectionLimits; }

    public Double getRefreshmentExpense() { return refreshmentExpense; }
    public void setRefreshmentExpense(Double refreshmentExpense) { this.refreshmentExpense = refreshmentExpense; }

    public Double getTransportationExpense() { return transportationExpense; }
    public void setTransportationExpense(Double transportationExpense) { this.transportationExpense = transportationExpense; }

    public Double getSessionCoverageFee() { return sessionCoverageFee; }
    public void setSessionCoverageFee(Double sessionCoverageFee) { this.sessionCoverageFee = sessionCoverageFee; }

    public Double getTotalExpense() { return totalExpense; }
    public void setTotalExpense(Double totalExpense) { this.totalExpense = totalExpense; }

    public Integer getDurationDays() { return durationDays; }
    public void setDurationDays(Integer durationDays) { this.durationDays = durationDays; }

    public String getRejectionReason() { return rejectionReason; }
    public void setRejectionReason(String rejectionReason) { this.rejectionReason = rejectionReason; }

    public String getConflictMessage() { return conflictMessage; }
    public void setConflictMessage(String conflictMessage) { this.conflictMessage = conflictMessage; }

    @Embeddable
    public static class ProposerInfo {
        @Column(name = "proposer_id")
        private Long id;
        
        @Column(name = "proposer_full_name")
        private String fullName;
        
        @Column(name = "proposer_email")
        private String email;
        
        @Column(name = "proposer_role")
        private String role;
        
        @Column(name = "proposer_department")
        private String department;

        public ProposerInfo() {}

        public ProposerInfo(Long id, String fullName, String email, String role, String department) {
            this.id = id;
            this.fullName = fullName;
            this.email = email;
            this.role = role;
            this.department = department;
        }

        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }

        public String getFullName() { return fullName; }
        public void setFullName(String fullName) { this.fullName = fullName; }

        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }

        public String getRole() { return role; }
        public void setRole(String role) { this.role = role; }

        public String getDepartment() { return department; }
        public void setDepartment(String department) { this.department = department; }
    }
}
