package com.fp.person.rules.save;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.EntityManager;

import com.fp.dto.Response;
import com.fp.dto.save.SaveBean;
import com.fp.dto.save.SaveRequest;
import com.fp.general.exception.GeneralException;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.commondb.helper.FormatDates;
import com.fp.persistence.pcustomer.balance.TcustPersonBalance;
import com.fp.persistence.pcustomer.gene.TcustPersonAddress;
import com.fp.persistence.pcustomer.gene.TcustPersonAddressKey;
import com.fp.persistence.pcustomer.gene.TcustPersonDetail;
import com.fp.persistence.pcustomer.gene.TcustPersonPhone;
import com.fp.persistence.pcustomer.people.TcustPeople;
import com.fp.persistence.pcustomer.people.TcustPeopleAditionalData;
import com.fp.persistence.pcustomer.people.TcustPeopleAssociation;
import com.fp.persistence.pcustomer.people.TcustPeopleAssociationKey;
import com.fp.persistence.pcustomer.people.TcustPeopleExpenses;
import com.fp.persistence.pcustomer.people.TcustPeopleExpensesKey;
import com.fp.persistence.pcustomer.people.TcustPeopleFixedIncome;
import com.fp.persistence.pcustomer.people.TcustPeopleFixedIncomeKey;
import com.fp.persistence.pcustomer.people.TcustPeopleIncome;
import com.fp.persistence.pcustomer.people.TcustPeopleIncomeKey;
import com.fp.persistence.pcustomer.people.TcustPeopleJob;
import com.fp.persistence.pcustomer.people.TcustPeopleJobKey;
import com.fp.persistence.pcustomer.people.TcustPeopleKey;
import com.fp.persistence.pcustomer.people.TcustPeopleLoan;
import com.fp.persistence.pcustomer.people.TcustPeopleLoanKey;
import com.fp.persistence.pcustomer.people.TcustPeopleOtherAssets;
import com.fp.persistence.pcustomer.people.TcustPeopleOtherAssetsKey;
import com.fp.persistence.pcustomer.people.TcustPeopleRealAssets;
import com.fp.persistence.pcustomer.people.TcustPeopleRealAssetsKey;
import com.fp.persistence.pcustomer.people.TcustPeopleTradereferences;
import com.fp.persistence.pcustomer.people.TcustPeopleTradereferencesKey;
import com.fp.persistence.pcustomer.people.TcustPeopleVehicle;
import com.fp.persistence.pcustomer.people.TcustPeopleVehicleKey;
import com.fp.persistence.pgeneral.safe.TsafeUser;
import com.fp.persistence.pgeneral.safe.TsafeUserDetail;
import com.fp.persistence.pgeneral.safe.TsafeUserDetailKey;
import com.fp.person.validate.ValidateIdentification;

/**
 * Clase que se encarga de completar el personcode cuando se crea una nueva
 * persona natural
 *
 * @author Santiago Castillo
 * @version 2.1
 */
public class CompletePersonCode extends CompletePersonAndCompany {

