package com.bankaudit.rest.process.service;

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

import org.jboss.logging.Logger;
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.dto.DataTableResponse;
import com.bankaudit.model.MaintAuditFinding;
import com.bankaudit.model.MaintAuditFindingHst;
import com.bankaudit.model.MaintAuditFindingWrk;
import com.bankaudit.process.model.TaskDetails;
import com.bankaudit.process.model.TaskDetailsHst;
import com.bankaudit.process.model.TaskDetailsWrk;
import com.bankaudit.rest.process.dao.AuditObservationDaoImpl;
import com.bankaudit.rest.process.dao.ReportDao;
import com.bankaudit.rest.process.dao.TaskDetailsDao;
import com.bankaudit.service.BusinessDateService;
import com.bankaudit.service.MaintEntityService;
import com.bankaudit.service.SequenceAppenderService;
import com.bankaudit.service.UserService;
import com.bankaudit.util.BankAuditUtil;


@Service
@Transactional("transactionManager")
public class TaskDetailsServiceImpl implements TaskDetailsService {
	
	static final Logger logger = Logger.getLogger(TaskDetailsServiceImpl.class);
	
	@Autowired(required=true)
	TaskDetailsDao taskDetailsDao;
	
	@Autowired 
	BusinessDateService businessDateService;
	
	@Autowired
	SequenceAppenderService sequenceAppenderService;
	
	@Autowired
	MaintEntityService maintEntityService;
	
	@Autowired
	UserService userService;
	
	@Autowired
	ReportDao reportDao;
	
	@Override
	public DataTableResponse getAssessmentsWithAdviceClosure(int legalEntityCode, String userId, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size, String role) {
		DataTableResponse ds= null;
		try {
			boolean isDeptAsRMD =false;
			List<String> deptList = null;
			List<String> unitList = null;
			logger.info("Inside getAssessmentsWithAdviceClosure .. "+ legalEntityCode+" :: "+userId+" :: "+role);
			if("G6".equalsIgnoreCase(role) || "G1".equalsIgnoreCase(role)) { // for OPS and Management user, allowed to see the data across all units under the Unit below.
				//unitList= getUnitList(legalEntityCode, role,"user", userId); //To get the list on all Units under the logged in User
				unitList = maintEntityService.getSubBranchesGyUserIdOrUnitId(legalEntityCode, "user", userId);
			}else{ // Other than OPS and Management user, allowed to see the data for the particular Unit
				String unitCode= userService.getUnitIdforUser(legalEntityCode, userId);
				unitList = new ArrayList();
				unitList.add(unitCode);
			}
			if("G3".equalsIgnoreCase(role))
				isDeptAsRMD = true;
			else {
				isDeptAsRMD = reportDao.isDeptAsRMD(legalEntityCode, role, userId);
				if(!isDeptAsRMD) 
					deptList =reportDao.getDeptList(legalEntityCode, role, userId);
			}
			logger.info("isDeptAsRMD .. "+isDeptAsRMD +" deptList .."+ deptList);
			logger.info("unitList :: "+unitList.size()+ ":: "+unitList);
			ds=taskDetailsDao.getAssessmentsWithAdviceClosure(legalEntityCode,userId,search,orderColumn,orderDirection,page,size,isDeptAsRMD, unitList, deptList);
		}catch(Exception e) {
			e.printStackTrace(System.out);
		}
		return ds;
	}
	
	@Override
	public DataTableResponse getTaskListAssessmentWise(int legalEntityCode,String planId, String auditId, String userId, String search, Integer orderColumn,
			String orderDirection, Integer page, Integer size) {
		DataTableResponse ds=taskDetailsDao.getTaskListAssessmentWise(legalEntityCode,planId,auditId,userId,search,orderColumn,
				orderDirection,page,size);
		return ds;
	}
	
	
	public List<TaskDetails> getTaskDetails(Integer legalEntityCode, String auditId, String observationId, String recStatus){
		List<TaskDetails> taskDetailsLst =null;
		try {
			taskDetailsLst = taskDetailsDao.getTaskDetails(legalEntityCode, auditId, observationId, recStatus);
		}catch(Exception e) {
			
		}return taskDetailsLst;
	}
	
