package performa.orm;

import com.stripe.model.Card;
import oneit.logging.LoggingArea;
import oneit.objstore.ObjectStatus;
import oneit.objstore.ValidationContext;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.objstore.rdbms.filters.IsNotNullFilter;
import oneit.security.SecUser;
import oneit.utils.CollectionUtils;
import oneit.utils.StringUtils;
import oneit.utils.math.NullArith;
import oneit.utils.parsers.FieldException;
import performa.orm.types.JobStatus;
import performa.utils.StripeUtils;


public class Company extends BaseCompany
{
    private static final long serialVersionUID = 0L;
    
    public  static LoggingArea  LOG = LoggingArea.createLoggingArea("Company");

    // This constructor should not be called
    public Company ()
    {
        // Do not add any code to this, always put it in initialiseNewObject
    }
    
    
    public boolean showHasClientSupport()
    {
        return isTrue(getHasClientSupport());
    }
    
    //This logic moved from invite_users.jsp
    public boolean createDefaultUser() throws FieldException
    {
        boolean addUser =   true;
        for (CompanyUser cUser : getUsersSet())
        {
            if(!CollectionUtils.equals(cUser, getAddedByUser()))
            {
                addUser =   false;
            }
        }
        
        if(addUser)
        {
            SecUser     secUser     =   SecUser.createSecUser(getTransaction());
            CompanyUser companyUser =   secUser.getExtensionOrCreate(CompanyUser.REFERENCE_CompanyUser);
        
            addToUsers(companyUser);
        }
        return addUser;
    }

    
    @Override
    public void validate(ValidationContext context) 
    {
        if(getStatus() != ObjectStatus.NEW)
        {
            context.check(getHiringTeamType() != null , this, FIELD_HiringTeamType, "mandatory");
        }
        
        super.validate(context);
    }
    
    
    public Boolean isEmailCorrect()
    {
        return StringUtils.isEmailAddress(StringUtils.subBlanks(getUserEmail()));
    }
    
    
    @Override
    public String getToString() 
    {
        return StringUtils.subNulls(getCompanyName(), super.getToString());
    }
    
    
    public PaymentPlan getSelectedPaymentPlan()
    {
        if(getPaymentJobCount()!=null)
        {
            PaymentPlan[]   plans   =   PaymentPlan.SearchByAll()
                                                .andActiveJobCount(new EqualsFilter<>(getPaymentJobCount()))
                                                .search(getTransaction());
            
            if(plans.length>0)
            {
                return plans[0];
            }
        }
        
        return null;
    }
    
    
    public Double getPaymentPlanAmount()
    {
        PaymentPlan selectedPaymentPlan =   getSelectedPaymentPlan();
        
        if(selectedPaymentPlan!=null)
        {
            return selectedPaymentPlan.getAmount();
        }
        
        return null;
    }
   
    
    public Double getPerJobPaymentPlanAmount()
    {
        PaymentPlan selectedPaymentPlan =   getSelectedPaymentPlan();
        
        if(selectedPaymentPlan!=null)
        {
            return NullArith.divide(selectedPaymentPlan.getAmount(), selectedPaymentPlan.getActiveJobCount());
        }
        
        return null;
    }
    
    
    public Double getPaymentPlanSaveAmount()
    {
        PaymentPlan selectedPaymentPlan =   getSelectedPaymentPlan();
        
        if(selectedPaymentPlan!=null)
        {
            return selectedPaymentPlan.getPerMonthSaveAmount();
        }
        
        return null;
    }
    
    
    public boolean canCreateJob()
    {
        Job[] openJobs  =   Job.SearchByCompany().andJobStatus(new EqualsFilter<>(JobStatus.OPEN))
                                .byCompany(this)
                                .search(getTransaction());
        
        return getPaymentPlan() != null && getPaymentPlan().getActiveJobCount() > openJobs.length;
    }
    
    public String getCardNumber() throws FieldException
    {
        Card    card    =   StripeUtils.retrieveCard(this);

        return card != null ? "xxxx-xxxx-xxxx-" + card.getLast4() : "";
    }
    
    
    public String getExpiry () throws FieldException
    {
        Card    card    =   StripeUtils.retrieveCard(this);

        return card != null ? String.format("%02d", card.getExpMonth()) + " / " + (card.getExpYear() % 100) : "";
    }
}