/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 */

package com.queplix.qwoss.client.frames.mainframe;


import com.queplix.core.client.app.rpc.RPC;
import com.queplix.core.client.app.rpc.RPC.QAsyncCallback;
import com.queplix.core.client.app.vo.DateFieldData;
import com.queplix.core.client.app.vo.EntityReferenceData;
import com.queplix.core.client.app.vo.FamgMeta;
import com.queplix.core.client.app.vo.FieldData;
import com.queplix.core.client.app.vo.ListboxFieldData;
import com.queplix.core.client.app.vo.MemoFieldData;
import com.queplix.core.client.app.vo.MessageReadFlagRequest;
import com.queplix.core.client.app.vo.MetaData;
import com.queplix.core.client.app.vo.TextboxFieldData;
import com.queplix.core.client.common.StringUtil;
import com.queplix.core.client.common.ui.DialogHelper;
import com.queplix.core.client.frames.email.EmailComposeDialog;
import com.queplix.core.client.frames.email.EmailComposeHelper;
import com.queplix.core.client.frames.htmledit.HtmlEditFrame;
import com.queplix.core.client.frames.mainframe.FormOperations;
import com.queplix.core.client.frames.mainframe.FormState;
import com.queplix.core.client.frames.mainframe.OperationContext;
import com.queplix.core.client.frames.mainframe.OperationTypes;
import com.queplix.qwoss.client.app.rpc.CustomRPC;

import java.util.Collection;
import java.util.HashMap;

/**
 * Description:
 *
 * @author Ladnev Ilya
 * @since 06-Mar-2007
 */
final class MyQueueHandler extends OSSOperationStrategy {
    private static final String TICKET_ID_CAPTION = "Ticket : ";
    private static final String INTERACTION_ID_CAPTION = "Interaction : ";

    private static final String INBOX_REPLY_BUTTON = "FORM_INBOX_REPLY";
    private static final String INBOX_FORWARD_BUTTON = "FORM_INBOX_FORWARD";
    private static final String INBOX_OPEN_BUTTON = "FORM_INBOX_OPEN_OBJECT";

    private static final String INBOX_MSG_TYPE_FIELD = "message_type";
    private static final String INBOX_MSG_SENDER_EMAIL_FIELD
            = "message_sender_email";
    private static final String INBOX_EMAIL_TO_FIELD = "email_to";
    private static final String INBOX_EMAIL_CC_FIELD = "email_cc";
    private static final String INBOX_SUBJCT_FIELD = "subject";
    private static final String INBOX_MESSAGE_FIELD = "message";
    private static final String INBOX_SENT_DATE_FIELD = "sent_date";
    private static final String INBOX_OBJ_TYPE_FIELD = "object_type";
    private static final String INBOX_OBJ_ID_FIELD = "object_id";
    private static final String INBOX_ACCOUNT_ID_FIELD = "account_id";

    private static final String TICKET_ID = "qw_ticketid";
    private static final String INTERACTION_ID = "qw_interactionid";
    private static final String OBJECT_TYPE = "object_type";
    private static final String OBJECT_ID = "object_id";

    private static final int INTERACTION = 1;
    private static final int TICKET = 2;
    private HashMap initVals;

    //events
//    private static final String CUSTOM_DELETE = "delete_custom";

    public static final int UNKNOWN_MESSAGE = -1;
    public static final int EMAIL_MESSAGE = 0;
    public static final int ALERT_MESSAGE = 1;

    private final int REPLY_TYPE = 0;
    private final int FORWARD_TYPE = 1;

    private ReplyComposeDialog replyDialog;
    private EmailComposeDialog forwardDialog;

    /*
     * Ticket and Interaction form ids
     * It should initialized in HandlerFactory or it's siblings
     */
    private String ticketFormId, interFormId;

    private int getMessageType(FamgMeta.Index form) {
        FieldData msgType = getOperationContext().getFormOperations()
                .getFieldData(
                        form, INBOX_MSG_TYPE_FIELD);
        if(!msgType.isEmpty()) {
            return Integer.parseInt(((TextboxFieldData) msgType).getText());
        } else {
            return UNKNOWN_MESSAGE;
        }
    }

