package com.sonymusic.dx.persistence.gras;

import java.util.ArrayList;
import java.util.List;

import jakarta.persistence.*;
import org.hibernate.type.YesNoConverter;

import jakarta.validation.constraints.NotNull;

@Entity
@Table(name = "vgras002")
public class ProductVersion extends RAASClientSpecificEntity {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "prod_vers_no")
    private Long productVersionNumber;

    @Column(name = "prod_fam_no")
    private Long productFamilyNumber;

    @Column(name = "is_prod_fam_head")
    @Convert(converter = YesNoConverter.class)
    @NotNull
    private Boolean isProductFamilyHead;

    @Column(name = "is_confidential")
    @Convert(converter = YesNoConverter.class)
    private boolean isConfidential;

    @Column(name = "rights_expired_flag")
    @Convert(converter = YesNoConverter.class)
    private Boolean sonyRightsExpired;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "rep_owner_key")
    private RepertoireOwner repertoireOwner;

    @Column(name = "prod_title")
    private String productTitle;

    @Column(name = "prod_match")
    private String productMatchTitle;

    @Column(name = "prod_title_suppl")
    private String productTitleSupplemental;

    @Column(name = "prod_title_suppl_match")
    private String productMatchTitleSupplemental;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "main_artist_no", referencedColumnName = "particip_no")
    private Participant mainArtist;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({ @JoinColumn(name = "label_key", referencedColumnName = "label_key"), @JoinColumn(name = "label_ext", referencedColumnName = "label_ext") })
    private Label label;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "genre_key")
    private Genre genre;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "prod_purpose_key")
    private ProductPurpose productPurpose;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "prod_class_key")
    private ProductClass productClass;
//
//    @ManyToOne(optional = false, fetch = FetchType.LAZY)
//    @JoinColumn(name = "config_cat_key")
//    private ConfigurationCategory configurationCategory;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "vgras364",joinColumns = { @JoinColumn(name = "prod_vers_no") }, inverseJoinColumns = { @JoinColumn(name = "rec_project_id") })
    @OrderBy("recordingProjectTitle ASC")
    private List<RecordingProject> recordingProjects = new ArrayList<RecordingProject>();

    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
    private List<Product> products = new ArrayList<Product>();

//    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
//    private List<ProductVersionParticipant> participants = new ArrayList<ProductVersionParticipant>();

//    @ManyToMany(fetch = FetchType.LAZY)
//    @JoinTable(name = "vgras045", joinColumns = @JoinColumn(name = "prod_vers_no", referencedColumnName = "prod_vers_no"),
//            inverseJoinColumns = @JoinColumn(name = "dist_area_key", referencedColumnName = "dist_area_key"))
//    private List<DistributionArea> distributionRightIncludes = new ArrayList<DistributionArea>();
//
//    @ManyToMany(fetch = FetchType.LAZY)
//    @JoinTable(name = "vgras046", joinColumns = @JoinColumn(name = "prod_vers_no", referencedColumnName = "prod_vers_no"),
//            inverseJoinColumns = @JoinColumn(name = "dist_area_key", referencedColumnName = "dist_area_key"))
//    private List<DistributionArea> distributionRightExcludes = new ArrayList<DistributionArea>();

    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
    private List<LocalProductVersion> localProductVersions = new ArrayList<LocalProductVersion>();
//
//    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
//    private List<ProductVersionLocalization> productVersionLocalLanguages = new ArrayList<ProductVersionLocalization>();

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "title_language_key", referencedColumnName = "language_key")
    private Language titleLanguage;

    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JoinColumn(name = "strategic_rep_grp_key", referencedColumnName = "strategic_rep_grp_key")
    private StrategicReportingGroup strategicReportingGroup;
