package jp.co.y_net.amm.page;

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

import jp.co.y_net.amm.AppSession;
import jp.co.y_net.amm.AppSession.LoginUser;
import jp.co.y_net.amm.common.AppStringUtils;
import jp.co.y_net.amm.common.AppUtils;
import jp.co.y_net.amm.dao.Grp;
import jp.co.y_net.amm.dao.Grpusr;
import jp.co.y_net.amm.dao.Usr;

import org.apache.wicket.ajax.AjaxRequestTarget;
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.Form;
import org.apache.wicket.markup.html.form.TextField;
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.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

public class GroupMemberListPage extends CommonFrameA {
    private static final long serialVersionUID = 1L;
    // TODO 運営管理者向け制御
    
    /*
     * 画面入力値
     */
    public String usrmailValue;
    public String usrmail2Value;
    
    /*
     * 画面の状態
     */
    private boolean complete = true;
    
    /**
     * ログインチェック定義
     * @see jp.co.y_net.amm.page.AppPage#validateLogin()
     */
    @Override
    public boolean validateLogin() {
        if(AppSession.get().isLogin()) {
            return true;
        }
        return false;
    }
    
    public GroupMemberListPage(PageParameters pageParams) {
        
        /* 共通戻るリンクの設置 */
        createCommonBackLinks();
        
        /* フィードバックメッセージ */
        final FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
        feedbackPanel.setOutputMarkupId(true);
        add(feedbackPanel);
        
        /* 入力フォーム */
        Form<Void> form  = new Form<Void>("form");
        add(form);
        
        /* 初期表示エラーチェック・共通変数設定 --------------------------------------------------------------------- */
        form.setVisible(false); // Formはエラーチェックが完了するまで非表示とする。
        
//        final Usr loginUser = AppSession.get().getLoginUser();
        
        final Integer paramGrpid;
        String paramGrpidStr = pageParams.get("grpid").toString();
        if(paramGrpidStr == null) {
            error("パラメータ grpid が指定されていません。");
            return;
        } else {
            try {
                paramGrpid = Integer.parseInt(paramGrpidStr);
            } catch (NumberFormatException e) {
                error("パラメータ grpid が不正です。");
                return;
            }
        }
        final Grp targetGroup = grpDao.getByGrpid(paramGrpid);
        if(targetGroup == null) {
            error("パラメータ grpid に該当するデータがありません。");
            return;
        }
        final Integer targetGroupAdminid = targetGroup.getAdminusrid();
        
        final LoginUser loginUser  = AppSession.get().getLoginUser();
        if(loginUser == null) {
            error("ログイン情報が取得できません。");
            return;
        }
        final Integer loginUserId = loginUser.getUsrid();
        
        if(Usr.KIND_運営管理者 == loginUser.getKind()) {
            // 運営管理者は全てのグループを表示できる
        } else {
            if(loginUserId.equals(targetGroup.getAdminusrid()) == false) {
                error("このグループの管理者ではありません。");
                return;
            }
        }

        
        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);
        /* ----------------------------------------------------------------------------------------------------------*/
        /* 一覧のモデルの設定 */
        
        final IModel<List<Grpusr>> listModel = new LoadableDetachableModel<List<Grpusr>>() {
            /* LoadableDetachableModel#load は リクエストごと、最初に実行される */
            @Override
            protected List<Grpusr> load() {
                
                Grpusr cnd = new Grpusr();
                cnd.setGrpid(paramGrpid);
                List<Grpusr> list = grpusrDao.get(cnd);
                /* 
                 *・脱退者は除外する
                 */
                List<Grpusr> tmp = new ArrayList<Grpusr>();
                for(Grpusr gu: list) {
                    if(Grpusr.STATUS_脱退.equals(gu.getStatus())) {
                     // 追加しない
                    } else {
                        tmp.add(gu);
                    }
                }
                list = tmp;
                /* 参加日の新しい順でソート*/
                Collections.sort(list, new Grpusr.JoindateComparator(true));
                return list;
            }
        };
        
        /*グループ名*/
        Label groupname = new Label("groupname", targetGroup.getName());
        form.add(groupname);
        
        /* コンテナの設定 ------ -------------------------------------------------------------------------------------*/
        /* 
         * 画面の部分更新の対象となるコンテナ
         */
        
        /* メンバー一覧 */
        final WebMarkupContainer listContainer = new WebMarkupContainer("listContainer");
        listContainer.setOutputMarkupId(true);
        listContainer.setOutputMarkupPlaceholderTag(true);// 初期非表示の場合に、後から表示できるようにする
        form.add(listContainer);
        
        /* 招待欄の設定 ---------------------------------------------------------------------------------------------*/
        
