package jp.co.y_net.amm.page;

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.AppLogger;
import jp.co.y_net.amm.common.AppSendMail;
import jp.co.y_net.amm.common.AppSendMail.MailSetting;
import jp.co.y_net.amm.common.AppStringUtils;
import jp.co.y_net.amm.common.AppUtils;
import jp.co.y_net.amm.common.ResourceReader;
import jp.co.y_net.amm.dao.AppDef;
import jp.co.y_net.amm.dao.Org;
import jp.co.y_net.amm.dao.Usr;

import org.apache.wicket.ajax.AjaxRequestTarget;
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.TextArea;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

public class OrgEntryDetailPage extends CommonFrameA {
	private static final long serialVersionUID = 1L;


    /*
     * 画面入力値
     */
	public String noteValue;
	/*
	 * 画面の状態
	 */
	private boolean completeA = false;
	private boolean completeR = false;
	private boolean complete = false;
	
	/**
	 * ログインチェック定義
	 * @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 OrgEntryDetailPage(final PageParameters pageParams) {
        
        /* 共通戻るリンクの設置 */
        createCommonBackLinks();

        /* 画面固有の戻るボタンの設置 */
        createBackLink(OrgEntryListPage.class, "申請一覧");
        
        /* フィードバックパネルの設置 */
        createFeedbackPanel();
        
        final Form<Void> form  = new Form<Void>("form");
        form.setOutputMarkupId(true);
        add(form);

        
        /* 初期表示エラーチェック ----------------------------------------------------------------------------------- */
        form.setVisible(false); // Formはエラーチェックが完了するまで非表示とする。
        
        final LoginUser loginUser  = AppSession.get().getLoginUser();
        if(loginUser == null) {
            error("ログイン情報が取得できません。");
            return; // ----------中断
        }
        final Integer loginUserId = loginUser.getUsrid();
        
        String orgid = pageParams.get("orgid").toString();
        validItemNum(orgid, "パラメータorgid", 1, Integer.MAX_VALUE);
        if(hasInputError()) return; // ----------エラーがあれば中止
        
        Integer iOrgid = Integer.parseInt(orgid);
        
        Org cond = new Org();
        cond.setOrgid(iOrgid);
        List<Org> orgs = orgDao.get(cond);
        if(orgs.size() != 1) {
            error("パラメータorgidが不正です。");
        }
        
        if(hasInputError()) return; // ----------エラーがあれば中止
        
        form.setVisible(true); 
        /* Form内の設定 ----------------------------------------------------------------------------------------------*/
        
        final Org org = orgs.get(0);
        
        /* 状態に応じて初期表示を変更 */
        if(org.getStatus().equals(Org.STATUS_承認済み)) {
            error("すでに承認されています。");
            complete = true;
        }
        if(org.getStatus().equals(Org.STATUS_本登録済み)) {
            error("すでに登録が完了しています。");
            complete = true;
        }
        if(org.getStatus().equals(Org.STATUS_拒否済み)) {
            error("すでに拒否されています。");
            complete = true;
        }
        
                
        /* 完了メッセージ */
        Model<String> resultMessageModel = new Model<String>() {
            @Override
            public String getObject() {
                if(completeA) {
                    return "承認しました。連絡先メールアドレスへ申請内容承認メールを送りました。";
                }
                if(completeR) {
                    return "拒否しました。連絡先メールアドレスへ申請内容拒否メールを送りました。";
                }
                return "";
            }
        };
        final Label resutlMessage = new Label("resutlMessage", resultMessageModel);
        form.add(resutlMessage);
        
        /* 出力コンポーネントの設定 ----------------------------------------------------------------------------------*/
        form.add(new Label("kind", Model.of(org.getKind_Disp())));
        Label name = new Label("name", Model.of(org.getName())){
            @Override
            public boolean isVisible() {
                if(org.isPersonalOrg()) { // 個人の場合は非表示
                    return false;
                }
                return true;
            }
        };
        form.add(name);
        form.add(new Label("adminname", Model.of(org.getAdminname())));
        form.add(new Label("adminnamekana", Model.of(org.getAdminnamekana())));
        form.add(new Label("postnum", Model.of(org.getPostnum_Disp())));
        form.add(new Label("address", Model.of(org.getAddress())));
        form.add(new Label("telnum", Model.of(org.getTelnum())));
        form.add(new Label("mail", Model.of(org.getMail())));
        
        noteValue = org.getNote();
        TextArea<String> note = new TextArea<String>("note", new PropertyModel<String>(this, "noteValue"));
        form.add(note);
        
        
        Label thAdminname = new Label("thAdminname", new Model<String>(){
            @Override
            public String getObject() {
                if(org.isPersonalOrg() == false) {
                    return "担当者";
                }
                return "氏名";
            }
        }){
        };
        form.add(thAdminname);
        
