package com.fp.general.score.save;

import java.io.File;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;

import com.fp.common.exception.ExceptionHandler;
import com.fp.common.helper.BeanManager;
import com.fp.common.logger.APPLogger;
import com.fp.dto.save.SaveRequest;
import com.fp.loan.exception.LoanException;
import com.fp.persistence.commondb.NestedSave;
import com.fp.persistence.commondb.PersistenceHelper;
import com.fp.persistence.commondb.PersistenceManager;
import com.fp.persistence.commondb.data.SessionData;
import com.fp.persistence.commondb.data.ThreadFacade;
import com.fp.persistence.pgeneral.score.TgeneScoreAdjustment;
import com.fp.persistence.pgeneral.score.TgeneScoreAdjustmentKey;
import com.fp.persistence.pgeneral.score.TgeneScoreFileIssues;
import com.fp.persistence.pgeneral.score.TgeneScoreFileIssuesKey;
import com.fp.persistence.pgeneral.score.TgeneScoreHeader;
import com.fp.persistence.pgeneral.score.TgeneScoreHeaderKey;


/**
 * Clase que se encarga de procesar una linea de archivo con información de pagos de créditos procedente de una canal de
 * recaudación
 * 
 * @author Omar Villanueva
 * @version 2.1
 */
public class UploadLineScoreThread extends Thread {

    private final Integer company;

    /* Arvhivo a procesar */
    private final File file;

    /* Institución financiera a la que pertenece el archivo */
   // private final String bank;

   /* Número de Operación */
    private final String account;
    
    /* Linea del archivo a procesar */
    private final String line;

    /* Número de linea que se esta procesando */
    private final int sequence;

    private final Timestamp realDate;

    /* Fecha de pago de la cuota del crédito */
    //private final Date paymentDate;

    /* Fecha de calififación */
    private final Date scoreDate;
    
    private final SaveRequest sr;
    
    /**
     * Constructor
     * 
     * @param company
     * @param file
     * @param account
     * @param line
     * @param sequence
     * @param realDate
     * @param scoreDate
     */
    public UploadLineScoreThread(Integer company, File file, String account, String line, int sequence, Timestamp realDate, Date scoreDate, SaveRequest sr) {
        super();
        this.company = company;
        this.file = file;
        this.account = account;
        this.line = line;
        this.sequence = sequence;
        this.realDate = realDate;
        this.scoreDate = scoreDate;
        this.sr=sr;
    }