    /**
     * Metodo que se encarga de completar el codigo de persona para su creacion
     * cuando un save es requerido.
     *
     * @param pSaveRequest
     * @return
     * @throws Exception
     */
    @Override
    public SaveRequest normalProcess(SaveRequest pSaveRequest) throws Exception {
    	try {
    		TcustPersonDetail tcustPersonDetail = (TcustPersonDetail) pSaveRequest.getSaveBeanModifiedObject("TCUSTPERSONDETAIL");
    		TcustPeople tcustPeople = (TcustPeople) pSaveRequest.getSaveBeanModifiedObject("TCUSTPEOPLE");    		
    		
    		if (tcustPersonDetail != null) {
    		    switch (tcustPersonDetail.getIdentificationcatalog()) {
    			case "CED":
    			    if (!ValidateIdentification.cedula(tcustPersonDetail.getIdentification())) {
    				throw new GeneralException("CUST-0013", "CÉDULA NO VÁLIDA");
    			    }
    			    break;
    			case "RUC":
    			    if (!ValidateIdentification.ruc(tcustPersonDetail.getIdentification())) {
    				throw new GeneralException("CUST-0014", "RUC NO VÁLIDO");
    			    }
    			    break;
    		    }
    		}
    		
    		//TcustPersonBalance tcustPersonBalance = (TcustPersonBalance) pSaveRequest.getSaveBeanModifiedObject("TCUSTPERSONBALANCE");
    		SaveBean sbTcustPersonBalance = (SaveBean) pSaveRequest.get("com.fp.persistence.pcustomer.balance.TcustPersonBalance");
    		TcustPersonBalance tcustPersonBalance = null;
    		if (sbTcustPersonBalance != null) {
    		    tcustPersonBalance = (TcustPersonBalance) sbTcustPersonBalance.getModifiedObject();
    		}
    		Object aditionalData = pSaveRequest.getSaveBeanModifiedObject("TCUSTPEOPLEADITIONALDATA");
    		List<Object> tcustPersonAddress = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPERSONADDRESS");
    		if(tcustPersonAddress==null || tcustPersonAddress.size()==0){
    			Object adress=  pSaveRequest.getSaveBeanModifiedObject("TCUSTPERSONADDRESS");
    			if(adress!=null){
    				tcustPersonAddress.add(adress);
    			}
    		}
    		
    		List<Object> tcustPersonPhone = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPERSONPHONE");
    		if(tcustPersonPhone==null || tcustPersonPhone.size()==0){
    			Object phone=  pSaveRequest.getSaveBeanModifiedObject("TCUSTPERSONPHONE");
    			if(phone!=null){
    				tcustPersonPhone.add(phone);
    			}
    		}
    		List<Object> income = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEINCOME");
    		List<Object> expenses = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEEXPENSES");
    		List<Object> job = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEJOB");
    		List<Object> vehicles = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEVEHICLE");
    		List<Object> otherassets = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEOTHERASSETS");
    		List<Object> realassets = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEREALASSETS");
    		List<Object> tradereferences = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLETRADEREFERENCES");
    		List<Object> bankreference = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPERSONBANKREFERENCE");
    		List<Object> personalreference = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPERSONPERSONALREFERENCE");
    		List<Object> loan = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLELOAN");
    		List<Object> fixedincome = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEFIXEDINCOME");
    		List<Object> association = pSaveRequest.getSaveBeanModifiedRecords("TCUSTPEOPLEASSOCIATION");
    		if ((tcustPersonDetail != null) && (tcustPersonDetail.getPk().getPersoncode() == null)) {
    		    Integer personcode = this.getPersonCode();
    		    this.createPerson(pSaveRequest, personcode);
    		    this.completePersonDetail(pSaveRequest, tcustPersonDetail, personcode);
    		    if (tcustPeople != null) {
    			this.completePeople(pSaveRequest, tcustPeople, personcode);
    		    }
    		    this.completeAddress(tcustPersonAddress, personcode);
    		    this.completePhone(tcustPersonPhone, personcode);
    		    
    		    this.completeVehicles(vehicles, personcode);
    		    this.completeOtherAssets(otherassets, personcode);
    		    this.completeRealAssets(realassets, personcode);
    		    this.completeIncome(income, personcode);
    		    this.completeExpenses(expenses, personcode);
    		    this.completeJob(job, personcode);
    		    this.completeTradeReferences(tradereferences, personcode);
    		    this.completeBankReference(bankreference, personcode);
    		    this.completePersonalReference(personalreference, personcode);
    		    this.completeLoan(loan, personcode);
    		    this.completeAditionalData(aditionalData, personcode);
    		    this.completeFixedIncome(fixedincome, personcode);
    		    this.completeAssociation(association, personcode);
    		    this.completeBalance(tcustPersonBalance, personcode, pSaveRequest);
    		    Response response = pSaveRequest.getResponse();
    		    response.put("personcode", personcode);
    		    response.put("personname", tcustPersonDetail.getName());
    		    
    		    // Creacion de usuario del sistema
    		    EntityManager entityManager = PersistenceHelper.getEntityManager();
    		    
        		Integer internalcode = getInternalCode();
        		TsafeUser userObj = new TsafeUser();    		
        		userObj.setPk(tcustPersonDetail.getIdentification());
        		userObj.setPersoncode(personcode);
        		userObj.setCompanycode(1);
        		userObj.setInternalcode(internalcode);
        		entityManager.persist(userObj);
        		
        		// Creacion de usuario DETALLE del sistema
        		TsafeUserDetailKey userDetailKeyObj = new TsafeUserDetailKey();
        		userDetailKeyObj.setDateto(FormatDates.getDefaultExpiryTimestamp());
        		userDetailKeyObj.setPersoncode(personcode);
        		userDetailKeyObj.setUsercode(tcustPersonDetail.getIdentification());
        		TsafeUserDetail userDetailObj = new TsafeUserDetail();
        		userDetailObj.setPk(userDetailKeyObj);
        		userDetailObj.setRecordversion(0);
        		userDetailObj.setDatefrom(new Timestamp(System.currentTimeMillis()));
        		userDetailObj.setUserstatuscatalog("ACT");
        		userDetailObj.setUserstatuscatalogcode("USERSTATUS");
        		userDetailObj.setCompanycode(1);
        		userDetailObj.setAreacode(1);
        		userDetailObj.setOfficecode(1);
        		userDetailObj.setBranchcode(1);
        		userDetailObj.setChannelcode("BRC");
        		userDetailObj.setLanguagecode("ES");
        		userDetailObj.setNickname(tcustPersonDetail.getIdentification());
        		userDetailObj.setPassword("7c4a8d09ca3762af61e59520943dc26494f8941b");
        		userDetailObj.setChangepassword("Y");
        		userDetailObj.setIngressuser("ADMIN");
        		userDetailObj.setActivateuser("ADMIN");
        		userDetailObj.setIsuserbpm("Y");
        		entityManager.persist(userDetailObj);
        		
    		}
    		this.completeAditionalInfo(pSaveRequest, tcustPersonDetail);
    		this.balanceCode(tcustPersonBalance, pSaveRequest);
			
		} catch (Exception e) {
			return pSaveRequest;
		}
    	return pSaveRequest;
    }

