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

import java.sql.SQLException;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpSession;

import qa.gov.moi.erp.core.business.custody.CustodyIssueManager;
import qa.gov.moi.erp.util.dto.MessageDTO;
import qa.gov.moi.erp.util.dto.UserDTO;
import qa.gov.moi.erp.util.exceptions.ERPException;
import qa.gov.moi.erp.util.helpers.DocumentCodes;
import qa.gov.moi.erp.util.helpers.ERPConstants;
import qa.gov.moi.erp.util.helpers.ERPUtility;

import com.isomorphic.datasource.DSRequest;
import com.isomorphic.datasource.DSResponse;
import com.isomorphic.datasource.DataSource;
import com.isomorphic.datasource.Validator;
import com.isomorphic.log.Logger;
import com.isomorphic.rpc.RPCManager;

public class CustodyIssueValidatorDMI
{

    Logger log = new Logger(this.getClass().getName());

    @SuppressWarnings("unchecked")
    public boolean condition(Object value, Validator validator, String fieldName, Map record, DataSource ds, RPCManager rpc, HttpSession session)
            throws Exception
    {
        String methodName = "condition";
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { methodName, " called " }));
        }
        DSRequest dsRequest1 = rpc.getDSRequest();

        if (fieldName.equalsIgnoreCase("II1_ISSUED_QUANTITY"))
        {
            return validateIssuedQuantity(value,validator,fieldName,record,ds,dsRequest1,session);
        }
        else if (fieldName.equalsIgnoreCase("II1_PRODUCT_STATE_V"))
        {
            return validateProductStateValue(value,dsRequest1,validator,session);
        }
        else if (fieldName.equalsIgnoreCase("II1_PRODUCT_NUMBER"))
        {
            if (value != null && value.toString().length() != 0)
            {
                String currectProductNumber = (String)value;
                currectProductNumber = currectProductNumber.trim();

                DSRequest dsRequest = new DSRequest("ProdTree",DataSource.OP_FETCH);
                dsRequest.addToCriteria("PR0_NUMBER",value);
                DSResponse dsResponse = dsRequest.execute();
                List listProducts = dsResponse.getRecords();

                if (listProducts.size() == 1)
                {
                    Map productMap = (Map)listProducts.get(0);

                    // Check whether the product is active or not
                    if ("N".equals((String)productMap.get("PR0_ISACTIVE")))
                    {
                        MessageDTO messageDTO = new MessageDTO();
                        messageDTO.set_messageCode("custody.issue.product.notactive.validation");
                        Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                        String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                        validator.addErrorMessageVariable("product",errMessage);
                        return false;
                    }

                    // Check whether the product is Consumable or not
                    if ("Y".equals((String)productMap.get("PR0_IS_CONSUMABLE")))
                    {
                        MessageDTO messageDTO = new MessageDTO();
                        messageDTO.set_messageCode("custody.issue.product.consumable.validation");
                        Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                        String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                        validator.addErrorMessageVariable("product",errMessage);
                        return false;
                    }
                }
                else
                {
                    MessageDTO messageDTO = new MessageDTO();
                    messageDTO.set_messageCode("custody.issue.product.valid.validation");
                    Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                    String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                    validator.addErrorMessageVariable("product",errMessage);
                    return false;
                }

                String newProd = dsRequest1.getFieldValue("II1_PRODUCT_NUMBER") == null?"":dsRequest1.getFieldValue("II1_PRODUCT_NUMBER").toString().trim();
                String oldProd = dsRequest1.getOldValues().get("II1_PRODUCT_NUMBER") == null?"":dsRequest1.getOldValues().get("II1_PRODUCT_NUMBER").toString()
                        .trim();
                if (!newProd.equalsIgnoreCase(oldProd))
                {
                    if (oldProd != null && oldProd != "")
                    {
                        oldProd = oldProd.trim();
                    }

                    if (oldProd != null && oldProd != "" && !oldProd.equalsIgnoreCase(currectProductNumber))
                    {
                        MessageDTO messageDTO = new MessageDTO();
                        messageDTO.set_messageCode("custody.issue.product.number.update.validation");
                        Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                        String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                        validator.addErrorMessageVariable("product",errMessage);
                        return false;
                    }
                    return true;
                }
            }
        }
        else if (fieldName.equalsIgnoreCase("II1_PRODUCT_SERIAL_NUMBER"))
        {

            String serialNumber = (String)dsRequest1.getFieldValue("II1_PRODUCT_SERIAL_NUMBER");
            String productNumber = (String)dsRequest1.getFieldValue("II1_PRODUCT_NUMBER");

            if (productNumber == null && dsRequest1.getOldValues().containsKey("II1_PRODUCT_NUMBER"))
            {
                productNumber = (String)dsRequest1.getOldValues().get("II1_PRODUCT_NUMBER");
            }

            if (productNumber != null && productNumber != "")
            {
                DSRequest dsRequest = new DSRequest("ProdTree",DataSource.OP_FETCH);
                dsRequest.addToCriteria("PR0_NUMBER",productNumber);
                DSResponse dsResponse = dsRequest.execute();
                List listProducts = dsResponse.getRecords();
                String productId = null;
                boolean isProductWithSerial = false;
                for (int i = 0; i < listProducts.size(); i++)
                {
                    Map productMap = (Map)listProducts.get(i);
                    String prodWithSerial = ERPUtility.removeSpace((String)productMap.get("PR0_IS_SERIAL_DEFINED"));
                    productId = (String)productMap.get("PR0_PRODUCT_ID");
                    if (prodWithSerial.equalsIgnoreCase("Y"))
                    {
                        isProductWithSerial = true;
                    }
                }

                if (isProductWithSerial)
                {
                    boolean result = isProductSerialValid(session,validator,serialNumber,productNumber,productId);
                    if (result)
                    {
                        String oldSerialNumber = null;

                        if (dsRequest1.getOldValues().containsKey("II1_PRODUCT_SERIAL_NUMBER"))
                        {
                            oldSerialNumber = (String)dsRequest1.getOldValues().get("II1_PRODUCT_SERIAL_NUMBER");
                        }

                        if (dsRequest1.getOperationType().equals(DataSource.OP_UPDATE))
                        {
                            if (oldSerialNumber == null || oldSerialNumber == ""
                                    || (oldSerialNumber != null && oldSerialNumber != "" && !oldSerialNumber.equalsIgnoreCase(serialNumber)))
                            {
                                return serialAlreadyExists(serialNumber,dsRequest1,session,validator);
                            }
                            else
                            {
                                MessageDTO messageDTO = new MessageDTO();
                                messageDTO.set_messageCode("custody.issue.serialNumber.valid.validation");
                                Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                                String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                                validator.addErrorMessageVariable("serialNumber",errMessage);
                                return false;
                            }
                        }
                        else if (dsRequest1.getOperationType().equals(DataSource.OP_ADD))
                        {
                            return serialAlreadyExists(serialNumber,dsRequest1,session,validator);
                        }
                        else
                        {
                            return true;
                        }
                    }
                    else
                    {
                        return result;
                    }
                }
            }
            else
            {

                MessageDTO messageDTO = new MessageDTO();
                messageDTO.set_messageCode("custody.issue.product.serial.product.selection.validation");
                Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                validator.addErrorMessageVariable("serialNumber",errMessage);
                return false;
            }

        }
        return true;
    }

    private boolean serialAlreadyExists(String serialNumber, DSRequest dsRequest1, HttpSession session, Validator validator) throws Exception
    {
        String ii1MId = null, ii1MMode = null;

        DSRequest newDSRequest = new DSRequest("TII1_CUSTODY_ISSUE_ITEM_DETAIL",DataSource.OP_FETCH);

        if (dsRequest1.getFieldValue("II1_MID") != null)
        {
            ii1MId = (String)dsRequest1.getFieldValue("II1_MID");
            ii1MMode = (String)dsRequest1.getFieldValue("II1_MMODE");
        }
        else if (dsRequest1.getFieldValue("ParentPrimayKey2") != null)
        {
            ii1MId = (String)dsRequest1.getFieldValue("ParentPrimayKey1");
            ii1MMode = (String)dsRequest1.getFieldValue("ParentPrimayKey2");
        }
        else if (session.getAttribute("ParentPrimayKey2") != null)
        {
            ii1MId = (String)session.getAttribute("ParentPrimayKey1");
            ii1MMode = (String)session.getAttribute("ParentPrimayKey2");
        }
        else if (dsRequest1.getOldValues().containsKey("II1_MID"))
        {
            ii1MId = (String)dsRequest1.getOldValues().get("II1_MID");
            ii1MMode = (String)dsRequest1.getOldValues().get("II1_MMODE");
        }

        newDSRequest.addToCriteria("II1_MID","equals",ii1MId);
        newDSRequest.addToCriteria("II1_MMODE","equals",ii1MMode);
        newDSRequest.addToCriteria("II1_PRODUCT_SERIAL_NUMBER","equals",serialNumber);

        DSResponse newDSResponse = newDSRequest.execute();
        if (newDSResponse.getRecords().size() > 0)
        {
            MessageDTO messageDTO = new MessageDTO();
            messageDTO.set_messageCode("custody.issue.serialNumber.validation");
            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
            validator.addErrorMessageVariable("serialNumber",errMessage);
            return false;
        }
        return true;
    }

    private boolean isProductSerialValid(HttpSession session, Validator validator, String serialNumber, String productNumber, String productId)
            throws ERPException
    {
        try
        {
            List<MessageDTO> messages = null;
            if (serialNumber != null && serialNumber != "")
            {
                CustodyIssueManager custodyIssueManager = new CustodyIssueManager();
                serialNumber = ERPUtility.removeSpace(serialNumber);
                if (productNumber != null && productNumber != "")
                {

                    messages = custodyIssueManager.validateSerialNumber(productId,serialNumber);

                    if (!messages.iterator().next().get_resultCode().equals((DocumentCodes.CUSTODY_ISSUE_CODES.SUCCESS)))
                    {
                        if (messages.iterator().next().get_resultCode().equals((DocumentCodes.CUSTODY_ISSUE_CODES.FAIL_PRODUCT_SERIAL_RELATION)))
                        {
                            MessageDTO messageDTO = new MessageDTO();
                            messageDTO.set_messageCode("custody.issue.serialNumber.valid.validation");
                            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                            validator.addErrorMessageVariable("serialNumber",errMessage);
                            return false;
                        }
                        else if (messages.iterator().next().get_resultCode().equals((DocumentCodes.CUSTODY_ISSUE_CODES.FAIL_PRODUCT_SERIAL_ACTIVE)))
                        {
                            MessageDTO messageDTO = new MessageDTO();
                            messageDTO.set_messageCode("custody.issue.serialNumber.not.active.validation");
                            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                            validator.addErrorMessageVariable("serialNumber",errMessage);
                            return false;
                        }
                        else if (messages.iterator().next().get_resultCode().equals((DocumentCodes.CUSTODY_ISSUE_CODES.FAIL_SERIAL_IN_HOLDING)))
                        {
                            MessageDTO messageDTO = new MessageDTO();
                            messageDTO.set_messageCode("custody.issue.serialNumber.inHolding.validation");
                            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                            validator.addErrorMessageVariable("serialNumber",errMessage);
                            return false;
                        }
                        else
                        {
                            MessageDTO messageDTO = new MessageDTO();
                            messageDTO.set_messageCode("custody.issue.serialNumber.valid.validation");
                            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                            validator.addErrorMessageVariable("serialNumber",errMessage);
                            return false;
                        }
                    }
                    else
                    {

                        return true;
                    }

                }
                else
                {
                    MessageDTO messageDTO = new MessageDTO();
                    messageDTO.set_messageCode("custody.issue.serialNumber.product.valid.validation");
                    Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                    String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                    validator.addErrorMessageVariable("serialNumber",errMessage);
                    return false;
                }
            }
            else
            {
                MessageDTO messageDTO = new MessageDTO();
                messageDTO.set_messageCode("custody.issue.serialNumber.no.serial.validation");
                Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                validator.addErrorMessageVariable("serialNumber",errMessage);
                return false;
            }
        }
        catch (SQLException e)
        {
            MessageDTO messageDTO = new MessageDTO();
            messageDTO.set_messageCode("custody.issue.serialNumber.valid.validation");
            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
            validator.addErrorMessageVariable("serialNumber",errMessage);
            return false;
        }
    }

    private boolean validateProductStateValue(Object value, DSRequest dsRequest1, Validator validator, HttpSession session) throws Exception
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();

        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { methodName, " called " }));
        }

        String prodNumber = (String)dsRequest1.getFieldValue("II1_PRODUCT_NUMBER");

        if (prodNumber == null && dsRequest1.getOldValues().containsKey("II1_PRODUCT_NUMBER"))
        {
            prodNumber = (String)dsRequest1.getOldValues().get("II1_PRODUCT_NUMBER");
        }

        if (prodNumber != null)
        {
            DSRequest productDSRequest = new DSRequest("VPR0_PRODUCT",DataSource.OP_FETCH);
            productDSRequest.addToCriteria("PR0_NUMBER",prodNumber);
            DSResponse productDSResponse = productDSRequest.execute();
            List productsList = productDSResponse.getRecords();

            if (productsList.size() == 1)
            {
                Map productMap = (Map)productsList.get(0);
                String productId = productMap.get("PR0_ID") + "";

                String mId = null, mMode = null;

                if (dsRequest1.getFieldValue("ParentPrimayKey2") != null)
                {
                    mId = (String)dsRequest1.getFieldValue("ParentPrimayKey1");
                    mMode = (String)dsRequest1.getFieldValue("ParentPrimayKey2");
                }
                else
                {
                    mId = (String)dsRequest1.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey1");
                    mMode = (String)dsRequest1.getHttpServletRequest().getSession().getAttribute("ParentPrimayKey2");
                }

                DSRequest parentDSRequest = new DSRequest("TII0_CUSTODY_ISSUE_ITEM_MAIN",DataSource.OP_FETCH);
                parentDSRequest.addToCriteria("II0_ID",mId);
                parentDSRequest.addToCriteria("II0_MODE",mMode);
                DSResponse parentDSResponse = parentDSRequest.execute();
                List parentRecordsList = parentDSResponse.getRecords();
                Map parentRecordMap = (Map)parentRecordsList.get(0);

                DSRequest productQuantityDSRequest = new DSRequest(ERPConstants.TABLES.VPR3_PRODUCT_QUANTITY,DataSource.OP_FETCH);
                productQuantityDSRequest.addToCriteria("PR3_PRODUCT_ID",productId);
                productQuantityDSRequest.addToCriteria("PR3_PRODUCT_STATE_V",value);
                productQuantityDSRequest.addToCriteria("PR3_WAREHOUSE_NUMBER",parentRecordMap.get("II0_WAREHOUSE_NUMBER"));
                DSResponse productQuantityDSResponse = productQuantityDSRequest.execute();
                List productQuantityList = productQuantityDSResponse.getRecords();

                if (productQuantityList.size() == 1)
                {
                    return true;
                }
                else
                {
                    MessageDTO messageDTO = new MessageDTO();
                    messageDTO.set_messageCode("custody.issue.productStateValue.product.combination.validation");
                    Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                    String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                    validator.addErrorMessageVariable("productStateValue",errMessage);
                }

            }
            else
            {
                MessageDTO messageDTO = new MessageDTO();
                messageDTO.set_messageCode("custody.issue.productStateValue.product.valid.validation");
                Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                validator.addErrorMessageVariable("productStateValue",errMessage);
            }
        }
        else
        {
            MessageDTO messageDTO = new MessageDTO();
            messageDTO.set_messageCode("custody.issue.productStateValue.product.productState.validation");
            Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
            String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
            validator.addErrorMessageVariable("productStateValue",errMessage);
        }

        return false;
    }

    @SuppressWarnings("unchecked")
    private boolean validateIssuedQuantity(Object value, Validator validator, String fieldName, Map record, DataSource ds, DSRequest dsRequest1,
            HttpSession session) throws Exception
    {
        String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
        if (log.isDebugEnabled())
        {
            log.debug(ERPUtility.prepareLog(new String[]
            { methodName, "Called" }));
        }

        String prodNumber = (String)dsRequest1.getFieldValue("II1_PRODUCT_NUMBER");

        if (prodNumber == null && dsRequest1.getOldValues().containsKey("II1_PRODUCT_NUMBER"))
        {
            prodNumber = (String)dsRequest1.getOldValues().get("II1_PRODUCT_NUMBER");
        }

        boolean checkSerialQuantity = true;
        if (prodNumber != null)
        {
            DSRequest dsRequest = new DSRequest("ProdTree",DataSource.OP_FETCH);
            dsRequest.addToCriteria("PR0_NUMBER",prodNumber);
            DSResponse dsResponse = dsRequest.execute();
            List listProducts = dsResponse.getRecords();

            for (int i = 0; i < listProducts.size(); i++)
            {
                Map productMap = (Map)listProducts.get(i);
                String isSerial = productMap.get("PR0_IS_SERIAL_DEFINED") + "";
                if (isSerial.equals("Y"))
                {
                    if ((Long)value > 1)
                    {
                        MessageDTO messageDTO = new MessageDTO();
                        messageDTO.set_messageCode("custody.issue.issuedQuantity.validation");
                        Locale userLocale = new Locale((((UserDTO)session.getAttribute("user")).getLang()));
                        String errMessage = ERPUtility.getMessageValues(messageDTO,userLocale);
                        validator.addErrorMessageVariable("issuedQuantity",errMessage);
                        checkSerialQuantity = false;
                    }
                }
            }
        }
        return checkSerialQuantity;
    }
}
