package com.capgemini.reports.bomlineholder.flattener.line;

import com.capgemini.framework.common.StringHelper;
import com.capgemini.framework.teamcenter.authent.TcSession;
import com.capgemini.framework.teamcenter.exceptions.KurtException;
import com.capgemini.reports.bomlineholder.BOMLineHolder;
import com.capgemini.reports.bomlineholder.BOMLineHolderHelper;
import com.capgemini.reports.snecmaobjects.ISnecmaObject;
import com.capgemini.reports.snecmaobjects.rf.AbstractRF;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * Represents a Receptor whose RF does not have any Component.
 *
 * @param <U> a Transformer object producing results of type T
 * @param <T> the result of a transformation by object of type U
 */
@Getter
@Slf4j
public abstract class AbstractReceptorLine<T, U> implements SnecmaLine<T, U> {

    private static final String NON = "Non";
    private static final String EMPTY = "";

    private final BOMLineHolder recepteurBL;
    private final BOMLineHolder repereBL;
    private final ISnecmaObject recepteur;
    private final AbstractRF repere;
    private final int lineNumber;
    private final TcSession session;


    /**
     * builds a {@link AbstractReceptorLine} object from its Receptor and Repere's {@link BOMLineHolder}.
     *
     * @param session
     * @param recepteurBL       the receptor
     * @param repereRecepteurBL the repere of the receptor
     * @param lineNum           the line number in the bom
     */
    public AbstractReceptorLine(TcSession session, final BOMLineHolder recepteurBL, final BOMLineHolder repereRecepteurBL, final int lineNum) {
        this.session = session;
        this.recepteurBL = recepteurBL;
        this.repereBL = repereRecepteurBL;
        this.recepteur = recepteurBL.getSnecmaObject();
        this.repere = (AbstractRF) repereRecepteurBL.getSnecmaObject();
        this.lineNumber = lineNum;
    }

    @Override
    public int compareTo(final SnecmaLine<T, U> other) {
        if (this.getClass().isAssignableFrom(other.getClass())) {
            return compareTo((AbstractReceptorLine<T, U>) other);
        } else {
            return getLineId().compareTo(other.getLineId());
        }
    }


    /**
     * Compares this {@link AbstractReceptorLine} to an other one.
     *
     * @param other the other {@link AbstractReceptorLine}
     * @return a difference number. 0 if equal.
     */
    public int compareTo(final AbstractReceptorLine<T, U> other) {
        int cmp = recepteur.getItemId().compareTo(other.recepteur.getItemId());
        if (cmp != 0) {
            return cmp;
        } else {
            return repere.getName().compareTo(other.repere.getName());
        }
    }

    @Override
    public String toString() {
        return "Receptor(" + recepteur.getItemId() + "/" + repere.getName();
    }

    @Override
    public String getLineId() {
        return recepteur.getItemId() + "/" + repere.getName();
    }

    @Override
    public String getIDReceptor() {
        return this.getRecepteur().getItemId();
    }

    @Override
    public String getNameReceptor() {
        return this.getRecepteur().getName();
    }

    @Override
    public String getRevisionReceptor() {
        return this.getRecepteur().getRevisionId();
    }

    @Override
    public String getRepereName() {
        return this.getRepere().getName();
    }

    @Override
    public String getRepereRevision() {
        return this.getRepere().getRevisionId();
    }

    @Override
    public String getResponsableRepere() {
        try {
            if (this.getRepere().isRFGeneric()) {
                return BOMLineHolderHelper.findRfAdmin(this.getRepereBL()).getResponsableRepere();
            } else if (this.getRepereBL().getSnecmaObject().isRFPartOrPartAssemb()) {
                if ("RF Part Assemb Revision".equals(this.getRepereBL().getSnecmaObject().getType())) {
                    return BOMLineHolderHelper.findRfAdminA(this.getRepereBL()).getResponsableRepere();
                } else {
                    return BOMLineHolderHelper.findRfAdmin(this.getRepereBL()).getResponsableRepere();
                }
            }
        } catch (KurtException e) {
            log.warn("Unable to find a RF Admin below Rf: " + this.getRepereBL().getSnecmaObject().getName(), e);
            return EMPTY;
        }
        return EMPTY;
    }

    @Override
    public String getSuiviMontage() {
        String response;
        if (this.getRepere().isRFGeneric()) {
            response = NON;
        } else {
            try {
                if (this.getRepereBL().getSnecmaObject().isRFPartOrPartAssemb()) {
                    if ("RF Part Assemb Revision".equals(this.getRepereBL().getSnecmaObject().getType())) {
                        response = BOMLineHolderHelper.findRfAdminA(this.getRepereBL()).getSuiviMontage();
                    } else {
                        response = BOMLineHolderHelper.findRfAdminAP(this.getRepereBL()).getSuiviMontage();
                    }
                } else {
                    response = EMPTY;
                }
            } catch (KurtException e) {
                log.warn("Unable to find a RF Admin A/AP below Rf Part / RF Part Assemb: " + this.getRepereBL().getSnecmaObject().getName(), e);
                return EMPTY;
            }
        }
        return response;
    }

    @Override
    public String getIDComponent() {
        return EMPTY;
    }

    @Override
    public String getIDRevisionComponent() {
        return EMPTY;
    }

    @Override
    public String getTypeReference() {
        return EMPTY;
    }

    @Override
    public String getNameReference() {
        return EMPTY;
    }

    @Override
    public String getReferenceConceptor() {
        return EMPTY;
    }

    @Override
    public String getReferenceTransposed() {
        return EMPTY;
    }

    @Override
    public String getReferenceAssociated() {
        return EMPTY;
    }

    @Override
    public String getResponsableConception() {
        return EMPTY;
    }

    @Override
    public String getArticleGestion() {
        return EMPTY;
    }

    @Override
    public String getClassement() {
        return EMPTY;
    }

    @Override
    public String getSuiviUtilisation() {
        return EMPTY;
    }

    @Override
    public String getSuiviDureeVie() {
        return EMPTY;
    }

    @Override
    public String[] getSuppliersList() {
        return new String[0];
    }

    @Override
    public String getALT() {
        return EMPTY;
    }

    @Override
    public String getSB() {
        return EMPTY;
    }

    @Override
    public String getQuantiteCumulee() {
        return EMPTY;
    }

    @Override
    public String getPanachage() {
        return EMPTY;
    }

    @Override
    public String getQuantite() {
        return EMPTY;
    }

    @Override
    public String getMaquetteInterneExterne() {
        return EMPTY;
    }

    @Override
    public Double getMass() {
        return null;
    }

    @Override
    public String getMassUnit() {
        return EMPTY;
    }

    @Override
    public String getDesignationENG() {
        return StringHelper.EMPTY;
    }

}
