package com.social.media.infrastructure.persistence.bot.entity;

import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * JPA Entity for Bot aggregate persistence
 */
@Entity
@Table(name = "bots")
public class BotEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    
    @Column(name = "company_id", nullable = false)
    private Long companyId;
    
    @Column(name = "created_by", nullable = false)
    private Long createdBy;
    
    @Column(name = "name", length = 100, nullable = false)
    private String name;
    
    @Column(name = "description", length = 500)
    private String description;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "bot_type", nullable = false, columnDefinition = "automation.bot_type")
    private BotTypeEntity botType;
    
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, columnDefinition = "automation.bot_status")
    private BotStatusEntity status;
    
    // Configuration settings as JSON
    @ElementCollection
    @CollectionTable(name = "bot_configuration_settings", joinColumns = @JoinColumn(name = "bot_id"))
    @MapKeyColumn(name = "setting_key")
    @Column(name = "setting_value", columnDefinition = "TEXT")
    private Map<String, String> configurationSettings = new HashMap<>();
    
    @Column(name = "max_actions_per_hour")
    private Integer maxActionsPerHour;
    
    @Column(name = "max_actions_per_day")
    private Integer maxActionsPerDay;
    
    @Column(name = "start_time")
    private LocalTime startTime;
    
    @Column(name = "end_time")
    private LocalTime endTime;
    
    @ElementCollection
    @CollectionTable(name = "bot_target_hashtags", joinColumns = @JoinColumn(name = "bot_id"))
    @Column(name = "hashtag")
    private Set<String> targetHashtags = new HashSet<>();
    
    @ElementCollection
    @CollectionTable(name = "bot_exclude_keywords", joinColumns = @JoinColumn(name = "bot_id"))
    @Column(name = "keyword")
    private Set<String> excludeKeywords = new HashSet<>();
    
    @Column(name = "respect_rate_limits")
    private Boolean respectRateLimits;
    
    @Column(name = "delay_between_actions")
    private Integer delayBetweenActions;
    
    // Target relationships
    @ElementCollection
    @CollectionTable(name = "bot_target_social_accounts", joinColumns = @JoinColumn(name = "bot_id"))
    @Column(name = "social_account_id")
    private Set<Long> targetSocialAccountIds = new HashSet<>();
    
    @ElementCollection
    @CollectionTable(name = "bot_target_user_lists", joinColumns = @JoinColumn(name = "bot_id"))
    @Column(name = "user_list_id")
    private Set<Long> targetUserListIds = new HashSet<>();
    
    // Execution tracking
    @Column(name = "total_executions")
    private Integer totalExecutions = 0;
    
    @Column(name = "successful_executions")
    private Integer successfulExecutions = 0;
    
    @Column(name = "failed_executions")
    private Integer failedExecutions = 0;
    
    @Column(name = "last_execution_at")
    private LocalDateTime lastExecutionAt;
    
    @Column(name = "next_execution_at")
    private LocalDateTime nextExecutionAt;
    
    // Scheduling
    @Column(name = "scheduled")
    private Boolean scheduled = false;
    
    @Column(name = "schedule_enabled")
    private Boolean scheduleEnabled = false;
    
    @Column(name = "cron_expression")
    private String cronExpression;
    
    // Audit fields
    @Column(name = "created_at", nullable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;
    
    @Version
    private Long version;
    
    // Default constructor for JPA
    public BotEntity() {}
    
    // Getters and Setters
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }
    
    public Long getCompanyId() {
        return companyId;
    }
    
    public void setCompanyId(Long companyId) {
        this.companyId = companyId;
    }
    
    public Long getCreatedBy() {
        return createdBy;
    }
    
    public void setCreatedBy(Long createdBy) {
        this.createdBy = createdBy;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public BotTypeEntity getBotType() {
        return botType;
    }
    
    public void setBotType(BotTypeEntity botType) {
        this.botType = botType;
    }
    
    public BotStatusEntity getStatus() {
        return status;
    }
    
    public void setStatus(BotStatusEntity status) {
        this.status = status;
    }
    
    public Map<String, String> getConfigurationSettings() {
        return configurationSettings;
    }
    
    public void setConfigurationSettings(Map<String, String> configurationSettings) {
        this.configurationSettings = configurationSettings != null ? configurationSettings : new HashMap<>();
    }
    
    public Integer getMaxActionsPerHour() {
        return maxActionsPerHour;
    }
    
    public void setMaxActionsPerHour(Integer maxActionsPerHour) {
        this.maxActionsPerHour = maxActionsPerHour;
    }
    
    public Integer getMaxActionsPerDay() {
        return maxActionsPerDay;
    }
    
    public void setMaxActionsPerDay(Integer maxActionsPerDay) {
        this.maxActionsPerDay = maxActionsPerDay;
    }
    
    public LocalTime getStartTime() {
        return startTime;
    }
    
    public void setStartTime(LocalTime startTime) {
        this.startTime = startTime;
    }
    
    public LocalTime getEndTime() {
        return endTime;
    }
    
    public void setEndTime(LocalTime endTime) {
        this.endTime = endTime;
    }
    
    public Set<String> getTargetHashtags() {
        return targetHashtags;
    }
    
    public void setTargetHashtags(Set<String> targetHashtags) {
        this.targetHashtags = targetHashtags != null ? targetHashtags : new HashSet<>();
    }
    
    public Set<String> getExcludeKeywords() {
        return excludeKeywords;
    }
    
    public void setExcludeKeywords(Set<String> excludeKeywords) {
        this.excludeKeywords = excludeKeywords != null ? excludeKeywords : new HashSet<>();
    }
    
    public Boolean getRespectRateLimits() {
        return respectRateLimits;
    }
    
    public void setRespectRateLimits(Boolean respectRateLimits) {
        this.respectRateLimits = respectRateLimits;
    }
    
    public Integer getDelayBetweenActions() {
        return delayBetweenActions;
    }
    
    public void setDelayBetweenActions(Integer delayBetweenActions) {
        this.delayBetweenActions = delayBetweenActions;
    }
    
    public Set<Long> getTargetSocialAccountIds() {
        return targetSocialAccountIds;
    }
    
    public void setTargetSocialAccountIds(Set<Long> targetSocialAccountIds) {
        this.targetSocialAccountIds = targetSocialAccountIds != null ? targetSocialAccountIds : new HashSet<>();
    }
    
    public Set<Long> getTargetUserListIds() {
        return targetUserListIds;
    }
    
    public void setTargetUserListIds(Set<Long> targetUserListIds) {
        this.targetUserListIds = targetUserListIds != null ? targetUserListIds : new HashSet<>();
    }
    
    public Integer getTotalExecutions() {
        return totalExecutions;
    }
    
    public void setTotalExecutions(Integer totalExecutions) {
        this.totalExecutions = totalExecutions;
    }
    
    public Integer getSuccessfulExecutions() {
        return successfulExecutions;
    }
    
    public void setSuccessfulExecutions(Integer successfulExecutions) {
        this.successfulExecutions = successfulExecutions;
    }
    
    public Integer getFailedExecutions() {
        return failedExecutions;
    }
    
    public void setFailedExecutions(Integer failedExecutions) {
        this.failedExecutions = failedExecutions;
    }
    
    public LocalDateTime getLastExecutionAt() {
        return lastExecutionAt;
    }
    
    public void setLastExecutionAt(LocalDateTime lastExecutionAt) {
        this.lastExecutionAt = lastExecutionAt;
    }
    
    public LocalDateTime getNextExecutionAt() {
        return nextExecutionAt;
    }
    
    public void setNextExecutionAt(LocalDateTime nextExecutionAt) {
        this.nextExecutionAt = nextExecutionAt;
    }
    
    public Boolean getScheduled() {
        return scheduled;
    }
    
    public void setScheduled(Boolean scheduled) {
        this.scheduled = scheduled;
    }
    
    public Boolean getScheduleEnabled() {
        return scheduleEnabled;
    }
    
    public void setScheduleEnabled(Boolean scheduleEnabled) {
        this.scheduleEnabled = scheduleEnabled;
    }
    
    public String getCronExpression() {
        return cronExpression;
    }
    
    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }
    
    public LocalDateTime getCreatedAt() {
        return createdAt;
    }
    
    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
    
    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }
    
    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }
    
    public Long getVersion() {
        return version;
    }
    
    public void setVersion(Long version) {
        this.version = version;
    }
}