    public void handleCustomButtonEvent(String buttonId) {
        FamgMeta.Index formIndex = getFormIndex();
        if(buttonId.equalsIgnoreCase(INBOX_REPLY_BUTTON)) {
            switch(getOperationContext().getFormOperations().getFormState(
                    formIndex)) {
                case FormState.SELECTED_STATE:
                    switch(getMessageType(formIndex)) {
                        case EMAIL_MESSAGE:
                            replyClick(formIndex);
                            return;
                        case ALERT_MESSAGE:
                        default:
                            DialogHelper.showModalMessageDialog(
                                    "This button is available only for email messages.");
                            return;
                    }
                default:
                    DialogHelper.showModalMessageDialog(
                            "This button is available only in SELECTED state.");
            }
        } else if(buttonId.equalsIgnoreCase(INBOX_FORWARD_BUTTON)) {
            switch(getOperationContext().getFormOperations().getFormState(
                    formIndex)) {
                case FormState.SELECTED_STATE:
                    switch(getMessageType(formIndex)) {
                        case EMAIL_MESSAGE:
                            forwardClick(formIndex);
                            return;
                        case ALERT_MESSAGE:
                        default:
                            DialogHelper.showModalMessageDialog(
                                    "This button is available only for email messages.");
                            return;
                    }
                default:
                    DialogHelper.showModalMessageDialog(
                            "This button is available only in SELECTED state.");
            }
        } else if(buttonId.equalsIgnoreCase(INBOX_OPEN_BUTTON)) {
            switch(getOperationContext().getFormOperations().getFormState(
                    formIndex)) {
                case FormState.SELECTED_STATE:
                    openClick(formIndex);
                    return;
                default:
                    DialogHelper.showModalMessageDialog(
                            "This button is available only in SELECTED state.");
            }
        }
    }

    public void deleteRecord(Collection rowIds) {
        RPC.QAsyncCallback callback = new CreateDeleteAsyncCallback(
                getFormIndex());
        CustomRPC.getCustomRPC().deleteInbox(rowIds, callback);
    }

    private void openClick(FamgMeta.Index formIndex) {
        FormOperations context = getOperationContext().getFormOperations();
        Long recordId = context.getSelectedRecordId(getFormIndex());
        MessageReadFlagRequest request = 
                        new MessageReadFlagRequest(recordId.longValue(), true);
        RPC.getRPC().setMessageReadFlag(request, new QAsyncCallback(){
            public void onRequestEnded(boolean success, Object result) {
            }
        });
        ListboxFieldData objectType = (ListboxFieldData) context.getFieldData(
                formIndex, OBJECT_TYPE);
        long[] selIDs = objectType.getItemsSelected().getSelectedIDs();
        int selectedType = (int) selIDs[0];
        TextboxFieldData objectId = (TextboxFieldData) context.getFieldData(
                formIndex, OBJECT_ID);
        String selectedObjId = objectId.getText();
        MetaData metaData = getOperationContext().getMetaData();
        FamgMeta.Index searchFormIndex = null;

        switch(selectedType) {
            case INTERACTION: {
                TextboxFieldData data = new TextboxFieldData(INTERACTION_ID,
                        selectedObjId);
                searchFormIndex = (FamgMeta.Index) metaData.getIndexByID(
                        interFormId);
                getOperationContext().getGridOperations().activateGrid(
                        searchFormIndex);
                context.activateForm(searchFormIndex);
                context.clearForm(searchFormIndex, true);
                context.setFieldData(searchFormIndex, data);
                break;
            }
            case TICKET: {
                TextboxFieldData data = new TextboxFieldData(TICKET_ID,
                        selectedObjId);
                searchFormIndex = (FamgMeta.Index) metaData.getIndexByID(
                        ticketFormId);
                getOperationContext().getGridOperations().activateGrid(
                        searchFormIndex);
                context.activateForm(searchFormIndex);
                context.clearForm(searchFormIndex, true);
                context.setFieldData(searchFormIndex, data);
                break;
            }
        }
        //performSearch(searchFormIndex);
        getOperationContext().performOperation(OperationTypes.SEARCH_RECORDS,
                searchFormIndex);
        getOperationContext().checkMailStatus();
    }

