package com.bankaudit.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bankaudit.constants.BankAuditConstant;
import com.bankaudit.dao.MaintReportStandardStmtDao;
import com.bankaudit.dto.DataTableResponse;
import com.bankaudit.dto.DeriveStatementUpdateDto;
import com.bankaudit.dto.process.DeriveStatementDto;
import com.bankaudit.model.MaintReportDerivedStmt;
import com.bankaudit.model.MaintReportStandardStmt;
import com.bankaudit.model.MaintReportStandardStmtHst;
import com.bankaudit.model.MaintReportStandardStmtWrk;

@Service("maintReportStandardStmtService")
@Transactional("transactionManager")
public class MaintReportStandardStmtServiceImpl implements MaintReportStandardStmtService {

	@Autowired
	private MaintReportStandardStmtDao maintReportStandardStmtDao;

	@Autowired
	BusinessDateService businessDateService;

	@Override
	public void createMaintReportStandardStmt(MaintReportStandardStmt maintReportStandardStmt) throws Exception {
		boolean isMappingIdExists = checkMaintReportStandardStmtExsits(maintReportStandardStmt.getLegalEntityCode(),
				maintReportStandardStmt.getMappingId());
		if (!isMappingIdExists) {
			if (maintReportStandardStmt.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
				maintReportStandardStmtDao.save(maintReportStandardStmt);
			} else {
				MaintReportStandardStmtWrk maintReportStandardStmtWrk = new MaintReportStandardStmtWrk();
				BeanUtils.copyProperties(maintReportStandardStmt, maintReportStandardStmtWrk);
				maintReportStandardStmtDao.save(maintReportStandardStmtWrk);
			}
		} else {
			throw new Exception("Same Mapping Id is already exist");
		}
	}

