package com.social.media.infrastructure.persistence.entity;

import jakarta.persistence.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.time.LocalDateTime;

/**
 * JPA Entity for Company aggregate
 */
@Entity
@Table(name = "companies", schema = "core_business")
public class CompanyEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;
    
    @Column(name = "name", nullable = false, length = 200)
    private String name;
    
    @Column(name = "email", nullable = false, unique = true, length = 100)
    private String email;
    
    @Column(name = "cnpj", nullable = false, unique = true, length = 18)
    private String cnpj;
    
    @Column(name = "phone", length = 20)
    private String phone;
    
    @Column(name = "website", length = 255)
    private String website;
    
    @Column(name = "activity_sector", length = 100)
    private String activitySector;
    
    @Enumerated(EnumType.STRING)
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(name = "plan", nullable = false, columnDefinition = "core_business.company_plan")
    private CompanyPlanEntity plan;
    
    @Enumerated(EnumType.STRING)
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(name = "status", nullable = false, columnDefinition = "core_business.company_status")
    private CompanyStatusEntity status;
    
    // Address fields
    @Column(name = "address_street", length = 200)
    private String addressStreet;
    
    @Column(name = "address_number", length = 20)
    private String addressNumber;
    
    @Column(name = "address_complement", length = 100)
    private String addressComplement;
    
    @Column(name = "address_neighborhood", length = 100)
    private String addressNeighborhood;
    
    @Column(name = "address_city", length = 100)
    private String addressCity;
    
    @Column(name = "address_state", length = 50)
    private String addressState;
    
    @Column(name = "address_zip_code", length = 10)
    private String addressZipCode;
    
    @Column(name = "address_country", length = 50)
    private String addressCountry;
    
    // === HIERARCHY FIELDS ===
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_company_id")
    private CompanyEntity parentCompany;
    
    @Column(name = "hierarchy_level", nullable = false)
    private Integer hierarchyLevel = 0;
    
    @Enumerated(EnumType.STRING)
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(name = "branch_type", nullable = false, columnDefinition = "core_business.company_branch_type")
    private BranchTypeEntity branchType = BranchTypeEntity.MATRIZ;
    
    @Column(name = "branch_code", length = 10)
    private String branchCode;
    
    @Column(name = "region", length = 100)
    private String region;
    
    @Enumerated(EnumType.STRING)
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(name = "branch_status", nullable = false, columnDefinition = "core_business.company_branch_status")
    private BranchStatusEntity branchStatus = BranchStatusEntity.ACTIVE;
    
    // Audit fields
    @Column(name = "created_at", nullable = false)
    private LocalDateTime createdAt;
    
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @Column(name = "created_by")
    private Long createdBy;
    
    @Column(name = "updated_by")
    private Long updatedBy;
    
    @Version
    @Column(name = "version")
    private Long version;
    
    // Constructors
    public CompanyEntity() {}
    
    public CompanyEntity(Long id, String name, String email, String cnpj, String phone,
                        String website, String activitySector, CompanyPlanEntity plan,
                        CompanyStatusEntity status, String addressStreet, String addressNumber,
                        String addressComplement, String addressNeighborhood, String addressCity,
                        String addressState, String addressZipCode, String addressCountry,
                        CompanyEntity parentCompany, Integer hierarchyLevel, BranchTypeEntity branchType,
                        String branchCode, String region, BranchStatusEntity branchStatus,
                        LocalDateTime createdAt, LocalDateTime updatedAt, Long createdBy,
                        Long updatedBy, Long version) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.cnpj = cnpj;
        this.phone = phone;
        this.website = website;
        this.activitySector = activitySector;
        this.plan = plan;
        this.status = status;
        this.addressStreet = addressStreet;
        this.addressNumber = addressNumber;
        this.addressComplement = addressComplement;
        this.addressNeighborhood = addressNeighborhood;
        this.addressCity = addressCity;
        this.addressState = addressState;
        this.addressZipCode = addressZipCode;
        this.addressCountry = addressCountry;
        this.parentCompany = parentCompany;
        this.hierarchyLevel = hierarchyLevel;
        this.branchType = branchType;
        this.branchCode = branchCode;
        this.region = region;
        this.branchStatus = branchStatus;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
        this.createdBy = createdBy;
        this.updatedBy = updatedBy;
        this.version = version;
    }
    
    // Getters and Setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public String getCnpj() { return cnpj; }
    public void setCnpj(String cnpj) { this.cnpj = cnpj; }
    
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
    
    public String getWebsite() { return website; }
    public void setWebsite(String website) { this.website = website; }
    
    public String getActivitySector() { return activitySector; }
    public void setActivitySector(String activitySector) { this.activitySector = activitySector; }
    
    public CompanyPlanEntity getPlan() { return plan; }
    public void setPlan(CompanyPlanEntity plan) { this.plan = plan; }
    
    public CompanyStatusEntity getStatus() { return status; }
    public void setStatus(CompanyStatusEntity status) { this.status = status; }
    
    public String getAddressStreet() { return addressStreet; }
    public void setAddressStreet(String addressStreet) { this.addressStreet = addressStreet; }
    
    public String getAddressNumber() { return addressNumber; }
    public void setAddressNumber(String addressNumber) { this.addressNumber = addressNumber; }
    
    public String getAddressComplement() { return addressComplement; }
    public void setAddressComplement(String addressComplement) { this.addressComplement = addressComplement; }
    
    public String getAddressNeighborhood() { return addressNeighborhood; }
    public void setAddressNeighborhood(String addressNeighborhood) { this.addressNeighborhood = addressNeighborhood; }
    
    public String getAddressCity() { return addressCity; }
    public void setAddressCity(String addressCity) { this.addressCity = addressCity; }
    
    public String getAddressState() { return addressState; }
    public void setAddressState(String addressState) { this.addressState = addressState; }
    
    public String getAddressZipCode() { return addressZipCode; }
    public void setAddressZipCode(String addressZipCode) { this.addressZipCode = addressZipCode; }
    
    public String getAddressCountry() { return addressCountry; }
    public void setAddressCountry(String addressCountry) { this.addressCountry = addressCountry; }
    
    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 getCreatedBy() { return createdBy; }
    public void setCreatedBy(Long createdBy) { this.createdBy = createdBy; }
    
    public Long getUpdatedBy() { return updatedBy; }
    public void setUpdatedBy(Long updatedBy) { this.updatedBy = updatedBy; }
    
    public Long getVersion() { return version; }
    public void setVersion(Long version) { this.version = version; }
    
    // === HIERARCHY GETTERS AND SETTERS ===
    
    public CompanyEntity getParentCompany() { return parentCompany; }
    public void setParentCompany(CompanyEntity parentCompany) { this.parentCompany = parentCompany; }
    
    public Integer getHierarchyLevel() { return hierarchyLevel; }
    public void setHierarchyLevel(Integer hierarchyLevel) { this.hierarchyLevel = hierarchyLevel; }
    
    public BranchTypeEntity getBranchType() { return branchType; }
    public void setBranchType(BranchTypeEntity branchType) { this.branchType = branchType; }
    
    public String getBranchCode() { return branchCode; }
    public void setBranchCode(String branchCode) { this.branchCode = branchCode; }
    
    public String getRegion() { return region; }
    public void setRegion(String region) { this.region = region; }
    
    public BranchStatusEntity getBranchStatus() { return branchStatus; }
    public void setBranchStatus(BranchStatusEntity branchStatus) { this.branchStatus = branchStatus; }
    
    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
    }
    
    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }
}