        TextField<String> usrmail = new TextField<String>("usrmail", new PropertyModel<String>(this, "usrmailValue"));
        form.add(usrmail);
        TextField<String> usrmail2 = new TextField<String>("usrmail2", new PropertyModel<String>(this, "usrmail2Value"));
        form.add(usrmail2);
        
        
        Button btnSubmit = new ConfirmAjaxButton("btnSubmit"){
            @Override
            boolean executeBefore() {
                /* 入力値変換 */
                usrmailValue = AppStringUtils.trimHalf(usrmailValue);
                usrmail2Value = AppStringUtils.trimHalf(usrmail2Value);
                
                /* 入力値検査 */
                if(usrmailValue.equals(usrmail2Value) == false) {
                    error("メールアドレスが一致しません。");
                }
                if(hasInputError()) return false; // ここまででエラーチェック
                
                Usr usr = usrDao.getByLoginid(usrmailValue);
                if(usr == null) {
                    error("メールアドレスが登録されていません。");
                } else {
                    if(usr.getStatus() == Usr.STATUS_退会) {
                        error("メールアドレスが無効です。");
                    }
                }
                if(hasInputError()) return false; // ここまででエラーチェック
                
                
                Grpusr newMember = new Grpusr();
                newMember.setGrpid(paramGrpid);
                newMember.setUsrid(usr.getUsrid());
                List<Grpusr> exists = grpusrDao.get(newMember);
                if(exists.isEmpty() == false) {
                    for(Grpusr gu: exists) {
                        if(Grpusr.STATUS_参加中.equals(gu.getStatus())) {
                            error("すでに参加しています。");
                            return false;
                        }
                        if(Grpusr.STATUS_招待中.equals(gu.getStatus())) {
                            error("すでに招待中です。");
                            return false;
                        }
                    }
                }
                
                return true;
            }
            @Override
            protected String getConfirmMessage() {
                return "ユーザを招待します。";
            }
            @Override
            void executableWork() {
                /* データアクセス メンバー招待
                 *   過去に参加してればUpdateとする
                 */
                Usr usr = usrDao.getByLoginid(usrmailValue);
                Grpusr newMember = new Grpusr();
                newMember.setGrpid(paramGrpid);
                newMember.setUsrid(usr.getUsrid());
                List<Grpusr> exists = grpusrDao.get(newMember);
                if(exists.isEmpty() == false) {
                    newMember = exists.get(0);
                }
                newMember.setInvitationdate(AppUtils.createNowLong());
                newMember.setStatus(Grpusr.STATUS_招待中);
                if(exists.isEmpty()) {
                    grpusrDao.add(newMember, loginUserId); // 更新処理
                } else {
                    grpusrDao.update(newMember, loginUserId); // 更新処理
                }
            }
            @Override
            void executeAfter(AjaxRequestTarget target) {
                Usr usr = usrDao.getByLoginid(usrmailValue);
                feedbackPanel.info(usr.getName() + "さんを招待しました。");
                
                /* 入力項目初期化 */
                usrmailValue = "";
                usrmail2Value = "";
              
                /* 画面部品の更新 */
                target.add(listContainer); // 一覧領域
            }
        };
        form.add(btnSubmit);
        