	@Override
	public void updateMaintReportStandardStmt(MaintReportStandardStmt maintReportStandardStmt) {
		if (maintReportStandardStmt.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)) {
			// get Db object and save into the history
			MaintReportStandardStmt maintReportStandardStmtdb = getMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
					maintReportStandardStmt.getMappingId(), BankAuditConstant.STATUS_MOD);
			if (maintReportStandardStmtdb != null) {
				MaintReportStandardStmtHst maintReportStandardStmtHst = new MaintReportStandardStmtHst();
				BeanUtils.copyProperties(maintReportStandardStmtdb, maintReportStandardStmtHst);
				maintReportStandardStmtDao.save(maintReportStandardStmtHst);
			}
			// delete the existing object from both the tables
			maintReportStandardStmtDao.deleteMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
					maintReportStandardStmt.getMappingId(), maintReportStandardStmt.getStatus());
			maintReportStandardStmtDao.deleteMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
					maintReportStandardStmt.getMappingId(), BankAuditConstant.STATUS_MOD);
			maintReportStandardStmtDao.flushSession();
			maintReportStandardStmt.setCheckerTimestamp(maintReportStandardStmt.getBusinessdateTimestamp());
			// save again
			maintReportStandardStmtDao.saveOrUpdate(maintReportStandardStmt);
		} else {
			if (maintReportStandardStmt.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
					|| maintReportStandardStmt.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_MOD)) {
				maintReportStandardStmt.setMakerTimestamp(
						businessDateService.getBusinessDateTimestampByLegalEntityCode(maintReportStandardStmt.getLegalEntityCode()));
			}
			MaintReportStandardStmt maintReportStandardStmtDb = getMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
					maintReportStandardStmt.getMappingId(), maintReportStandardStmt.getStatus());
			if (maintReportStandardStmtDb != null) {
				maintReportStandardStmtDao.flushSession();
				MaintReportStandardStmtHst maintReportStandardStmtHst = new MaintReportStandardStmtHst();
				BeanUtils.copyProperties(maintReportStandardStmtDb, maintReportStandardStmtHst);
				maintReportStandardStmtDao.save(maintReportStandardStmtHst);
			} else {
				MaintReportStandardStmt maintReportStandardStmtmainDb = getMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
						maintReportStandardStmt.getMappingId(), BankAuditConstant.STATUS_AUTH);
				maintReportStandardStmtDao.flushSession();
				MaintReportStandardStmtHst maintReportStandardStmtHst = new MaintReportStandardStmtHst();
				BeanUtils.copyProperties(maintReportStandardStmtmainDb, maintReportStandardStmtHst);
				maintReportStandardStmtDao.save(maintReportStandardStmtHst);
			}
			maintReportStandardStmtDao.deleteMaintReportStandardStmt(maintReportStandardStmt.getLegalEntityCode(),
					maintReportStandardStmt.getMappingId(), maintReportStandardStmt.getStatus());
			MaintReportStandardStmtWrk maintReportStandardStmtWrk = new MaintReportStandardStmtWrk();
			BeanUtils.copyProperties(maintReportStandardStmt, maintReportStandardStmtWrk);
			maintReportStandardStmtDao.flushSession();
			maintReportStandardStmtDao.saveOrUpdate(maintReportStandardStmtWrk);
		}

	}

	@Override
	public MaintReportStandardStmt getMaintReportStandardStmt(Integer legalEntityCode, String mappingId, String status) {
		Map<String, Object> properties = new HashMap<>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("mappingId", mappingId);
		if (BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)) {
			return (MaintReportStandardStmt) maintReportStandardStmtDao.getUniqueEntityByMatchingProperties(MaintReportStandardStmt.class,
					properties);
		} else {
			MaintReportStandardStmt maintReportStandardStmt = null;
			MaintReportStandardStmtWrk maintReportStandardStmtWrk = (MaintReportStandardStmtWrk) maintReportStandardStmtDao
					.getUniqueEntityByMatchingProperties(MaintReportStandardStmtWrk.class, properties);
			if (maintReportStandardStmtWrk != null) {
				maintReportStandardStmt = new MaintReportStandardStmt();
				BeanUtils.copyProperties(maintReportStandardStmtWrk, maintReportStandardStmt);
			}
			return maintReportStandardStmt;
		}
	}

	@Override
	public DataTableResponse getAllMaintReportStandardStmt(Integer legalEntityCode, String search, Integer orderColumn, String orderDirection,
			Integer page, Integer size) {
		return maintReportStandardStmtDao.getAllMaintReportStandardStmt(legalEntityCode, search, orderColumn, orderDirection, page, size);
	}

	@Override
	public void deleteMaintReportStandardStmt(Integer legalEntityCode, String mappingId, String status) {
		maintReportStandardStmtDao.deleteMaintReportStandardStmt(legalEntityCode, mappingId, status);
	}

	@Override
	public boolean checkMaintReportStandardStmtExsits(Integer legalEntityCode, String mappingId) {
		Map<String, Object> properties = new HashMap<>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("mappingId", mappingId);
		MaintReportStandardStmt maintReportStandardStmt = (MaintReportStandardStmt) maintReportStandardStmtDao
				.getUniqueEntityByMatchingProperties(MaintReportStandardStmt.class, properties);
		MaintReportStandardStmtWrk maintReportStandardStmtwrk = (MaintReportStandardStmtWrk) maintReportStandardStmtDao
				.getUniqueEntityByMatchingProperties(MaintReportStandardStmtWrk.class, properties);
		return !(maintReportStandardStmt == null && maintReportStandardStmtwrk == null); 
	}

	@Override
	public MaintReportStandardStmt getMaintReportStandardStmt(Integer legalEntityCode, String mappingId) {
		List<MaintReportStandardStmt> list = maintReportStandardStmtDao.getMaintReportStandardStmtByMappindId(legalEntityCode, mappingId);
		if(list!= null && !list.isEmpty()) {
			return list.get(0);
		}
		return null;
	}
	
	@Override
	public MaintReportStandardStmt getMaintReportStandardStmtWrk(Integer legalEntityCode, String mappingId) {
		List<MaintReportStandardStmt> list = maintReportStandardStmtDao.getMaintReportStandardStmtWrkByMappindId(legalEntityCode, mappingId);
		if(list!= null && !list.isEmpty()) {
			return list.get(0);
		}
		return null;
	}
	
	// Derive statements fetch
	@Override
	public List<DeriveStatementUpdateDto> getDeriveStatementById(Integer legalEntityCode, String statementId, String auditTypeCode) {
		List<DeriveStatementUpdateDto> lst= new ArrayList<DeriveStatementUpdateDto>();
		MaintReportDerivedStmt stmnt= maintReportStandardStmtDao.getMaintReportDerivedStmtById(legalEntityCode, statementId, auditTypeCode);
		if(stmnt!= null ) {
			for(int i=0; i<=27;i++) {
				DeriveStatementUpdateDto dto=new DeriveStatementUpdateDto();
				dto.setLegalEntityCode(legalEntityCode);
				dto.setStatementId(statementId);
				dto.setSlNo(String.valueOf(i));
				dto.setAuditTypeCode(stmnt.getAuditTypeCode());
				if(i==0) {dto.setStatement(stmnt.getDerivedStmt());dto.setOutput("99");}
				else if(i==1) {dto.setStatement(stmnt.getDerivedStmt1());dto.setOutput("111");}
				else if(i==2) {dto.setStatement(stmnt.getDerivedStmt2());dto.setOutput("112");}
				else if(i==3) {dto.setStatement(stmnt.getDerivedStmt3());dto.setOutput("110");}
				else if(i==4) {dto.setStatement(stmnt.getDerivedStmt4());dto.setOutput("121");}
				else if(i==5) {dto.setStatement(stmnt.getDerivedStmt5());dto.setOutput("122");}
				else if(i==6) {dto.setStatement(stmnt.getDerivedStmt6());dto.setOutput("120");}
				else if(i==7) {dto.setStatement(stmnt.getDerivedStmt7());dto.setOutput("101");}
				else if(i==8) {dto.setStatement(stmnt.getDerivedStmt8());dto.setOutput("102");}
				else if(i==9) {dto.setStatement(stmnt.getDerivedStmt9());dto.setOutput("100");}
				
				else if(i==10) {dto.setStatement(stmnt.getDerivedStmt10());dto.setOutput("211");}
				else if(i==11) {dto.setStatement(stmnt.getDerivedStmt11());dto.setOutput("212");}
				else if(i==12) {dto.setStatement(stmnt.getDerivedStmt12());dto.setOutput("210");}
				else if(i==13) {dto.setStatement(stmnt.getDerivedStmt13());dto.setOutput("221");}
				else if(i==14) {dto.setStatement(stmnt.getDerivedStmt14());dto.setOutput("222");}
				else if(i==15) {dto.setStatement(stmnt.getDerivedStmt15());dto.setOutput("220");}
				else if(i==16) {dto.setStatement(stmnt.getDerivedStmt16());dto.setOutput("201");}
				else if(i==17) {dto.setStatement(stmnt.getDerivedStmt17());dto.setOutput("202");}
				else if(i==18) {dto.setStatement(stmnt.getDerivedStmt18());dto.setOutput("200");}
				
				/*else if(i==19) {dto.setStatement(stmnt.getDerivedStmt19());dto.setOutput("011");}
				else if(i==20) {dto.setStatement(stmnt.getDerivedStmt20());dto.setOutput("012");}
				else if(i==21) {dto.setStatement(stmnt.getDerivedStmt21());dto.setOutput("010");}
				else if(i==22) {dto.setStatement(stmnt.getDerivedStmt22());dto.setOutput("021");}
				else if(i==23) {dto.setStatement(stmnt.getDerivedStmt23());dto.setOutput("022");}
				else if(i==24) {dto.setStatement(stmnt.getDerivedStmt24());dto.setOutput("020");}
				else if(i==25) {dto.setStatement(stmnt.getDerivedStmt25());dto.setOutput("001");}
				else if(i==26) {dto.setStatement(stmnt.getDerivedStmt26());dto.setOutput("002");}
				else if(i==27) {dto.setStatement(stmnt.getDerivedStmt27());dto.setOutput("000");}*/
				
				lst.add(dto);
			}
		}
		return lst;
	}
	
	@Override
	public void updateDeriveStatementById(DeriveStatementUpdateDto drvDto) {
		maintReportStandardStmtDao.updateDeriveStatementById(drvDto);
	}

}
