package com.social.media.infrastructure.persistence.entity;

import jakarta.persistence.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * JPA Entity for SocialAccount aggregate
 */
@Entity
@Table(name = "social_accounts", schema = "core_business")
public class SocialAccountEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;
    
    @Column(name = "account_code", length = 20)
    private String accountCode;
    
    @Column(name = "company_id", nullable = false)
    private Long companyId;
    
    @Column(name = "social_network_id", nullable = false)
    private Long socialNetworkId;
    
    @Column(name = "responsible_user_id")
    private Long responsibleUserId;
    
    // Account information
    @Column(name = "username", nullable = false, length = 100)
    private String username;
    
    @Column(name = "display_name", length = 255)
    private String displayName;
    
    @Column(name = "bio", columnDefinition = "TEXT")
    private String bio;
    
    @Column(name = "profile_photo_url", length = 1000)
    private String profilePhotoUrl;
    
    @Column(name = "profile_url", length = 1000)
    private String profileUrl;
    
    @Column(name = "verified", nullable = false)
    private Boolean verified = false;
    
    @Column(name = "is_private", nullable = false)
    private Boolean isPrivate = false;
    
    @Column(name = "category", length = 100)
    private String category;
    
    // Contact information
    @Column(name = "contact_phone", length = 20)
    private String contactPhone;
    
    @Column(name = "contact_email", length = 320)
    private String contactEmail;
    
    @Column(name = "location", length = 255)
    private String location;
    
    @Column(name = "website", length = 500)
    private String website;
    
    // Metrics as JSONB
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "metrics", columnDefinition = "jsonb")
    private Map<String, Object> metrics;
    
    // Tokens as JSONB
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "tokens", columnDefinition = "jsonb")
    private Map<String, Object> tokens;
    
    // Automation config as JSONB
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(name = "automation_config", columnDefinition = "jsonb")
    private Map<String, Object> automationConfig;
    
    // Connection status
    @Enumerated(EnumType.STRING)
    @Column(name = "connection_status", nullable = false, columnDefinition = "core_business.connection_status")
    private SocialAccountStatusEntity status;
    
    @Column(name = "last_sync_date")
    private LocalDateTime lastSyncDate;
    
    @Column(name = "next_sync_date")
    private LocalDateTime nextSyncDate;
    
    @Column(name = "last_sync_error", columnDefinition = "TEXT")
    private String lastSyncError;
    
    // Flags
    @Column(name = "active", nullable = false)
    private Boolean active = true;
    
    // Dates
    @Column(name = "registration_date", nullable = false)
    private LocalDateTime registrationDate;
    
    @Column(name = "last_update_date", nullable = false)
    private LocalDateTime lastUpdateDate;
    
    // Control fields
    @Column(name = "deleted", nullable = false)
    private Boolean deleted = false;
    
    @Column(name = "created_at", nullable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;
    
    // Constructors
    public SocialAccountEntity() {}
    
    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    
    public String getAccountCode() { return accountCode; }
    public void setAccountCode(String accountCode) { this.accountCode = accountCode; }
    
    public Long getCompanyId() { return companyId; }
    public void setCompanyId(Long companyId) { this.companyId = companyId; }
    
    public Long getSocialNetworkId() { return socialNetworkId; }
    public void setSocialNetworkId(Long socialNetworkId) { this.socialNetworkId = socialNetworkId; }
    
    public Long getResponsibleUserId() { return responsibleUserId; }
    public void setResponsibleUserId(Long responsibleUserId) { this.responsibleUserId = responsibleUserId; }
    
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    
    public String getDisplayName() { return displayName; }
    public void setDisplayName(String displayName) { this.displayName = displayName; }
    
    public String getBio() { return bio; }
    public void setBio(String bio) { this.bio = bio; }
    
    public String getProfilePhotoUrl() { return profilePhotoUrl; }
    public void setProfilePhotoUrl(String profilePhotoUrl) { this.profilePhotoUrl = profilePhotoUrl; }
    
    public String getProfileUrl() { return profileUrl; }
    public void setProfileUrl(String profileUrl) { this.profileUrl = profileUrl; }
    
    public Boolean getVerified() { return verified; }
    public void setVerified(Boolean verified) { this.verified = verified; }
    
    public Boolean getIsPrivate() { return isPrivate; }
    public void setIsPrivate(Boolean isPrivate) { this.isPrivate = isPrivate; }
    
    public String getCategory() { return category; }
    public void setCategory(String category) { this.category = category; }
    
    public String getContactPhone() { return contactPhone; }
    public void setContactPhone(String contactPhone) { this.contactPhone = contactPhone; }
    
    public String getContactEmail() { return contactEmail; }
    public void setContactEmail(String contactEmail) { this.contactEmail = contactEmail; }
    
    public String getLocation() { return location; }
    public void setLocation(String location) { this.location = location; }
    
    public String getWebsite() { return website; }
    public void setWebsite(String website) { this.website = website; }
    
    public Map<String, Object> getMetrics() { return metrics; }
    public void setMetrics(Map<String, Object> metrics) { this.metrics = metrics; }
    
    public Map<String, Object> getTokens() { return tokens; }
    public void setTokens(Map<String, Object> tokens) { this.tokens = tokens; }
    
    public Map<String, Object> getAutomationConfig() { return automationConfig; }
    public void setAutomationConfig(Map<String, Object> automationConfig) { this.automationConfig = automationConfig; }
    
    public SocialAccountStatusEntity getStatus() { return status; }
    public void setStatus(SocialAccountStatusEntity status) { this.status = status; }
    
    public LocalDateTime getLastSyncDate() { return lastSyncDate; }
    public void setLastSyncDate(LocalDateTime lastSyncDate) { this.lastSyncDate = lastSyncDate; }
    
    public LocalDateTime getNextSyncDate() { return nextSyncDate; }
    public void setNextSyncDate(LocalDateTime nextSyncDate) { this.nextSyncDate = nextSyncDate; }
    
    public String getLastSyncError() { return lastSyncError; }
    public void setLastSyncError(String lastSyncError) { this.lastSyncError = lastSyncError; }
    
    public Boolean getActive() { return active; }
    public void setActive(Boolean active) { this.active = active; }
    
    public LocalDateTime getRegistrationDate() { return registrationDate; }
    public void setRegistrationDate(LocalDateTime registrationDate) { this.registrationDate = registrationDate; }
    
    public LocalDateTime getLastUpdateDate() { return lastUpdateDate; }
    public void setLastUpdateDate(LocalDateTime lastUpdateDate) { this.lastUpdateDate = lastUpdateDate; }
    
    public Boolean getDeleted() { return deleted; }
    public void setDeleted(Boolean deleted) { this.deleted = deleted; }
    
    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; }
    
    // Helper methods to access metrics data safely
    public Long getFollowersCount() {
        if (metrics != null && metrics.containsKey("followers")) {
            Object followers = metrics.get("followers");
            if (followers instanceof Number) {
                return ((Number) followers).longValue();
            }
        }
        return 0L;
    }
    
    public Long getFollowingCount() {
        if (metrics != null && metrics.containsKey("following")) {
            Object following = metrics.get("following");
            if (following instanceof Number) {
                return ((Number) following).longValue();
            }
        }
        return 0L;
    }
    
    public Long getPostsCount() {
        if (metrics != null && metrics.containsKey("posts")) {
            Object posts = metrics.get("posts");
            if (posts instanceof Number) {
                return ((Number) posts).longValue();
            }
        }
        return 0L;
    }
    
    public Double getEngagement() {
        if (metrics != null && metrics.containsKey("engagement")) {
            Object engagement = metrics.get("engagement");
            if (engagement instanceof Number) {
                return ((Number) engagement).doubleValue();
            }
        }
        return 0.0;
    }
    
    // Helper methods to access token data safely
    public String getAccessToken() {
        if (tokens != null && tokens.containsKey("accessToken")) {
            return (String) tokens.get("accessToken");
        }
        return null;
    }
    
    public String getRefreshToken() {
        if (tokens != null && tokens.containsKey("refreshToken")) {
            return (String) tokens.get("refreshToken");
        }
        return null;
    }
    
    public String getExternalAccountId() {
        if (tokens != null && tokens.containsKey("externalAccountId")) {
            return (String) tokens.get("externalAccountId");
        }
        return null;
    }
    
    public LocalDateTime getLastSyncAt() {
        return lastSyncDate;
    }
    
    @PrePersist
    protected void onCreate() {
        LocalDateTime now = LocalDateTime.now();
        createdAt = now;
        updatedAt = now;
        registrationDate = now;
        lastUpdateDate = now;
    }
    
    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
        lastUpdateDate = LocalDateTime.now();
    }
}