    /**
     * Metodo para reversos
     *
     * @param pSaveRequest
     * @return
     * @throws Exception
     */
    @Override
    public SaveRequest reverseProcess(SaveRequest pSaveRequest) throws Exception {
	return pSaveRequest;
    }

    /**
     * Completa el codigo de la persona en la tabla TcustPeople
     *
     * @param tcustPeople
     * @param personcode
     * @throws Exception
     */
    private void completePeople(SaveRequest pSaverequest, TcustPeople tcustPeople, Integer personcode) throws Exception {
	TcustPeopleKey tcustPeopleKey = new TcustPeopleKey();
	tcustPeopleKey.setPersoncode(personcode);
	tcustPeople.setPk(tcustPeopleKey);
	tcustPeople.setIngressusercode(pSaverequest.getUser());
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * Tcustpeoplejob
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeJob(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleJob tcustPeopleJob = (TcustPeopleJob) object;
	    if ((tcustPeopleJob != null) && (tcustPeopleJob.getPk().getPersoncode() == null)) {
		TcustPeopleJobKey tcustPeopleJobKey = new TcustPeopleJobKey();
		tcustPeopleJobKey.setPersoncode(personcode);
		tcustPeopleJobKey.setJobsequence(tcustPeopleJob.getPk().getJobsequence());
		tcustPeopleJob.setPk(tcustPeopleJobKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleVehicle
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeVehicles(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleVehicle tcustPeopleVehicle = (TcustPeopleVehicle) object;
	    if ((tcustPeopleVehicle != null) && (tcustPeopleVehicle.getPk().getPersoncode() == null)) {
		TcustPeopleVehicleKey tcustPeopleVehicleKey = new TcustPeopleVehicleKey();
		tcustPeopleVehicleKey.setPersoncode(personcode);
		tcustPeopleVehicleKey.setVehiclesequence(tcustPeopleVehicle.getPk().getVehiclesequence());
		tcustPeopleVehicle.setPk(tcustPeopleVehicleKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleOtherAssets
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeOtherAssets(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleOtherAssets tcustPeopleOtherAssets = (TcustPeopleOtherAssets) object;
	    if ((tcustPeopleOtherAssets != null) && (tcustPeopleOtherAssets.getPk().getPersoncode() == null)) {
		TcustPeopleOtherAssetsKey tcustPeopleOtherAssetsKey = new TcustPeopleOtherAssetsKey();
		tcustPeopleOtherAssetsKey.setPersoncode(personcode);
		tcustPeopleOtherAssetsKey.setAssetssequence(tcustPeopleOtherAssets.getPk().getAssetssequence());
		tcustPeopleOtherAssets.setPk(tcustPeopleOtherAssetsKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleRealAssets
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeRealAssets(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleRealAssets tcustPeopleRealAssets = (TcustPeopleRealAssets) object;
	    if ((tcustPeopleRealAssets != null) && (tcustPeopleRealAssets.getPk().getPersoncode() == null)) {
		TcustPeopleRealAssetsKey tcustPeopleRealAssetsKey = new TcustPeopleRealAssetsKey();
		tcustPeopleRealAssetsKey.setPersoncode(personcode);
		tcustPeopleRealAssetsKey.setAssetssequence(tcustPeopleRealAssets.getPk().getAssetssequence());
		tcustPeopleRealAssets.setPk(tcustPeopleRealAssetsKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleTradeReferences
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeTradeReferences(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleTradereferences tcustPeopleTradereferences = (TcustPeopleTradereferences) object;
	    if ((tcustPeopleTradereferences != null) && (tcustPeopleTradereferences.getPk().getPersoncode() == null)) {
		TcustPeopleTradereferencesKey tcustPeopleTradereferencesKey = new TcustPeopleTradereferencesKey();
		tcustPeopleTradereferencesKey.setPersoncode(personcode);
		tcustPeopleTradereferencesKey.setTradesequence(tcustPeopleTradereferences.getPk().getTradesequence());
		tcustPeopleTradereferences.setPk(tcustPeopleTradereferencesKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleIncome
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeIncome(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleIncome tcustPeopleIncome = (TcustPeopleIncome) object;
	    if ((tcustPeopleIncome != null) && (tcustPeopleIncome.getPk().getPersoncode() == null)) {
		TcustPeopleIncomeKey tcustPeopleIncomeKey = new TcustPeopleIncomeKey();
		tcustPeopleIncomeKey.setPersoncode(personcode);
		tcustPeopleIncomeKey.setIncomesequence(tcustPeopleIncome.getPk().getIncomesequence());
		tcustPeopleIncome.setPk(tcustPeopleIncomeKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleExpenses
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeExpenses(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleExpenses tcustPeopleExpenses = (TcustPeopleExpenses) object;
	    if ((tcustPeopleExpenses != null) && (tcustPeopleExpenses.getPk().getPersoncode() == null)) {
		TcustPeopleExpensesKey tcustPeopleExpensesKey = new TcustPeopleExpensesKey();
		tcustPeopleExpensesKey.setPersoncode(personcode);
		tcustPeopleExpensesKey.setExpensesequence(tcustPeopleExpenses.getPk().getExpensesequence());
		tcustPeopleExpenses.setPk(tcustPeopleExpensesKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleLoan
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeLoan(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleLoan tcustPeopleLoan = (TcustPeopleLoan) object;
	    if ((tcustPeopleLoan != null) && (tcustPeopleLoan.getPk().getPersoncode() == null)) {
		TcustPeopleLoanKey tcustPeopleLoanKey = new TcustPeopleLoanKey();
		tcustPeopleLoanKey.setPersoncode(personcode);
		tcustPeopleLoanKey.setLoansequence(tcustPeopleLoan.getPk().getLoansequence());
		tcustPeopleLoan.setPk(tcustPeopleLoanKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleAditionalData
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeAditionalData(Object lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	TcustPeopleAditionalData tcustPeopleAditionalData = (TcustPeopleAditionalData) lDetail;
	if ((tcustPeopleAditionalData != null) && (tcustPeopleAditionalData.getPk().getPersoncode() == null)) {
	    tcustPeopleAditionalData.getPk().setPersoncode(personcode);
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleFixedIncome
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeFixedIncome(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleFixedIncome tcustPeopleFixedIncome = (TcustPeopleFixedIncome) object;
	    if ((tcustPeopleFixedIncome != null) && (tcustPeopleFixedIncome.getPk().getPersoncode() == null)) {
		TcustPeopleFixedIncomeKey tcustPeopleFixedIncomeKey = new TcustPeopleFixedIncomeKey();
		tcustPeopleFixedIncomeKey.setPersoncode(personcode);
		tcustPeopleFixedIncomeKey.setFixedincomesequence(tcustPeopleFixedIncome.getPk().getFixedincomesequence());
		tcustPeopleFixedIncome.setPk(tcustPeopleFixedIncomeKey);
	    }
	}
    }

    /**
     * Metodo que se encarga de completar el personcode en la tabla
     * TcustPeopleAssociation
     *
     * @param lDetail
     * @param personcode
     * @throws Exception
     */
    private void completeAssociation(List<Object> lDetail, Integer personcode) throws Exception {
	if (lDetail == null) {
	    return;
	}
	for (Object object : lDetail) {
	    TcustPeopleAssociation tcustPeopleAssociation = (TcustPeopleAssociation) object;
	    if ((tcustPeopleAssociation != null) && (tcustPeopleAssociation.getPk().getPersoncode() == null)) {
		TcustPeopleAssociationKey tcustPeopleAssociationKey = new TcustPeopleAssociationKey();
		tcustPeopleAssociationKey.setPersoncode(personcode);
		tcustPeopleAssociationKey.setAssociationsequence(tcustPeopleAssociation.getPk().getAssociationsequence());
		tcustPeopleAssociation.setPk(tcustPeopleAssociationKey);
	    }
	}
    }
}