//
//    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
//    private List<ProductVersionIndicatorInfo> productVersionIndicators = new ArrayList<ProductVersionIndicatorInfo>();
//
//    @ManyToOne(fetch = FetchType.LAZY)
//    @JoinColumn(name = "compilation_version_key")
//    private CompilationVersion compilationVersion;
//
//    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
//    private List<ProductVersionMoodInfo> productVersionMoods = new ArrayList<ProductVersionMoodInfo>();
//
//    @OneToMany(mappedBy = "productVersion", fetch = FetchType.LAZY)
//    private List<ProductVersionCountrySecondaryGenreInfo> localGenres = new ArrayList<ProductVersionCountrySecondaryGenreInfo>();

    protected ProductVersion() {}

    /**
     * Returns the number that uniquely identifies this <code>ProductVersion in GRAS.
     *
     * @return
     */
    public Long getProductVersionNumber() {
        return productVersionNumber;
    }

    public void setProductVersionNumber(Long productVersionNumber) {
        this.productVersionNumber = productVersionNumber;
    }

    /**
     * Returns the number of product family; this number is used to connect multiple product versions to one product family.
     *
     * @return
     */
    public Long getProductFamilyNumber() {
        return productFamilyNumber;
    }

    public void setProductFamilyNumber(Long productFamilyNumber) {
        this.productFamilyNumber = productFamilyNumber;
    }

    /**
     * Returns <code>true</code> if this <code>ProductVersion</code> is the head of the product family, and <code>false</code> otherwise.
     *
     * @return
     */
    public Boolean getIsProductFamilyHead() {
        return isProductFamilyHead;
    }

    public void setIsProductFamilyHead(Boolean isProductFamilyHead) {
        this.isProductFamilyHead = isProductFamilyHead;
    }

    /**
     * Returns the {@link RepertoireOwner} that owns this <code>ProductVersion</code>.
     *
     * @return
     */
    public RepertoireOwner getRepertoireOwner() {
        return repertoireOwner;
    }

    public void setRepertoireOwner(RepertoireOwner repertoireOwner) {
        this.repertoireOwner = repertoireOwner;
    }

    public boolean isConfidential() {
        return isConfidential;
    }

    public String getProductTitle() {
        return productTitle;
    }

    public String getProductMatchTitle() {
        return productMatchTitle;
    }

    public String getProductTitleSupplemental() {
        return productTitleSupplemental;
    }

    public String getProductMatchTitleSupplemental() {
        return productMatchTitleSupplemental;
    }

//    public Participant getMainArtist() {
//        return mainArtist;
//    }

    public void setConfidential(boolean isConfidential) {
        this.isConfidential = isConfidential;
    }

    public void setProductTitle(String productTitle) {
        this.productTitle = productTitle;
    }

    public void setProductMatchTitle(String productMatchTitle) {
        this.productMatchTitle = productMatchTitle;
    }

    public void setProductTitleSupplemental(String productTitleSupplemental) {
        this.productTitleSupplemental = productTitleSupplemental;
    }

    public void setProductMatchTitleSupplemental(String productMatchTitleSupplemental) {
        this.productMatchTitleSupplemental = productMatchTitleSupplemental;
    }

    public Participant getMainArtist() {
        return mainArtist;
    }

    public void setMainArtist(Participant mainArtist) {
        this.mainArtist = mainArtist;
    }

    //    public void setMainArtist(Participant mainArtist) {
//        this.mainArtist = mainArtist;
//    }

    public List<RecordingProject> getRecordingProjects() {
        return recordingProjects;
    }

    public void setRecordingProjects(List<RecordingProject> recordingProjects) {
        this.recordingProjects = recordingProjects;
    }

//    public List<Product> getProducts() {
//        return products;
//    }
//
//    public void setProducts(List<Product> products) {
//        this.products = products;
//    }

    public Label getLabel() {
        return label;
    }

    public void setLabel(Label label) {
        this.label = label;
    }

    public Genre getGenre() {
        return genre;
    }

    public void setGenre(Genre genre) {
        this.genre = genre;
    }

    public ProductPurpose getProductPurpose() {
        return productPurpose;
    }

    public void setProductPurpose(ProductPurpose productPurpose) {
        this.productPurpose = productPurpose;
    }