        final Button btnSubmitA = new ConfirmAjaxButton("btnSubmitA"){
            @Override
            String getConfirmMessage() {
                return "承認します";
            }
            @Override
            boolean executeBefore() {
                /* 入力値変換 */
                // なし
                
                /* 入力値チェック */
                // なし
                
                /*
                 *  この時点でもう一度メールアドレスのチェックが必要。
                 *  （申請中に別の申請が通過してユーザが作成されている可能性を考慮）
                 */
                if(mailAddressCheck.existWithoutOrg(org.getAddress())) {
                    error("このメールアドレスは既に使用されています。");
                }
                
                if(hasInputError()) return false; // ここまででエラーチェック
                
                return true;
            }
            @Override
            void executeAfter(AjaxRequestTarget target) {
                /* データアクセス 新規申請承認 */
                
                org.setStatus(Org.STATUS_承認済み);
                org.setApprovaldate(AppUtils.createNowLong());
                orgDao.update(org, loginUserId); // 【更新実施】
                
                Usr usr = new Usr();
                usr.setLoginid(org.getMail());
                usr.setName(org.getAdminname());
                usr.setKind(Usr.KIND_機関管理者);
                usr.setOrgid(org.getOrgid());
                usr.setOrgrole(Usr.ROLE_管理者);
                usr.setStoplogin(AppDef.FLASE);
                usr.setStatus(Usr.STATUS_仮登録); // 仮登録
                usr.setLoginerrorcount(0);
                usrDao.add(usr, loginUserId); // 【更新実施】
                
                /* 共通機能：パスワード登録チケット発行 からチケットを取得する（申請者のユーザIDをキーとする）*/
                String random = passwordTicketManager.execute新規パスワード発行(usr.getUsrid());

                /* 申請内容承認メール */
                MailSetting setting = new MailSetting();
                setting.setTemplate(ResourceReader.getText("message/mail.org.approval"));
                setting.setMailTo(org.getMail());
                setting.replace("機関名称", org.getName());
                setting.replace("申請者氏名", org.getAdminname());
                String 本登録URL = ResourceReader.getStringQuick("urlroot") + "entrypassword?value=" + random;
                setting.replace("本登録URL", 本登録URL);
                boolean sendmailrsult = AppSendMail.send(setting);
                if(sendmailrsult == false) {
                    error("メールの送信に失敗しました。");
                }
                
                /* テスト自動化対応 */
                if (AppLogger.isDebug()) {
                    //info("メールに記載したURL【" + 本登録URL + "】");
                    addDebugUrl(本登録URL);
                }
                
                
                /* 完了状態へ移行 */
                completeA = true;
                
                /* コンポーネント更新 */
                target.add(form);
            }
            @Override
            public boolean isVisible() {
                /* 完了後の状態ならボタンを表示しない */
                return completeA == false && completeR == false && complete== false;
            }
        };
        form.add(btnSubmitA);
        
        final Button btnSubmitR = new ConfirmAjaxButton("btnSubmitR"){
            @Override
            String getConfirmMessage() {
                return "拒否します";
            }
            @Override
            boolean executeBefore() {
                /* 入力値変換 */
                noteValue = AppStringUtils.trim(noteValue);
                
                /* 入力値チェック */
                validItem(noteValue, "拒否理由", 1, 5000);
                
                if(hasInputError()) return false; // ここまででエラーチェック
                
                return true;
            }
            @Override
            void executeAfter(AjaxRequestTarget target) {
                /* データアクセス 新規機関申請拒否 */
                org.setStatus(Org.STATUS_拒否済み);
                org.setRejectdate(AppUtils.createNowLong());
                org.setNote(noteValue);
                orgDao.update(org, loginUserId); // 【更新実施】
                
                
                /* 申請内容拒否メール */
                MailSetting setting = new MailSetting();
                setting.setTemplate(ResourceReader.getText("message/mail.org.reject"));
                setting.setMailTo(org.getMail());
                setting.replace("機関名称", org.getName());
                setting.replace("申請者氏名", org.getAdminname());
                setting.replace("否認理由", noteValue);
                boolean sendmailrsult = AppSendMail.send(setting);
                if(sendmailrsult == false) {
                    error("メールの送信に失敗しました。");
                }
                
                /* 完了状態へ移行 */
                completeR = true;
                
                /* コンポーネント更新 */
                target.add(form);
            }
            @Override
            public boolean isVisible() {
                /* 完了後の状態ならボタンを表示しない */
                return completeA == false && completeR == false && complete== false;
            }
        };
        form.add(btnSubmitR);
        