    @Override
    public void run() {
        try {
            SessionData s = new SessionData();
            s.setCompany(company);
            ThreadFacade.setSaveRequest(s);
            PersistenceHelper.setEntityManager(PersistenceManager.getInstance().createEntityManagerLocal());
            PersistenceHelper.beginNewTransaction();
            /* Procesar la linea de archivo */
            process();
            PersistenceHelper.commitNewTransaction();
        } catch (Exception e) {
            PersistenceHelper.rollbackNewTransaction();
            ExceptionHandler eh = new ExceptionHandler(e, "es");
            APPLogger.getLogger().error("codigo ==>" + eh.getCode());
            APPLogger.getLogger().error("user ==>" + eh.getUserMessage());
            APPLogger.getLogger().error("technical ==>" + eh.getTechnicalMessage());
            APPLogger.getLogger().error("stacktrace ==>" + eh.getStackTrace());
            try {
                /* Guarda en TLOANPAYMENTBANKISSUES información de las lineas con problemas */
                LogUploadIssues(eh);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        } finally {
            PersistenceHelper.closeSession();
        }
    }

    /**
     * Método que procesa la linea de archivo. Carga la data en la tabla TLOANPAYMENTBANKPROCESS
     * 
     * @throws Exception
     */
    private void process() throws Exception {
              processSP();
              processHeader();
    }

     /**
     * Método que procesa las lineas de archivos
     * 
     * @throws Exception
     */
    private void processSP() throws Exception {
        String data[] = line.split("\t");
        //TGENESCOREADJUSTMENT
        TgeneScoreAdjustmentKey key1 = new TgeneScoreAdjustmentKey();
        key1.setAccount(data[1].trim());
        key1.setCompanycode(company);
        key1.setDateto(realDate);
        key1.setScoredate(new Timestamp (getDateByFormat(data[0].trim(), "dd/MM/yyyy").getTime())); 

        TgeneScoreAdjustment tgsa = new TgeneScoreAdjustment();
        tgsa.setPk(key1);
        tgsa.setAdjustmenttype("F");
        tgsa.setCurrencycode(data[5].trim());
        tgsa.setDatefrom(realDate);
        tgsa.setJournalid(sr.getJournalId());
        tgsa.setManualprovisionpercent(new BigDecimal(data[6].trim()));
        tgsa.setModulecode(data[2].trim());
        tgsa.setProductcode(data[3].trim());
        tgsa.setSubproductcode(data[4].trim());
        tgsa.setFilename(file.getName());
        tgsa.setStatus("C"); // ESTADO CARGADO
        
        PersistenceHelper.save(tgsa);
    }

    
     /**
     * Método que ingresa cabecera en tabla: TGENESCOREHEADER
     * 
     * @throws Exception
     */
    private void processHeader() throws Exception {
        String data[] = line.split("\t");
        TgeneScoreHeader scoreHeader = new TgeneScoreHeader();
        TgeneScoreHeaderKey scoreHeaderKey = new TgeneScoreHeaderKey();
        
        scoreHeaderKey.setCompanycode(company);
        scoreHeaderKey.setScoredate(getDateByFormat(data[0].trim(), "dd/MM/yyyy"));
        scoreHeader.setPk(scoreHeaderKey);
        scoreHeader.setFilecode(300);
        scoreHeader.setTabulated("N");
              
        PersistenceHelper.saveOrUpdate(scoreHeader);
    }
    
    
     /**
     * Método que devuelve la fecha según el formato requerido
     * 
     * @param pStrDate
     * @param pFormat
     * @return
     * @throws Exception
     */
    private Date getDateByFormat(String pStrDate, String pFormat) throws Exception {
        Date date = null;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pFormat);
            date = new Date(simpleDateFormat.parse(pStrDate).getTime());
        } catch (Exception e) {
            throw new LoanException("LOAN-0038", "FECHA INCORRECTAMENTE DEFINIDA EN TLOANPAYMENTACCOBANK PARA INSTITUCIÓN FINANCIERA: {0}", account);
        }

        return date;
        
    }

    /**
     * Método que guarda un log de las lineas de archivos que no pueden ser procesadas en la tabla
     * TGENESCOREFILEISSUES
     * 
     * @param eh
     * @throws Exception
     * @throws Exception
     */
    private void LogUploadIssues(ExceptionHandler eh) throws Exception {
        TgeneScoreFileIssuesKey key1 = new TgeneScoreFileIssuesKey();
        key1.setLinenumber(sequence);
        key1.setAccount(account);
        key1.setCompany(company);
        key1.setFilename(file.getName());
        key1.setUploaddate(realDate);
        
        TgeneScoreFileIssues scoreIssue = new TgeneScoreFileIssues();
        scoreIssue.setPk(key1);
        scoreIssue.setLinecontent(line);
             

        if (eh.getUserMessage().length() > 100) {
            scoreIssue.setUsermessage(eh.getUserMessage().substring(0, 100));
        } else {
            scoreIssue.setUsermessage(eh.getUserMessage());
        }
        if (eh.getTechnicalMessage().length() > 500) {
            scoreIssue.setTechnicalmessage(eh.getTechnicalMessage().substring(0, 500));
        } else {
            scoreIssue.setTechnicalmessage(eh.getTechnicalMessage());
        }

        new NestedSave(company, scoreIssue).start();
    }

}
