package jp.co.y_net.amm.page;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jp.co.y_net.amm.AppSession;
import jp.co.y_net.amm.common.ChoiceElement;
import jp.co.y_net.amm.common.ResourceReader;
import jp.co.y_net.amm.dao.Org;
import jp.co.y_net.amm.dao.Usr;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;

public class OrgMemberListPage extends CommonFrameA {
	private static final long serialVersionUID = 1L;
	
    /*
     * 画面入力値
     */
    // 無し
    
    /*
     * 画面の状態
     */
	private boolean complete = true;
	
    /**
     * ログインチェック定義
     * @see jp.co.y_net.amm.page.AppPage#validateLogin()
     */
    @Override
    public boolean validateLogin() {
        if(AppSession.get().isLogin()) {
            if(AppSession.get().getLoginUser().getKind().equals(Usr.KIND_運営管理者)) {
                return true;
            }
        }
        return false;
    }
	
    public OrgMemberListPage(PageParameters pageParams) {
        
        /* 戻るリンク */
        add(new ExternalLink("lnkSysAdmin", ResourceReader.getStringQuick("url.back.sysadmin")));
        
        /* フィードバックメッセージ */
        final FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
        feedbackPanel.setOutputMarkupId(true);
        add(feedbackPanel);
        
        /* 入力フォーム */
        Form<Void> form  = new Form<Void>("form");
        add(form);
        
        /* 初期表示エラーチェック ----------------------------------------------------------------------------------- */
        form.setVisible(false); // Formはエラーチェックが完了するまで非表示とする。
        // なし
        
        if(hasInputError()) return; // ----------エラーがあれば中止
        form.setVisible(true);
        
        /* Form内の設定 ----------------------------------------------------------------------------------------------*/
        /* 完了メッセージ */
        Model<String> resultMessageModel = new Model<String>() {
            @Override
            public String getObject() {
                if(complete) {
                    return "";
                }
                return "";
            }
        };
        final Label resutlMessage = new Label("resutlMessage", resultMessageModel);
        resutlMessage.setOutputMarkupId(true);
        form.add(resutlMessage);
        
        /* 入力コンポーネントの設定 ----------------------------------------------------------------------------------*/
        
        /* 絞り込み */
        // 会員の種類
        List<ChoiceElement> choiceKind = new ArrayList<ChoiceElement>();
        choiceKind.add(new ChoiceElement(" ","(選択してください)"));
        Map<String, String> map = Org.getOrgkindMap();
        for(Entry<String, String> e: map.entrySet()) {
            choiceKind.add(new ChoiceElement(e.getKey(), e.getValue()));
        }
        final Model<ChoiceElement> kindModel = new Model<ChoiceElement>();
        ChoiceElement.setDropDownList(kindModel, choiceKind, " "); // 初期値設定
        final DropDownChoice<ChoiceElement> filterKind = new DropDownChoice<ChoiceElement>(
                "filterKind", kindModel, choiceKind, new ChoiceElement.Renderer());
        filterKind.setOutputMarkupId(true);
        form.add(filterKind);

        
        // 名称|氏名での絞り込み
        final TextField<String> filterName = new TextField<String>("filterName", Model.of(""));
        filterName.setOutputMarkupId(true);
        form.add(filterName);
        // 名称|氏名のラベル
        final Label labelFilterName = new Label("labelFilterName", new Model<String>(){
            @Override
            public String getObject() {
                if(kindModel.getObject().getId().equals(" ")) {
                    return "名称か氏名";
                } else {
                    if(kindModel.getObject().getId().equals(Org.KIND_PERSONAL_STR)) {
                        return "会員の氏名";
                    } else {
                        return "会員の名称";
                    }
                }
            }
        });
        labelFilterName.setOutputMarkupId(true);
        form.add(labelFilterName);
        // 会員の種類で表示するラベルを変更する。
        filterKind.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                target.add(labelFilterName);
            }
        });
        
        
        /* コンテナの設定 ------------------------------------------------------------------------------------------------*/
        /* 
         * 画面の部分更新の対象となるコンテナ
         * 　ページをインスタンス化するときに初期非表示としてはいけない。
         */
        final WebMarkupContainer orglistContainer = new WebMarkupContainer("orglistContainer");
        orglistContainer.setOutputMarkupId(true);
        form.add(orglistContainer);
        
        final WebMarkupContainer orglistContainerData = new WebMarkupContainer("orglistContainerData");
        orglistContainer.add(orglistContainerData);
        orglistContainerData.setOutputMarkupId(true);
        
        final WebMarkupContainer orglistContainerNoData = new WebMarkupContainer("orglistContainerNoData");
        orglistContainer.add(orglistContainerNoData);
        
        /* 一覧の設定 ------------------------------------------------------------------------------------------------*/
        
        // LoadableDetachableModel は リクエストの最初に load にてデータを取得するモデル
        final IModel<List<Org>> orgModel = new LoadableDetachableModel<List<Org>>() {
            @Override
            protected List<Org> load() {
                
                List<Org> list = new ArrayList<Org>();

                if(kindModel.getObject().getId().equals(" ")) {
                    /* 「（選択してください）」のままなので、検索しない*/

                } else {
                    String targetName = filterName.getValue();
                    if(targetName != null) targetName = targetName.trim();
                    
                    Org cnd = new Org();
                    Integer kind = Integer.parseInt(kindModel.getObject().getId());
                    cnd.setKind(kind);
                    List<Org> results = orgDao.get(cnd);
                    
                    if(StringUtils.isEmpty(targetName)) {
                        list.addAll(results);
                    } else {
                        for(Org result: results) {
                            if(result.getNameOrAdminname().contains(targetName)) {
                                list.add(result);
                            }
                        }
                    }
                }

                /* 申請日付の新しい順でソート*/
                Collections.sort(list, new Org.EntryDateComparator(true));
                
                return list;
            }
        };
        final PageableListView<Org> orglist = new PageableListView<Org>("orglist", orgModel, 20) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<Org> item) {
                final Org org = item.getModelObject();

                /* 会員種別 */
                item.add(new Label("kind", org.getKind_Disp()));
                
                /* 名称とリンク */
                final PageParameters param = new PageParameters();
                param.add("orgid", org.getOrgid());
                //BookmarkablePageLink<Void> lnkName = new BookmarkablePageLink<Void>("lnkName", OrgDetailPage.class, param); 
                Link<Void> lnkName = new Link<Void>("lnkName") {
                    @Override
                    public void onClick() {
                        OrgDetailPage nextPage = new OrgDetailPage(param);
                        nextPage.setReturnPage(getPage());
                        setResponsePage(nextPage);
                    }

                    @Override
                    protected boolean isLinkEnabled() {
                        return Org.STATUS_本登録済み == org.getStatus();
                    }
                    
                };
                
                String name = org.getNameOrAdminname();
                if(StringUtils.isEmpty(name)) {
                    name = "※"; // 仮に値が取得できない場合でも、リンクに使用されるため、疑似値を設定した。
                }
                Label lnklblName = new Label("lnklblName", name);
                lnkName.add(lnklblName);
                item.add(lnkName);
                
                /* ステータス */
                item.add(new Label("status", org.getStatus_Disp()));

                /* 申請日時 */
                item.add(new Label("entrydate" , org.getEntrydate_Disp()));
                
                /* 子会員の情報を取得 */
                Usr usrCnd = new Usr();
                usrCnd.setOrgid(org.getOrgid());
                Usr usrCndNot = new Usr();
                usrCndNot.setStatus(Usr.STATUS_退会);
                final List<Usr> usrs = usrDao.get(usrCnd, usrCndNot); // 該当組織で退会していないデータのリスト
                
                /* 会員一覧へのリンク */
                Link<Void> lnkMemberlist = new Link<Void>("lnkMemberlist"){
                    @Override
                    public void onClick() {
                        MemberListPage nextPage = new MemberListPage(param);
                        nextPage.setReturnPage(getPage());
                        setResponsePage(nextPage);
                    }
                    @Override
                    public boolean isEnabled() {
                        return usrs.size() > 0;
                    }
                };
                item.add(lnkMemberlist);
                
                /* 会員数（登録可能会員数）*/
                String 会員数と登録可能会員数 = String.valueOf(usrs.size());
                if(org.getLimitnum() != null && org.getLimitnum() >= 0) {
                    会員数と登録可能会員数 += "(" + org.getLimitnum() + ")";
                }
                lnkMemberlist.add(new Label("limitnum" , 会員数と登録可能会員数));

            }
        };
        orglistContainerData.add(orglist);
        
        /* ページングの部品 */
        final AjaxPagingNavigator pagingOrglist = new AjaxPagingNavigator("pagingOrglist", orglist){};
        orglistContainerData.add(pagingOrglist);

        
        
        /* コンテナ制御 */
        if(orgModel.getObject().isEmpty()) {
            orglistContainerData.setVisible(false);
            orglistContainerNoData.setVisible(true);
        } else {
            orglistContainerData.setVisible(true);
            orglistContainerNoData.setVisible(false);
        }
        
        
        /* 処理ボタン定義 --------------------------------------------------------------------------------------------*/
        AjaxButton btnSubmit = new AjaxButton("submitSelect") {
            private static final long serialVersionUID = 1L;
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form){
                if(kindModel.getObject().getId().equals(" ")) {
                    /* 「（選択してください）」のままなので、検索しない*/
                    error("会員の種別を選択してください。");
                    target.add(feedbackPanel);
                    return;
                }
                /* コンテナ制御 */
                if(orgModel.getObject().isEmpty()) {
                    orglistContainerData.setVisible(false);
                    orglistContainerNoData.setVisible(true);
                } else {
                    orglistContainerData.setVisible(true);
                    orglistContainerNoData.setVisible(false);
                }
                
                target.add(orglistContainer); // 一覧再描画
            }
            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form) {
                /* エラーハンドリングなし */
            }
        };
        form.add(btnSubmit);
        
        
        
        /* 一括簡易登録 --------------------------------------------------------------------------------------------*/
        final WebMarkupContainer cntBachUsrCreate = new WebMarkupContainer("cntBachUsrCreate");
        form.add(cntBachUsrCreate);
        
        final FeedbackPanel fbBachUsrCreate = new FeedbackPanel("fbBachUsrCreate");
        fbBachUsrCreate.setOutputMarkupId(true);
        cntBachUsrCreate.add(fbBachUsrCreate);
        
        final TextField<String> idBase = new TextField<String>("idBase", Model.of(""));
        cntBachUsrCreate.add(idBase);
        
        final TextField<String> pwBase = new TextField<String>("pwBase", Model.of(""));
        cntBachUsrCreate.add(pwBase);
        
        final TextField<String> from = new TextField<String>("from", Model.of(""));
        cntBachUsrCreate.add(from);
        
        final TextField<String> to = new TextField<String>("to", Model.of(""));
        cntBachUsrCreate.add(to);
        
        final WebMarkupContainer cntExample = new WebMarkupContainer("cntExample");
        cntExample.setOutputMarkupPlaceholderTag(true);
        cntExample.setOutputMarkupId(true);
        cntExample.setVisible(false);
        cntBachUsrCreate.add(cntExample);
        
        /* 作成例のリアルタイム更新 */
        idBase.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                updateExample(fbBachUsrCreate, idBase, pwBase, from, to, cntExample, target);
            }
        });
        pwBase.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                updateExample(fbBachUsrCreate, idBase, pwBase, from, to, cntExample, target);
            }
        });
        from.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                updateExample(fbBachUsrCreate, idBase, pwBase, from, to, cntExample, target);
            }
        });
        to.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                updateExample(fbBachUsrCreate, idBase, pwBase, from, to, cntExample, target);
            }
        });
        
        Button submitBachUsrCreate = new ConfirmAjaxButton("submitBachUsrCreate"){
            @Override
            boolean executeBefore() {
                
                /* 入力値検査 */
                String idBaseValue = idBase.getValue();
                String pwBaseValue = pwBase.getValue();
                String fromValue = from.getValue();
                String toValue = to.getValue();
                String errorMessage = batchUsrCreate.validInputs(idBaseValue, pwBaseValue, fromValue, toValue);
                if (StringUtils.isEmpty(errorMessage) == false) {
                    error(errorMessage);
                    return false;
                }
                
                return true;
            }
            @Override
            protected String getConfirmMessage() {
                return "一括登録を行います。";
            }
            @Override
            void executeAfter(AjaxRequestTarget target) {
                
                /* 入力値検査 */
                String idBaseValue = idBase.getValue();
                String pwBaseValue = pwBase.getValue();
                String fromValue = from.getValue();
                String toValue = to.getValue();
                
                /* 一括作成実施 */
                String errorMessage = batchUsrCreate.execute(idBaseValue, pwBaseValue, fromValue, toValue);
                
                if (StringUtils.isEmpty(errorMessage) == false) {
                    fbBachUsrCreate.error(errorMessage);
                    target.add(fbBachUsrCreate);
                    return;
                }
                
                /* 画面部品の更新 */
                filterKind.setDefaultModelObject(new ChoiceElement("9", "個人"));
                filterName.setDefaultModel(Model.of(idBase.getValue()));        
                target.add(filterName);
                target.add(filterKind);
                
                /* 画面部品の更新 一覧 */
                if(orgModel.getObject().isEmpty()) {
                    orglistContainerData.setVisible(false);
                    orglistContainerNoData.setVisible(true);
                } else {
                    orglistContainerData.setVisible(true);
                    orglistContainerNoData.setVisible(false);
                }
                
                target.add(orglistContainer); // 一覧再描画
                
            }
        };

        cntBachUsrCreate.add(submitBachUsrCreate);
        
        /* データエクスポート-----------------------------------------------------------------------------------------*/
        form.add(new BookmarkablePageLink<Void>("goExport", ExportPage.class));
    }
    
    /**
     * 一括簡易登録 即時検証メッセージの表示
     * @param fb
     * @param idBase
     * @param pwBase
     * @param from
     * @param to
     * @param cntExample
     * @param target
     */
    private void updateExample(FeedbackPanel fb, final TextField<String> idBase, final TextField<String> pwBase,
            final TextField<String> from, final TextField<String> to, final WebMarkupContainer cntExample, AjaxRequestTarget target) {
        
        String idBaseValue = idBase.getValue();
        String pwBaseValue = pwBase.getValue();
        String fromValue = from.getValue();
        String toValue = to.getValue();
        
        /* 入力値検査 */
        String errorMessage = batchUsrCreate.validInputs(idBaseValue, pwBaseValue, fromValue, toValue);
        if (StringUtils.isEmpty(errorMessage) == false) {
            fb.error(errorMessage);
            target.add(fb);
            return;
        }
        
        cntExample.setVisible(true);
        cntExample.addOrReplace(new Label("example", 
                "[ログインID『"+ batchUsrCreate.combine(idBaseValue, fromValue) + "』" +
                " パスワード『"+ batchUsrCreate.combine(pwBaseValue, fromValue) + "』]"));
        
        /* 表示用コンポーネント更新 */
        target.add(fb);
        target.add(cntExample);
    }
}