    //private void performSearch(FamgMeta.Index searchFormIndex) {
    //    //perform search
    //    getOperationContext().performOperation(OperationTypes.SEARCH_RECORDS, searchFormIndex);
    //}

    private void composeAnswer(int answerType, FamgMeta.Index form) {
        initVals = new HashMap();
        FormOperations context = getOperationContext().getFormOperations();

        FieldData senderMailFld = context.getFieldData(form,
                INBOX_MSG_SENDER_EMAIL_FIELD);
        FieldData toFld = context.getFieldData(form,
                INBOX_EMAIL_TO_FIELD);
        FieldData ccFld = context.getFieldData(form,
                INBOX_EMAIL_CC_FIELD);
        FieldData subjectFld = context.getFieldData(form, INBOX_SUBJCT_FIELD);
        FieldData messageFld = context.getFieldData(form, INBOX_MESSAGE_FIELD);
        FieldData sentDateFld = context.getFieldData(form,
                INBOX_SENT_DATE_FIELD);
        FieldData objTypeFld = context.getFieldData(form,
                INBOX_OBJ_TYPE_FIELD);
        FieldData objIdFld = context.getFieldData(form, INBOX_OBJ_ID_FIELD);
        FieldData accountIdFld = context.getFieldData(form,
                INBOX_ACCOUNT_ID_FIELD);

        String senderMail = "";
        String emailTo = "";
        String emailCc = "";
        String sentDate = "";
        String oldSubject = "";
        if(!senderMailFld.isEmpty()) {
            senderMail = ((TextboxFieldData) senderMailFld).getText();
        }
        if(!toFld.isEmpty()) {
            emailTo = ((TextboxFieldData) toFld).getText();
        }
        if(!ccFld.isEmpty()) {
            emailCc = ((TextboxFieldData) ccFld).getText();
        }
        if(!sentDateFld.isEmpty()) {
            sentDate = ((DateFieldData) sentDateFld).getFormatedDate();
        }
        if(!subjectFld.isEmpty()) {
            oldSubject = ((TextboxFieldData) subjectFld).getText();
        }

        String newBody = "<br><hr><b>From: </b>" + senderMail
                + "<br><b>Sent: </b>" + sentDate +
                "<br><b>To: </b>" + emailTo + "<br><b>Cc: </b>" + emailCc +
                "<br><b>Subject: </b>" + oldSubject + "<br>";
        if(!messageFld.isEmpty()) {
            String oldBody = ((MemoFieldData) messageFld).getText();
            if(!StringUtil.isStringEmpty(oldBody)) {
                if(!HtmlEditFrame.isHTML(oldBody)) {
                    newBody = "\n------------- Original message -------------" +
                            StringUtil.htmlToText(newBody);
                }
                newBody += oldBody;
            } else {
                newBody += HtmlEditFrame.HTML_INDICATOR;
            }
        } else {
            newBody += HtmlEditFrame.HTML_INDICATOR;
        }

        AccountReplyEmailAsyncCallback callback;
        switch(answerType) {
            case REPLY_TYPE:
                String newSubject = "";
                if(objTypeFld.isEmpty() || objIdFld.isEmpty()) {
                    DialogHelper.showModalMessageDialog(
                            "Can't proceed message with empty object id or object type.");
                    return;
                }
                int objectType = (int) ((ListboxFieldData) objTypeFld)
                        .getItemsSelected().getSelectedIDs()[0];
                long objectId = Long.parseLong(
                        ((TextboxFieldData) objIdFld).getText());
                if(objectType == OperationsHelper.TICKET_OBJECT_TYPE) {
                    newSubject = TICKET_ID_CAPTION + objectId;
                } else
                if(objectType == OperationsHelper.INTERACTION_OBJECT_TYPE) {
                    newSubject = INTERACTION_ID_CAPTION + objectId;
                }
                newSubject = ("RE: QueWeb " + newSubject + " : " + oldSubject)
                        .substring(0, 255);
                initVals.put(EmailComposeHelper.TO_MAP_FIELD, senderMail);
                initVals.put(EmailComposeHelper.SUBJECT_MAP_FIELD, newSubject);
                initVals.put(EmailComposeHelper.BODY_MAP_FIELD, newBody);
                if(replyDialog == null) {
                    replyDialog = new ReplyComposeDialog();
                }
                callback = new AccountReplyEmailAsyncCallback(objectType,
                        objectId);
                break;
            case FORWARD_TYPE:
                initVals.put(EmailComposeHelper.SUBJECT_MAP_FIELD,
                        "FW: " + oldSubject);
                initVals.put(EmailComposeHelper.BODY_MAP_FIELD, newBody);
                if(forwardDialog == null) {
                    forwardDialog = new EmailComposeDialog(
                            "Forward Compose Form", false, true);
                }
                callback = new AccountReplyEmailAsyncCallback();
                break;
            default:
                DialogHelper.showModalMessageDialog("Unsupported answer type.");
                return;
        }
        if(!accountIdFld.isEmpty()) {
            Long accId = ((EntityReferenceData) accountIdFld)
                    .getSelectedRowID();
            if(accId != null) {
                CustomRPC.getCustomRPC().getAccountReplyEmail(accId, callback);
            }
        }
    }