	@Override
	public TaskDetails getTaskById(Integer legalEntityCode,String id, String auditId, String observationId, String status) {
		Map<String,Object> properties=new HashMap<String, Object>();
		properties.put("legalEntityCode", legalEntityCode);
		properties.put("id",Integer.parseInt(id));
		TaskDetails taskDetails=null;
		try {
			logger.info("getTaskById .. "+ id);
		if(!BankAuditConstant.STATUS_AUTH.equalsIgnoreCase(status)){
			
			TaskDetailsWrk taskDetailsWrk =(TaskDetailsWrk) taskDetailsDao.getUniqueEntityByMatchingProperties(TaskDetailsWrk.class, properties);
			if(taskDetailsWrk!=null){
				taskDetails=new TaskDetails();
				BeanUtils.copyProperties(taskDetailsWrk, taskDetails);
			}
			
		}else {
			taskDetails= (TaskDetails) taskDetailsDao.getUniqueEntityByMatchingProperties(TaskDetails.class, properties);
		}
		}catch(Exception e) {
			e.printStackTrace(System.out);
		}
		logger.info("taskDetails .."+taskDetails);
		return taskDetails;
	}
	
	
	@Override
	public void deleteUnauthRejTaskDetails(TaskDetails taskDetails) { // Delete the Task which are UnAuth or Rejected mode.
		try {
			logger.info("deleteUnauthRejTaskDetails .. "+ taskDetails.getStatus());
			// get Db object and save into the history
			TaskDetails taskDetailsDb= getTaskById(taskDetails.getLegalEntityCode(), taskDetails.getId()+"",taskDetails.getAuditId(),taskDetails.getObservationId(), BankAuditConstant.STATUS_AUTH);
			if(taskDetailsDb!=null){
				TaskDetailsHst taskDetailsHst=new TaskDetailsHst();
				BeanUtils.copyProperties(taskDetailsDb, taskDetailsHst);
				taskDetailsDao.save(taskDetailsHst);
			}
			// delete from work
			taskDetailsDao.deleteTaskDetailsByIdAndStatus(taskDetails.getLegalEntityCode(), taskDetails.getId()+"",BankAuditConstant.STATUS_UNAUTH);
			
		}catch(Exception e) {
			e.printStackTrace(System.out);
		}
	}
	
	@Override
	public void updateTaskDetails(TaskDetails taskDetails) {

		try {
			logger.info("updateTaskDetails .. "+ taskDetails.getStatus());
			if(!taskDetails.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_AUTH)){  // For Modidy case
	
				if(taskDetails.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_UNAUTH)
						|| taskDetails.getStatus().equalsIgnoreCase(BankAuditConstant.STATUS_MOD)){
					taskDetails.setMakerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(taskDetails.getLegalEntityCode()));
				}
	
				// get Db object and save into the history
				TaskDetails taskDetailsDb=getTaskById(taskDetails.getLegalEntityCode(), taskDetails.getId()+"",taskDetails.getAuditId(),taskDetails.getObservationId(), BankAuditConstant.STATUS_UNAUTH);
				
				if(taskDetailsDb!=null){ // Copy from Wrk and Insert into Hst
					TaskDetailsHst taskDetailsHst=new TaskDetailsHst();
					BeanUtils.copyProperties(taskDetailsDb, taskDetailsHst);
					taskDetailsDao.save(taskDetailsHst);
				}
				
				TaskDetailsWrk taskDetailsWrk=new TaskDetailsWrk();
				BeanUtils.copyProperties(taskDetails, taskDetailsWrk); // Insert/Update into Wrk
				taskDetailsDao.flushSession();
				
				taskDetailsDao.saveOrUpdate(taskDetailsWrk);
				
			}else{
	
				// get Db object and save into the history
				TaskDetails taskDetailsDb= getTaskById(taskDetails.getLegalEntityCode(), taskDetails.getId()+"",taskDetails.getAuditId(),taskDetails.getObservationId(), BankAuditConstant.STATUS_AUTH);
				if(taskDetailsDb!=null){
					TaskDetailsHst taskDetailsHst=new TaskDetailsHst();
					BeanUtils.copyProperties(taskDetailsDb, taskDetailsHst);
					taskDetailsDao.save(taskDetailsHst);
				}
	
				// delete from work
				taskDetailsDao.deleteTaskDetailsByIdAndStatus(taskDetails.getLegalEntityCode(), taskDetails.getId()+"",BankAuditConstant.STATUS_UNAUTH);
				
				// save into the Master Table  
				taskDetailsDao.flushSession();
				taskDetails.setCheckerTimestamp(businessDateService.getBusinessDateTimestampByLegalEntityCode(taskDetails.getLegalEntityCode()));
				taskDetailsDao.saveOrUpdate(taskDetails);
			}
	
		}catch(Exception e) {
			e.printStackTrace(System.out);
		}
	}
}