        /*
         * 承認済みのときに表示される領域
         */
        WebMarkupContainer cntStatus1 = new WebMarkupContainer("cntStatus1") {
            @Override
            public boolean isVisible() {
                return org.getStatus().equals(Org.STATUS_承認済み);
            }
        };
        cntStatus1.setOutputMarkupId(true);
        cntStatus1.setOutputMarkupPlaceholderTag(true);
        form.add(cntStatus1);
            

        
//        /* パスワードの有効期限 */
//        Label pwtcktLabel = new Label("pwtckt", new Model<String>(){
//            @Override
//            public String getObject() {
//                /* 仮登録されている代表者 */
//                final Usr usrPreAdmin = 仮登録されている代表者(org);
//                String ticket = "xxx";
//                Pwtckt pwtckt = passwordTicketManager.get有効なチケット(usrPreAdmin.getUsrid());
//                if(pwtckt != null) {
//                    if(pwtckt.getTicketdate() != null) {
//                        ticket = "パスワード受付の有効期限は "
//                                + AppUtils.toStrYyyyMMdd_HHmmss(pwtckt.getTicketdate())
//                                + " です。";
//                    } else {
//                        ticket = "パスワード受付の有効期限が取得できません。";
//                    }
//                } else {
//                    ticket = "パスワード受付の有効期限が取得できません。";
//                }
//                return ticket;
//            }
//        });
//        pwtcktLabel.setOutputMarkupPlaceholderTag(true);
//        cntStatus1.add(pwtcktLabel);
        
        /* 承認メールを再送する ボタン */
        final Button btnSubmitStatus1 = new ConfirmAjaxButton("btnSubmitStatus1"){
            @Override
            String getConfirmMessage() {
                return "承認メールを再送します。";
            }
            @Override
            boolean executeBefore() {
                /* 入力値変換 */
                // なし
                /* 入力値チェック */
                // なし
                return true;
            }
            @Override
            void executeAfter(AjaxRequestTarget target) {
                
                /* 共通機能：パスワード登録チケット発行 からチケットを取得する（申請者のユーザIDをキーとする）*/
                final Usr usrPreAdmin = 組織の代表者(org);
                String random = passwordTicketManager.execute新規パスワード発行(usrPreAdmin.getUsrid());

                /* 申請内容承認メール */
                MailSetting setting = new MailSetting();
                setting.setTemplate(ResourceReader.getText("message/mail.org.approval"));
                setting.setMailTo(org.getMail());
                setting.replace("機関名称", org.getName());
                setting.replace("申請者氏名", org.getAdminname());
                String 本登録URL = ResourceReader.getStringQuick("urlroot") + "entrypassword?value=" + random;
                setting.replace("本登録URL", 本登録URL);
                boolean sendmailrsult = AppSendMail.send(setting);
                if(sendmailrsult == false) {
                    error("メールの送信に失敗しました。");
                }
                
                /* テスト自動化対応 */
                if (AppLogger.isDebug()) {
                    addDebugUrl(本登録URL);
                }
                
                /* メッセージ表示 */
                info("パスワード受付の有効期限を更新して、メールを再送しました。");
                
                /* コンポーネント更新 */
                target.add(form);
                
            }
            @Override
            public boolean isVisible() {
                return org.getStatus().equals(Org.STATUS_承認済み);
            }
        };
        btnSubmitStatus1.setOutputMarkupPlaceholderTag(true);
        cntStatus1.add(btnSubmitStatus1);
        
        FeedbackPanel fb = new FeedbackPanel("feedback");
        fb.setOutputMarkupPlaceholderTag(true);
        cntStatus1.add(fb);
        
        
        /* パスワード情報 */
        PasswordInfoPanel passwordInfoPanel = new PasswordInfoPanel("PasswordInfoPanel", 
                組織の代表者(org),
                isSystemAdmin(),
                true);
        form.add(passwordInfoPanel);
        

    }
    private Usr 組織の代表者(final Org org) {
        Usr usrPreAdminCnd = new Usr();
        if(Org.KIND_運営管理 == org.getKind()) { // 運営管理を考慮
            usrPreAdminCnd.setKind(Usr.KIND_運営管理者);
        } else {
            usrPreAdminCnd.setKind(Usr.KIND_機関管理者);
        }
        usrPreAdminCnd.setOrgid(org.getOrgid());
        usrPreAdminCnd.setOrgrole(Usr.ROLE_管理者);
        List<Usr> usrs = usrDao.get(usrPreAdminCnd);
        if(usrs.isEmpty()) {
            //throw new RuntimeException("承認済み組織からユーザ情報が取得できませんでした。");
            return null; // 「未処理」を考慮
        }
        final Usr usrPreAdmin = usrs.get(0);
        return usrPreAdmin;
    }
}
