package qa.gov.moi.erp.web.dmi;

import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import qa.gov.moi.erp.core.extejb.ExternalSystemManager;
import qa.gov.moi.erp.core.framework.LookUpManager;
import qa.gov.moi.erp.util.dto.UomDTO;
import qa.gov.moi.erp.util.dto.UserDTO;
import qa.gov.moi.erp.util.exceptions.ERPException;
import qa.gov.moi.erp.util.helpers.ERPConstants;
import qa.gov.moi.erp.util.helpers.ERPUtility;
import qa.gov.moi.erp.web.helpers.ERPWebUtiliy;

import com.isomorphic.datasource.DSRequest;
import com.isomorphic.datasource.DSResponse;
import com.isomorphic.datasource.DataSource;

public class CustodyRequsitionDetailDMI
{

    private Logger log = LoggerFactory.getLogger(CustodyRequsitionDetailDMI.class);

    public DSResponse add(DSRequest dsRequest, HttpServletRequest request) throws Exception
    {
        UserDTO userDTO = (UserDTO)request.getSession().getAttribute("user");
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(userDTO,new String[]
            { methodName + " Called" }));
        }
        Timestamp currentTimeStamp = new Timestamp(Calendar.getInstance().getTime().getTime());
        try
        {
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            LookUpManager lookup = LookUpManager.getInstance();

            dsRequest.setFieldValue("RQ1_ID",uuid);
            dsRequest.setFieldValue("RQ1_MODE",ERPConstants.ModeCode.DRAFT);

            dsRequest.setFieldValue("RQ1_RECEIVER_USER_ID",userDTO.getName());
            dsRequest.setFieldValue("RQ1_CREATED_USER_ID",userDTO.getName());
            dsRequest.setFieldValue("RQ1_CREATED_USER_ROLE",userDTO.getCurrentRole().getName());
            dsRequest.setFieldValue("RQ1_CREATED_USER_SMP",currentTimeStamp);
            dsRequest.setFieldValue("RQ1_LASTUPDATED_USER_ID",userDTO.getName());
            dsRequest.setFieldValue("RQ1_LASTUPDATED_USER_ROLE",userDTO.getCurrentRole().getName());
            dsRequest.setFieldValue("RQ1_LASTUPDATED_USER_SMP",currentTimeStamp);

            if (dsRequest.getFieldValue("ParentPrimayKey1") != null)
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getFieldValue("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getFieldValue("ParentPrimayKey2"));

                if (dsRequest.getValues().get("RQ1_PRODUCT_NUMBER") != null)
                {
                    UomDTO uomDTO = lookup.getUomDTO((String)dsRequest.getValues().get("RQ1_PRODUCT_NUMBER"));
                    dsRequest.setFieldValue("RQ1_PRODUCT_NUMBER",uomDTO.getProductNumber());
                    dsRequest.setFieldValue("RQ1_PRODUCT_UOM_ID",uomDTO.getUomUnit());
                    dsRequest.setFieldValue("PR0_NAME_ARABIC",uomDTO.getProductName());
                    dsRequest.setFieldValue("PR0_DESCRIPTION",uomDTO.getProductDescription());

                    // Fetch the Product Id from the Product Number
                    DSRequest productDSRequest = new DSRequest("PROD_DOCUMENT",DataSource.OP_FETCH,dsRequest.getRPCManager());
                    productDSRequest.addToCriteria("PR0_NUMBER",uomDTO.getProductNumber());
                    DSResponse productDSResponse = productDSRequest.execute();
                    String productId = productDSResponse.getRecord().get("PR0_PRODUCT_ID").toString();
                    log.info("The product Id from the product number " + uomDTO.getProductNumber() + " is " + productId);
                    dsRequest.setFieldValue("RQ1_PRODUCT_ID",productId);
                }
            }
            else
            {
                dsRequest.setFieldValue("RQ1_MID",(String)request.getSession().getAttribute("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",(String)request.getSession().getAttribute("ParentPrimayKey2"));

                if (dsRequest.getValues().get("RQ1_PRODUCT_NUMBER") != null)
                {
                    // Fetch the UOM Data
                    UomDTO uomDTO = lookup.getUomDTO((String)dsRequest.getValues().get("RQ1_PRODUCT_NUMBER"));
                    dsRequest.setFieldValue("RQ1_PRODUCT_NUMBER",uomDTO.getProductNumber());
                    dsRequest.setFieldValue("RQ1_PRODUCT_UOM_ID",uomDTO.getUomUnit());
                    dsRequest.setFieldValue("PR0_NAME_ARABIC",uomDTO.getProductName());
                    dsRequest.setFieldValue("PR0_DESCRIPTION",uomDTO.getProductDescription());

                    // Fetch the Product Id from the Product Number
                    DSRequest productDSRequest = new DSRequest("PROD_DOCUMENT",DataSource.OP_FETCH,dsRequest.getRPCManager());
                    productDSRequest.addToCriteria("PR0_NUMBER",uomDTO.getProductNumber());
                    DSResponse productDSResponse = productDSRequest.execute();
                    String productId = productDSResponse.getRecord().get("PR0_PRODUCT_ID").toString();
                    log.info("The product Id from the product number " + uomDTO.getProductNumber() + " is " + productId);
                    dsRequest.setFieldValue("RQ1_PRODUCT_ID",productId);
                }
            }
            if (dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == null || dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == "#"
                    || dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == "")
            {
                dsRequest.setFieldValue("RQ1_PRODUCT_PKG_ID",null);
            }

            if (dsRequest.getFieldValue("RQ1_ASSIGNEE_TYPE_V") != null)
            {
                ERPWebUtiliy utiliy = new ERPWebUtiliy();
                String assignees[] =
                { "RQ1_ASSIGNEE_TYPE_V", "RQ1_ASSIGNEE_DEPARTMENT", "RQ1_ASSIGNEE_OFFICE_ID", "RQ1_ASSIGNEE_SECTION_ID", "RQ1_ASSIGNEE_UNIT_ID",
                        "RQ1_ASSIGNEE_QIDNO", "RQ1_ASSIGNEE_STAFF_NUMBER", "RQ1_ASSIGNEE_VISA_NUM", "RQ1_ASSIGNEE_RANK" };
                utiliy.clearAssigneeValues(dsRequest,assignees);
            }

            DSRequest requestMain = new DSRequest(ERPConstants.TABLES.CUSTODY_REQUISITION_MAIN,DataSource.OP_UPDATE,dsRequest.getRPCManager());

            requestMain.addToCriteria("RQ0_ID",dsRequest.getFieldValue("RQ1_MID"));
            requestMain.addToCriteria("RQ0_MODE",dsRequest.getFieldValue("RQ1_MMODE"));

            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ID",userDTO.getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ROLE",userDTO.getCurrentRole().getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_SMP",currentTimeStamp);

            requestMain.execute();

        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
        return dsRequest.execute();
    }

    @SuppressWarnings("unchecked")
    public DSResponse fetch(DSRequest dsRequest, HttpServletRequest request) throws Exception
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { methodName + " Called" }));
        }

        DSResponse responseDetail = null;
        try
        {
            if (dsRequest.getCriteriaValue("RQ0_ID") != null)
            {
                dsRequest.addToCriteria("RQ1_MID",dsRequest.getCriteriaValue("RQ0_ID"));
                dsRequest.addToCriteria("RQ1_MMODE",dsRequest.getCriteriaValue("RQ0_MODE"));
            }

            responseDetail = dsRequest.execute();
            List<HashMap<String, String>> responseList = responseDetail.getDataList();
            ExternalSystemManager externalSystemManager = new ExternalSystemManager();
            List<HashMap<String, String>> finalData = externalSystemManager.getAssigneeInformation(responseList,"RQ1_ASSIGNEE_TYPE_V","RQ1_ASSIGNEE_QIDNO",
                    "RQ1_ASSIGNEE_VISA_NUM","RQ1_ASSIGNEE_STAFF_NUMBER","RQ1_ASSIGNEE_RANK",request);
            responseDetail.setData(finalData);

        }
        catch (ERPException e)
        {

            throw new Exception(e.getArg1());

        }
        catch (SQLException e)
        {

            log.error(e.getErrorCode() + "",e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getErrorCode(),e.getMessage()));
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
        return responseDetail;
    }

    public DSResponse update(DSRequest dsRequest) throws Exception
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { methodName + " Called" }));
        }
        try
        {
            LookUpManager lookup = LookUpManager.getInstance();

            if (log.isTraceEnabled())
            {
                log.trace(ERPUtility.prepareLog(new String[]
                { "dsRequest.getValues().get(RQ1_PRODUCT_NUMBER)  ", dsRequest.getValues().get("RQ1_PRODUCT_NUMBER") + "" }));
            }
            Timestamp currentTimeStamp = new Timestamp(Calendar.getInstance().getTime().getTime());
            dsRequest.setFieldValue("RQ1_LASTUPDATED_USER_SMP",currentTimeStamp);

            if (dsRequest.getValues().get("RQ1_PRODUCT_NUMBER") != null)
            {
                // To fetch the UOM Values based on the product id
                UomDTO uomDTO = lookup.getUomDTO((String)dsRequest.getValues().get("RQ1_PRODUCT_NUMBER"));
                dsRequest.setFieldValue("RQ1_PRODUCT_NUMBER",uomDTO.getProductNumber());
                dsRequest.setFieldValue("RQ1_PRODUCT_UOM_ID",uomDTO.getUomUnit());
                dsRequest.setFieldValue("PR0_NAME_ARABIC",uomDTO.getProductName());
                dsRequest.setFieldValue("PR0_DESCRIPTION",uomDTO.getProductDescription());

                // Fetch the Product Id from the Product Number
                DSRequest productDSRequest = new DSRequest("PROD_DOCUMENT",DataSource.OP_FETCH,dsRequest.getRPCManager());
                productDSRequest.addToCriteria("PR0_NUMBER",uomDTO.getProductNumber());
                DSResponse productDSResponse = productDSRequest.execute();
                String productId = productDSResponse.getRecord().get("PR0_PRODUCT_ID").toString();
                log.info("The product Id from the product number " + uomDTO.getProductNumber() + " is " + productId);
                dsRequest.setFieldValue("RQ1_PRODUCT_ID",productId);
            }
            if (dsRequest.getFieldValue("RQ1_ASSIGNEE_TYPE_V") != null)
            {
                ERPWebUtiliy utiliy = new ERPWebUtiliy();
                String assignees[] =
                { "RQ1_ASSIGNEE_TYPE_V", "RQ1_ASSIGNEE_DEPARTMENT", "RQ1_ASSIGNEE_OFFICE_ID", "RQ1_ASSIGNEE_SECTION_ID", "RQ1_ASSIGNEE_UNIT_ID",
                        "RQ1_ASSIGNEE_QIDNO", "RQ1_ASSIGNEE_STAFF_NUMBER", "RQ1_ASSIGNEE_VISA_NUM", "RQ1_ASSIGNEE_RANK" };
                utiliy.clearAssigneeValues(dsRequest,assignees);
            }

            if (dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == null || dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == "#"
                    || dsRequest.getFieldValue("RQ1_PRODUCT_PKG_ID") == "")
            {
                dsRequest.setFieldValue("RQ1_PRODUCT_PKG_ID",null);
            }

            if ((dsRequest.getFieldValue("RQ1_MID") != null) && (dsRequest.getFieldValue("RQ1_MMODE") != null))
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getFieldValue("RQ1_MID"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getFieldValue("RQ1_MMODE"));
            }
            else if (dsRequest.getFieldValue("ParentPrimayKey1") != null)
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getFieldValue("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getFieldValue("ParentPrimayKey2"));
            }
            else if (dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey1") != null
                    && dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey2") != null)
            {
                dsRequest.setFieldValue("RQ1_MID",(String)dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",(String)dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey2"));

            }
            else if ((dsRequest.getOldValues().get("RQ1_MID") != null) && (dsRequest.getOldValues().get("RQ1_MMODE") != null))
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getOldValues().get("RQ1_MID"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getOldValues().get("RQ1_MMODE"));
            }

            DSRequest requestMain = new DSRequest(ERPConstants.TABLES.CUSTODY_REQUISITION_MAIN,DataSource.OP_UPDATE,dsRequest.getRPCManager());

            requestMain.addToCriteria("RQ0_ID",dsRequest.getFieldValue("RQ1_MID"));
            requestMain.addToCriteria("RQ0_MODE",dsRequest.getFieldValue("RQ1_MMODE"));

            UserDTO userDTO = (UserDTO)dsRequest.getHttpServletRequest().getSession().getAttribute("user");

            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ID",userDTO.getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ROLE",userDTO.getCurrentRole().getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_SMP",currentTimeStamp);

            requestMain.execute();

        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }

        return dsRequest.execute();
    }

    public void remove(DSRequest dsRequest, HttpServletRequest request) throws Exception
    {
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { "Called" }));
        }
        String methodName = "remove";
        try
        {
            Timestamp currentTimeStamp = new Timestamp(Calendar.getInstance().getTime().getTime());

            if ((dsRequest.getFieldValue("RQ1_MID") != null) && (dsRequest.getFieldValue("RQ1_MMODE") != null))
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getFieldValue("RQ1_MID"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getFieldValue("RQ1_MMODE"));
            }
            else if (dsRequest.getFieldValue("ParentPrimayKey1") != null)
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getFieldValue("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getFieldValue("ParentPrimayKey2"));
            }
            else if (dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey1") != null
                    && dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey2") != null)
            {
                dsRequest.setFieldValue("RQ1_MID",(String)dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey1"));
                dsRequest.setFieldValue("RQ1_MMODE",(String)dsRequest.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey2"));

            }
            else if ((dsRequest.getOldValues().get("RQ1_MID") != null) && (dsRequest.getOldValues().get("RQ1_MMODE") != null))
            {
                dsRequest.setFieldValue("RQ1_MID",dsRequest.getOldValues().get("RQ1_MID"));
                dsRequest.setFieldValue("RQ1_MMODE",dsRequest.getOldValues().get("RQ1_MMODE"));
            }

            DSRequest requestMain = new DSRequest(ERPConstants.TABLES.CUSTODY_REQUISITION_MAIN,DataSource.OP_UPDATE,dsRequest.getRPCManager());

            requestMain.addToCriteria("RQ0_ID",dsRequest.getFieldValue("RQ1_MID"));
            requestMain.addToCriteria("RQ0_MODE",dsRequest.getFieldValue("RQ1_MMODE"));

            UserDTO userDTO = (UserDTO)dsRequest.getHttpServletRequest().getSession().getAttribute("user");

            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ID",userDTO.getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_ROLE",userDTO.getCurrentRole().getName());
            requestMain.setFieldValue("RQ0_LASTUPDATED_USER_SMP",currentTimeStamp);

            requestMain.execute();
            dsRequest.execute();
        }
        catch (SQLException e)
        {
            log.error(e.getErrorCode() + "",e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getErrorCode(),e.getMessage()));
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
            throw new ERPException(ERPUtility.formatError(this.getClass().getName(),methodName,e.getMessage()));
        }
    }

}
