package jp.co.y_net.amm.page;

import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import jp.co.y_net.amm.AppSession;
import jp.co.y_net.amm.common.AppLogger;
import jp.co.y_net.amm.common.AppUtils;
import jp.co.y_net.amm.common.ResourceReader;
import jp.co.y_net.amm.dao.Grp;
import jp.co.y_net.amm.dao.Grpusr;
import jp.co.y_net.amm.dao.Org;
import jp.co.y_net.amm.dao.Usr;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.resource.StringResourceStream;

public class ExportPage 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 ExportPage(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);
        
        final List<Usr> usrs = usrDao.get();
        final List<Org> orgs = orgDao.get();
        final List<Grp> grps = grpDao.get();
        
        /* Form内の設定 ----------------------------------------------------------------------------------------------*/
        form.add(new Button("btnCsvUsr"){
            @Override
            public void onSubmit() {
                StringBuilder csvBuilder = new StringBuilder();

                csvBuilder.append("ユーザ情報\n");
                csvBuilder.append("出力日:" + new SimpleDateFormat("yyyy年MM月dd日 HH時:mm分").format(new Date()) + "\n");
                csvBuilder.append("\n");
                
                List<String> heads = Arrays.asList(new String[]{
                        "ユーザID",
                        "ログインID",
                        "氏名",
                        "種別",
                        "所属組織",
                        "所属組織での役割",
                        "入会日時",
                        "ログイン失敗回数",
                        "最終ログイン日時",
                        "パスワード変更日時",
                        "退会日付",
                        "状態",
                });
                for (String str: heads) {
                    csvBuilder.append(escapeCsv(str) + ",");
                }
                csvBuilder.append("\n");
                
                List<List<Object>> recodes = new ArrayList<List<Object>>();
                for (Usr usr: usrs) {
                    List<Object> datas = Arrays.asList(new Object[]{
                            (usr.getUsrid()),
                            (usr.getLoginid()),
                            (usr.getName()),
                            名称へ変換(usr.getKind(), "1.機関会員,2.機関管理者,3.運営管理者,"),
                            組織名へ変換(usr.getOrgid(), orgs),
                            名称へ変換(usr.getOrgrole(), "1.管理者, 9.通常会員"),
                            yyyyMMddへ変換(usr.getJoindate()),
                            (usr.getLoginerrorcount()),
                            yyyyMMddへ変換(usr.getLastlogindate()),
                            yyyyMMddへ変換(usr.getModpwdate()),
                            yyyyMMddへ変換(usr.getLeavedate()),
                            名称へ変換(usr.getStatus(), "0.仮登録（登録待ち）,1.登録済み,2.退会,"),
                    });
                    recodes.add(datas);
                }
                for (List<Object> recode: recodes) {
                    for (Object obj: recode) {
                        String str= "";
                        if (obj!= null) {
                            str = obj.toString();
                        }
                        csvBuilder.append(escapeCsv(str) + ",");
                    }
                    csvBuilder.append("\n");
                }
                
                /* CSVファイル名をセットしてレスポンス */
                String strCsvName = "USR_" + String.valueOf(getTodayNumber()) + ".csv";
                responseCsv(csvBuilder, strCsvName);
            }
        });
        
        form.add(new Button("btnCsvOrg"){
            @Override
            public void onSubmit() {
                StringBuilder csvBuilder = new StringBuilder();

                csvBuilder.append("組織情報\n");
                csvBuilder.append("出力日:" + new SimpleDateFormat("yyyy年MM月dd日 HH時:mm分").format(new Date()) + "\n");
                csvBuilder.append("\n");
                
                List<String> heads = Arrays.asList(new String[]{
                        "組織ID",
                        "種別",
                        "名称",
                        "管理者氏名",
                        "申請日時",
                        "本登録日時",
                        "状態",
                });
                for (String str: heads) {
                    csvBuilder.append(escapeCsv(str) + ",");
                }
                csvBuilder.append("\n");
                
                List<List<Object>> recodes = new ArrayList<List<Object>>();
                for (Org data: orgs) {
                    List<Object> datas = Arrays.asList(new Object[]{
                            (data.getOrgid()),
                            名称へ変換(data.getKind(),"1.教育機関, 2.施設団体（政令指定）, 3.施設団体（非政令指定）, 9.個人, 999.運営管理"),
                            (data.getName()),
                            (data.getAdminname()),
                            yyyyMMddへ変換(data.getEntrydate()),
                            yyyyMMddへ変換(data.getJoindate()),
                            名称へ変換(data.getStatus(),"0. 申請中（未処理）,1. 承認済み（本登録待ち）,2. 拒否済み,3. 本登録済み,"),

                    });
                    recodes.add(datas);
                }
                for (List<Object> recode: recodes) {
                    for (Object obj: recode) {
                        String str= "";
                        if (obj!= null) {
                            str = obj.toString();
                        }
                        csvBuilder.append(escapeCsv(str) + ",");
                    }
                    csvBuilder.append("\n");
                }
                
                /* CSVファイル名をセットしてレスポンス */
                String strCsvName = "ORG_" + String.valueOf(getTodayNumber()) + ".csv";
                responseCsv(csvBuilder, strCsvName);
            }
        });
        
        form.add(new Button("btnCsvGrp"){
            @Override
            public void onSubmit() {
                StringBuilder csvBuilder = new StringBuilder();

                csvBuilder.append("グループ情報\n");
                csvBuilder.append("出力日:" + new SimpleDateFormat("yyyy年MM月dd日 HH時:mm分").format(new Date()) + "\n");
                csvBuilder.append("\n");
                
                List<String> heads = Arrays.asList(new String[]{
                        "グループID",
                        "名称",
                        "メンバー",
                        "メンバーの状態",
                });
                for (String str: heads) {
                    csvBuilder.append(escapeCsv(str) + ",");
                }
                csvBuilder.append("\n");
                
                List<List<Object>> recodes = new ArrayList<List<Object>>();
                for (Grp grp: grps) {
                    Grpusr cnd = new Grpusr();
                    cnd.setGrpid(grp.getGrpid());
                    boolean first = true;
                    for (Grpusr grpusr: grpusrDao.get(cnd)){
                        Usr member = usrDao.getByUsrid(grpusr.getUsrid());
                        String admin = "";
                        if (grp.getAdminusrid().equals(member.getUsrid())) {
                            admin = "（グループ管理者）";
                        }
                        List<Object> datas = Arrays.asList(new Object[]{
                                first ? grp.getGrpid() : "",
                                first ?grp.getName() : "",
                                member.getUsrid() + "." + member.getName() + admin,
                                名称へ変換(grpusr.getStatus(),"0.招待中,1.参加中,2.脱退,"),
                        });
                        recodes.add(datas);
                        first = false;
                    }
                }
                for (List<Object> recode: recodes) {
                    for (Object obj: recode) {
                        String str= "";
                        if (obj!= null) {
                            str = obj.toString();
                        }
                        csvBuilder.append(escapeCsv(str) + ",");
                    }
                    csvBuilder.append("\n");
                }
                
                /* CSVファイル名をセットしてレスポンス */
                String strCsvName = "GRP_" + String.valueOf(getTodayNumber()) + ".csv";
                responseCsv(csvBuilder, strCsvName);
            }
        });
    }
    
    
    private String 名称へ変換(Integer i, String defs) {
        List<String> listDefs = Arrays.asList(defs.split(","));
        for (String def: listDefs) {
            if (def.trim().isEmpty()) continue;
            String key = def.split("\\.")[0].trim();
            String value = def.split("\\.")[1].trim();
            if (key.equals(i.toString())) {
                return value;
            }
        }
        AppLogger.error("!!! 値が不正です !!!(" + i + ")");
        return "!!! 値が不正です !!!(" + i + ")";
    }

    private String yyyyMMddへ変換(Long l) {
        if (l == null) return "";
        return new SimpleDateFormat("yyyy/MM/dd").format(AppUtils.toDate(l));
    }

    private String 組織名へ変換(Integer orgid, List<Org> orgs) {
        for (Org org: orgs) {
            if (org.getOrgid().equals(orgid)) {
                return "(" + orgid + ")"+org.getName();
            }
        }
        
        Org deletedOrg = orgDao.getByOrgid(orgid, true);
        if (deletedOrg != null) {
            return "(" + orgid + ")" + deletedOrg.getNameOrAdminname() + "(削除済み)";
        }
        
        AppLogger.error("!!! 組織情報が引き当てられませんでした !!!" + orgid);
        return "!!! 組織情報が引き当てられませんでした !!!" + orgid;
    }
    
    /**
    *
    * システム日付（yyyymmdd）を数値で返す
    *
    * @return システム日付（8桁数値）
    */
    private static int getTodayNumber(){

        Calendar cal;
        int intToday = 0;

        cal = Calendar.getInstance();

        /* 年を取得 */
        int y = cal.get(Calendar.YEAR) * 10000;

        /* 月を取得（0～11で返ってくるため+1する) */
        int m = (cal.get(Calendar.MONTH) + 1)  * 100;

        /* 日を取得 */
        int d = cal.get(Calendar.DATE);

        /* 日付yyyymmddを取得 */
        intToday = y + m + d;

        return intToday;
    }
    private String escapeCsv(String value) {
        return StringEscapeUtils.escapeCsv(value);
    }

    private void responseCsv(StringBuilder csvBuilder, String strCsvName) {
        /* 作成したCSVデータを配信するためのリソースストリームを生成 */
        StringResourceStream stream = new StringResourceStream(csvBuilder.toString(), "application/octet-stream");
        stream.setCharset(Charset.forName("Shift_JIS"));
        /* ターゲットをResourceStreamRequestTargetに差し替える */
        getRequestCycle().scheduleRequestHandlerAfterCurrent(new ResourceStreamRequestHandler(stream, strCsvName));
    }
}