    private void forwardClick(FamgMeta.Index form) {
        composeAnswer(FORWARD_TYPE, form);
    }

    private void replyClick(FamgMeta.Index form) {
        composeAnswer(REPLY_TYPE, form);
        /*initVals = new HashMap();
        QFormModel qFormModel = form.getModel();
        FieldData senderMailFld = qFormModel.getElementData(INBOX_MSG_SENDER_EMAIL_FIELD);
        FieldData toFld = qFormModel.getElementData(INBOX_EMAIL_TO_FIELD);
        FieldData ccFld = qFormModel.getElementData(INBOX_EMAIL_CC_FIELD);
        FieldData subjectFld = qFormModel.getElementData(INBOX_SUBJCT_FIELD);
        FieldData messageFld = qFormModel.getElementData(INBOX_MESSAGE_FIELD);
        FieldData sentDateFld = qFormModel.getElementData(INBOX_SENT_DATE_FIELD);
        FieldData objTypeFld = qFormModel.getElementData(INBOX_OBJ_TYPE_FIELD);
        FieldData objIdFld = qFormModel.getElementData(INBOX_OBJ_ID_FIELD);
        FieldData accountIdFld = qFormModel.getElementData(INBOX_ACCOUNT_ID_FIELD);
        if(objTypeFld.isEmpty() || objIdFld.isEmpty()){
            DialogHelper.showModalMessageDialog("Can't send reply with empty object id or object type.");
            return EMPTY_BREAK_RESPONSE;
        }
        int objectType = (int)((ListboxFieldData)objTypeFld).getItemsSelected().getSelectedIDs()[0];
        long objectId = Long.parseLong( ((TextboxFieldData)objIdFld).getText() );
        String senderMail = "";
        if(!senderMailFld.isEmpty()){
            senderMail = ((TextboxFieldData)senderMailFld).getText();
            initVals.put(EmailComposeHelper.TO_MAP_FIELD, senderMail);
        }
        String emailTo = "";
        String emailCc = "";
        String sentDate = "";
        String oldSubject = "";
        if(!toFld.isEmpty()){
            emailTo = ((TextboxFieldData)toFld).getText();
        }
        if(!ccFld.isEmpty()){
            emailCc = ((TextboxFieldData)ccFld).getText();
        }
        if(!sentDateFld.isEmpty()){
            sentDate = ((DateFieldData)sentDateFld).getFormatedDate();
        }
        if(!subjectFld.isEmpty()){
            oldSubject = ((TextboxFieldData)subjectFld).getText();
        }
        String newSubject = "";
        if(objectType == HandlerHelper.TICKET_OBJECT_TYPE)
            newSubject = HandlerHelper.TICKET_ID_CAPTION + objectId;
        else if(objectType == HandlerHelper.INTERACTION_OBJECT_TYPE)
            newSubject = HandlerHelper.INTERACTION_ID_CAPTION + objectId;
        newSubject = ("RE: QueWeb "+newSubject+" : "+oldSubject).substring(0,255);
        initVals.put(EmailComposeHelper.SUBJECT_MAP_FIELD, newSubject);
        String newBody = "<br><hr><b>From: </b>"+senderMail+"<br><b>Sent: </b>"+sentDate+
                         "<br><b>To: </b>"+emailTo+"<br><b>Cc: </b>"+emailCc+
                         "<br><b>Subject: </b>"+oldSubject+"<br>";
        if(!messageFld.isEmpty()){
            String oldBody = ((MemoFieldData)messageFld).getText();
            if(!StringUtil.isStringEmpty(oldBody)){
                if(!HtmlEditFrame.isHTML(oldBody))
                    newBody = "\n------------- Original message -------------"+
                                StringUtil.htmlToText(newBody);
                newBody += oldBody;
            }
            else
                newBody += HtmlEditFrame.HTML_INDICATOR;
        }
        else
            newBody += HtmlEditFrame.HTML_INDICATOR;
        initVals.put(EmailComposeHelper.BODY_MAP_FIELD, newBody);
        if(replyDialog == null){
            replyDialog = new ReplyComposeDialog();
        }
        if(!accountIdFld.isEmpty()){
             Long accId = ((EntityReferenceData)accountIdFld).getSelectedRowID();
             if(accId != null ){
                 AccountReplyEmailAsyncCallback callback = new AccountReplyEmailAsyncCallback(objectType, objectId);
                 CustomRPC.getCustomRPC().getAccountReplyEmail(accId, callback);
             }
        }*/
        //return EMPTY_CONTINUE_RESPONSE;
    }