        /* 一覧の繰り返し処理   --------------------------------------------------------------------------------------*/
        final PageableListView<Grpusr> list = new PageableListView<Grpusr>("list", listModel, 20) {
            private static final long serialVersionUID = 1L;
            @Override
            protected void populateItem(ListItem<Grpusr> item) {
                
                final Grpusr grpusr = item.getModelObject();
                final Usr member = usrDao.getByUsrid(grpusr.getUsrid());
                
                final String memberName = member.getName();
                
                item.add(new Label("name", memberName)); // メンバーの名前
                
                item.add(new Label("joindate" , AppUtils.toStrYyyyMMdd(grpusr.getJoindate()))); // 参加日
                
                item.add(new Label("status" , grpusr.getStatus合算())); // 状態
                
                item.add(new Label("isAdmin", "このグループの管理者です。"){
                    @Override
                    public boolean isVisible() {
                        return member.getUsrid().equals(targetGroup.getAdminusrid());
                    }
                    
                });
                
                /* 招待取消 ボタン */
                item.add(new ConfirmAjaxButton("buttonReject"){
                    @Override
                    protected String getConfirmMessage() {
                        return memberName + "さんへの招待を取消します。";
                    }
                    @Override
                    void executableWork() {
                        /* データ操作 */
                        grpusrDao.removeLogical(grpusr, loginUserId); // 【論理削除】
                    }
                    @Override
                    void executeAfter(AjaxRequestTarget target) {
                        /* メッセージ表示 */
                        feedbackPanel.info(memberName + "さんへの招待を取消しました。");
                        /* 画面部品の更新 */
                        target.add(listContainer); // 一覧領域
                    }
                    @Override
                    public boolean isVisible() {
                        /* グループ管理者か、運営管理者でなければ非表示 */
                        if(loginUserId.equals(targetGroupAdminid) == false && isSystemAdmin() == false) return false;
                        /* 招待状態でなければ非表示 */
                        if(Grpusr.STATUS_招待中.equals(grpusr.getStatus()) == false) return false;
                        return true;
                    }
                });
                
                /* 脱退させる ボタン */
                item.add(new ConfirmAjaxButton("buttonLeave"){
                    @Override
                    protected String getConfirmMessage() {
                        return memberName + "さんを脱退させます。";
                    }
                    @Override
                    void executableWork() {
                        /* データ操作 */
                        grpusr.set脱退設定();
                        grpusrDao.update(grpusr, loginUserId); // 【データ更新】
                    }
                    @Override
                    void executeAfter(AjaxRequestTarget target) {
                        /* メッセージ表示 */
                        feedbackPanel.info(memberName + "さんを脱退させました。");
                        /* 画面部品の更新 */
                        target.add(listContainer); // 一覧領域
                    }
                    @Override
                    public boolean isVisible() {
                        /* グループ管理者か、運営管理者でなければ非表示 */
                        if(loginUserId.equals(targetGroupAdminid) == false && isSystemAdmin() == false) return false;
                        /* 自分自身のデータの場合は非表示 */
                        if(member.getUsrid().equals(loginUser.getUsrid())) return false;
                        /* 参加状態でなければ非表示 */
                        if(Grpusr.STATUS_参加中.equals(grpusr.getStatus()) == false) return false;
                        return true;
                    }
                });
                /* 管理者依頼 ボタン */
                item.add(new ConfirmAjaxButton("buttonAdmin"){
                    @Override
                    protected String getConfirmMessage() {
                        return memberName + "さんに管理者を依頼します。";
                    }
                    @Override
                    void executableWork() {
                        /* データ操作 */
                        grpusr.setStatusadmin(Grpusr.STATUS_ADMIN_移管依頼中);
                        grpusrDao.update(grpusr, loginUserId); // 【データ更新】
                    }
                    @Override
                    void executeAfter(AjaxRequestTarget target) {
                        /* メッセージ表示 */
                        feedbackPanel.info(memberName + "さんに管理者を依頼しました。");
                        /* 画面部品の更新 */
                        target.add(listContainer); // 一覧領域
                    }
                    @Override
                    public boolean isVisible() {
                        /* グループ管理者か、運営管理者でなければ非表示 */
                        if(loginUserId.equals(targetGroupAdminid) == false && isSystemAdmin() == false) return false;
                        /* 自分自身のデータの場合は非表示 */
                        if(member.getUsrid().equals(loginUser.getUsrid())) return false;
                        /* 参加状態でなければ非表示 */
                        if(Grpusr.STATUS_参加中.equals(grpusr.getStatus()) == false) return false;
                        /* 移管依頼中の場合は非表示 */
                        if(Grpusr.STATUS_ADMIN_移管依頼中.equals(grpusr.getStatusadmin())) return false;
                        return true;
                    }
                });
                /* 管理者依頼取消 ボタン */
                item.add(new ConfirmAjaxButton("buttonAdminReject"){
                    @Override
                    protected String getConfirmMessage() {
                        return memberName + "さんへの管理者依頼を取消します。";
                    }
                    @Override
                    void executableWork() {
                        /* データ操作 */
                        grpusr.setStatusadmin(Grpusr.STATUS_ADMIN_未設定);
                        grpusrDao.update(grpusr, loginUserId); // 【データ更新】
                    }
                    @Override
                    void executeAfter(AjaxRequestTarget target) {
                        /* メッセージ表示 */
                        feedbackPanel.info(memberName + "さんへの管理者依頼を取消しました。");
                        /* 画面部品の更新 */
                        target.add(listContainer); // 一覧領域
                    }
                    @Override
                    public boolean isVisible() {
                        /* グループ管理者か運営管理者でなければ非表示 */
                        if(loginUserId.equals(targetGroupAdminid) == false && isSystemAdmin() == false) return false;
                        /* 自分自身のデータの場合は非表示 */
                        if(member.getUsrid().equals(loginUser.getUsrid())) return false;
                        /* 参加状態でなければ非表示 */
                        if(Grpusr.STATUS_参加中.equals(grpusr.getStatus()) == false) return false;
                        /* 移管依頼中でなければ非表示 */
                        if(Grpusr.STATUS_ADMIN_移管依頼中.equals(grpusr.getStatusadmin()) == false) return false;
                        return true;
                    }
                });
            }
        };
        listContainer.add(list);
        
        /* ページングの部品 */
        final AjaxPagingNavigator pagingList = new AjaxPagingNavigator("pagingList", list){};
        listContainer.add(pagingList);
    }
}