//    public List<ProductVersionParticipant> getParticipants() {
//        return participants;
//    }
//
//    public void setParticipants(List<ProductVersionParticipant> participants) {
//        this.participants = participants;
//    }

    public ProductClass getProductClass() {
        return productClass;
    }

    public void setProductClass(ProductClass productClass) {
        this.productClass = productClass;
    }

//    public List<DistributionArea> getDistributionRightIncludes() {
//        return distributionRightIncludes;
//    }
//
//    public void setDistributionRightIncludes(List<DistributionArea> distributionRightIncludes) {
//        this.distributionRightIncludes = distributionRightIncludes;
//    }
//
//    public List<DistributionArea> getDistributionRightExcludes() {
//        return distributionRightExcludes;
//    }
//
//    public void setDistributionRightExcludes(List<DistributionArea> distributionRightExcludes) {
//        this.distributionRightExcludes = distributionRightExcludes;
//    }

    public Boolean getSonyRightsExpired() {
        return sonyRightsExpired;
    }

    public void setSonyRightsExpired(Boolean sonyRightsExpired) {
        this.sonyRightsExpired = sonyRightsExpired;
    }

    public List<LocalProductVersion> getLocalProductVersions() {
        return localProductVersions;
    }
//
//    public void setLocalProductVersions(List<LocalProductVersion> localProductVersions) {
//        this.localProductVersions = localProductVersions;
//    }
//
//    public List<ProductVersionLocalization> getProductVersionLocalLanguages() {
//        return productVersionLocalLanguages;
//    }
//
//    public void setProductVersionLocalLanguages(List<ProductVersionLocalization> productVersionLocalLanguages) {
//        this.productVersionLocalLanguages = productVersionLocalLanguages;
//    }

    //    public ConfigurationCategory getConfigurationCategory() {
//        return configurationCategory;
//    }
//
//    public void setConfigurationCategory(ConfigurationCategory configurationCategory) {
//        this.configurationCategory = configurationCategory;
//    }
//
    public Language getTitleLanguage() {
        return titleLanguage;
    }


    public void setTitleLanguage(Language titleLanguage) {
        this.titleLanguage = titleLanguage;
    }

    public StrategicReportingGroup getStrategicReportingGroup() {
        return strategicReportingGroup;
    }

    public void setStrategicReportingGroup(StrategicReportingGroup strategicReportingGroup) {
        this.strategicReportingGroup = strategicReportingGroup;
    }
//
//    public List<ProductVersionIndicatorInfo> getProductVersionIndicators() {
//        return productVersionIndicators;
//    }
//
//    public void setProductVersionIndicators(List<ProductVersionIndicatorInfo> productVersionIndicators) {
//        this.productVersionIndicators = productVersionIndicators;
//    }
//
//    public CompilationVersion getCompilationVersion() {
//        return compilationVersion;
//    }
//
//    public void setCompilationVersion(CompilationVersion compilationVersion) {
//        this.compilationVersion = compilationVersion;
//    }
//
//    public List<ProductVersionMoodInfo> getProductVersionMoods() {
//        return productVersionMoods;
//    }
//
//    public void setProductVersionMoods(List<ProductVersionMoodInfo> productVersionMoods) {
//        this.productVersionMoods = productVersionMoods;
//    }
//
//    public List<ProductVersionCountrySecondaryGenreInfo> getLocalGenres() {
//        return localGenres;
//    }
//
//    public void setLocalGenresInfo(List<ProductVersionCountrySecondaryGenreInfo> localGenres) {
//        this.localGenres = localGenres;
//    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((productVersionNumber == null) ? 0 : productVersionNumber.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ProductVersion other = (ProductVersion) obj;
        if (productVersionNumber == null) {
            if (other.productVersionNumber != null)
                return false;
        } else if (!productVersionNumber.equals(other.productVersionNumber)) {
            return false;
        }
        return true;
    }

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }

}