    private class AccountReplyEmailAsyncCallback extends RPC.QAsyncCallback {
        int objectType = -1;
        long objectId = -1;
        int answerType;

        public AccountReplyEmailAsyncCallback(int objType, long objId) {
            objectType = objType;
            objectId = objId;
            answerType = REPLY_TYPE;
        }

        public AccountReplyEmailAsyncCallback() {
            answerType = FORWARD_TYPE;
        }

        public void onRequestEnded(boolean success, Object result) {
            if(success) {
                if(result == null || ((String) result).trim().length() == 0) {
                    DialogHelper.showModalMessageDialog(
                            "Can't get account reply email. Message can't be sent.");
                    return;
                }
                String fromAdr = (String) result;
                initVals.put(EmailComposeHelper.FROM_MAP_FIELD, fromAdr);
                switch(answerType) {
                    case REPLY_TYPE:
                        replyDialog.setInitialDataMap(initVals);
                        replyDialog.setObjectType(objectType);
                        replyDialog.setObjectId(objectId);
                        replyDialog.show(true);
                        break;
                    case FORWARD_TYPE:
                        forwardDialog.setInitialDataMap(initVals);
                        forwardDialog.show(true);
                        break;
                    default:
                        DialogHelper.showModalMessageDialog(
                                "Unsupported answer type.");
                }
            } else {
                DialogHelper.showModalMessageDialog(
                        "RPC call failed. Message can't be sent.");
            }
        }
    }

    protected class CreateDeleteAsyncCallback extends RPC.QAsyncCallback {
        private FamgMeta.Index form;

        CreateDeleteAsyncCallback(FamgMeta.Index form) {
            this.form = form;
        }

        public void onRequestEnded(boolean success, Object result) {
            if(success) {
                Boolean rv = (Boolean) result;
                if(rv.booleanValue()) {
                    DialogHelper.showModalMessageDialog("Record(s) deleted");
                    FormOperations context = getOperationContext()
                            .getFormOperations();
                    context.turnFormToState(form, FormState.SEARCH_STATE);
                    context.clearForm(form, false);
                    getOperationContext().performOperation(
                            OperationTypes.SEARCH_RECORDS, form);
                } else {
                    DialogHelper.showModalMessageDialog("Record cannot delete");
                }
            } else {
                DialogHelper.showModalMessageDialog("RPC call failed.");
            }
        }
    }

    public void setTicketFormId(String ticketFormId) {
        this.ticketFormId = ticketFormId;
    }

    public void setInterFormId(String interFormId) {
        this.interFormId = interFormId;
    }

    public void init(OperationContext operationContext, String formId, FamgMeta.Index formIndex) {
        super.init(operationContext, formId, formIndex);
        
    }
}
