package jp.co.y_net.amm.service;

import java.util.List;

import jp.co.y_net.amm.common.AppUtils;
import jp.co.y_net.amm.common.CalcHash;
import jp.co.y_net.amm.dao.AppDef;
import jp.co.y_net.amm.dao.Org;
import jp.co.y_net.amm.dao.OrgDao;
import jp.co.y_net.amm.dao.Usr;
import jp.co.y_net.amm.dao.UsrDao;

import org.apache.commons.lang.StringUtils;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component("batchUsrCreate")
public class BatchUsrCreate {
    
    @Autowired(required = true)
    @Qualifier("usrDao")
    protected UsrDao usrDao;
    
    @Autowired(required = true)
    @Qualifier("orgDao")
    protected OrgDao orgDao;
    
    @Autowired(required = true)
    @SpringBean(name="mailAddressCheck")
    protected MailAddressCheck mailAddressCheck;
    
    public static void main(String[] args) {
        
        final ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContextBase.xml", "hibernateContextBase.xml");
        
        final BatchUsrCreate me = (BatchUsrCreate)context.getBean("batchUsrCreate");
        me.execute("temp", "pass", "0", "8");
        
    }

    public String validInputs(String idBase, String pwBase, String from, String to) {
        if (StringUtils.isEmpty(idBase) || idBase.length() > 5) {
            return "ログインIDの接頭文字を5文字以内で入力してください。";
        }
        if (StringUtils.isEmpty(pwBase) || pwBase.length() > 5) {
            return "パスワードの接頭文字を5文字以内で入力してください。";
        }
        int iFrom = toInt(from);
        int iTo = toInt(to);
        if (iFrom == -1 || iTo == -1) {
            return "連番を0～99で入力してください。";
        };
        if (iFrom > 99 || iTo > 99) {
            return "連番を0～99で入力してください。";
        };
        if (iFrom > iTo) {
            return "連番の大小関係が不正です。";
        }
        return null;
    }
    
    public String execute(String baseId, String basePw, String from, String to) {
        int iFrom = toInt(from);
        int iTo = toInt(to);
        String errorMessage = validInputs(baseId, basePw, String.valueOf(from), String.valueOf(to));
        if (StringUtils.isEmpty(errorMessage) == false) {
            return errorMessage;
        }
        for (int i = iFrom; i <= iTo; i++) {
            
            /* 既存データチェック */
            if(mailAddressCheck.exist(combine(baseId, i))) {
                return "既に登録済みのデータがあります。";
            }
        }
        for (int i = iFrom; i <= iTo; i++) {
            /* 手続き実施 */
            create(combine(baseId, i), combine(basePw, i));
        }
        return null;
    }

    private void create(String id, String pw) {
        
        int iOrgid;
        int iUsrid;
        int updateUserId = -1;
                
        /*
         * 申請
         * OrgEntryPage相当
         */
        /* データアクセス 新規機関申請 */
        {
            Org org = new Org();
            org.setKind(9); // 個人会員
            org.setName("ユーザー" + id);
            org.setAdminname("ユーザー" + id);
            org.setAdminnamekana("ユーザー" + id);
            org.setPostnum("0000000");
            org.setTelnum("000-000-0000");
            org.setAddress("0000000000");
            org.setMail(id);
            org.setEntrydate(AppUtils.createNowLong());
            org.setStatus(Org.STATUS_未処理);
            orgDao.add(org,AppDef.USERID_NONE); // 【データ更新】
            
            iOrgid = org.getOrgid();
        }

        
        /*
         * 承認
         * OrgEntryDetailPage#btnSubmitA(申請一覧.承認ボタン)相当
         */
        {
            Org cond = new Org();
            cond.setOrgid(iOrgid);
            List<Org> orgs = orgDao.get(cond);
            final Org org = orgs.get(0);
            
            if(mailAddressCheck.existWithoutOrg(org.getAddress())) {
                throw new RuntimeException("このメールアドレスは既に使用されています。");
            }
            
            org.setStatus(Org.STATUS_承認済み);
            org.setApprovaldate(AppUtils.createNowLong());
            orgDao.update(org, updateUserId); // 【更新実施】
            
            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, updateUserId); // 【更新実施】
            
            iUsrid = usr.getUsrid();
        }
        
        
        /*
         * 本登録
         * EntryPasswordPage相当
         */
        {
            Usr usr = usrDao.getByUsrid(iUsrid);
            
            /* ユーザ情報更新 */
            String pwhash = CalcHash.passowrdHash(pw, usr.getLoginid());
            usr.setPwhash(pwhash);
            usr.setModpwdate(AppUtils.createNowLong());
            usr.setJoindate(AppUtils.createNowLong()); // 入会日時
            usr.setStatus(Usr.STATUS_登録済み);
            
            usrDao.update(usr, AppDef.USERID_NONE); // 【更新処理】
            
            
            /* 機関情報更新 */
            Org org = orgDao.getByOrgid(usr.getOrgid());
            if(org == null) {
                throw new RuntimeException("組織情報が登録されていません。");
            }
            org.setStatus(Org.STATUS_本登録済み);
            org.setJoindate(AppUtils.createNowLong()); // 本登録日時
            
            orgDao.update(org, AppDef.USERID_NONE); // 【更新処理】
        }
        
    }
    

    public static int toInt(String value) {
        if (StringUtils.isEmpty(value)) {
            return -1;
        }
        int i;
        try {
            i = Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return -1;
        }
        if (i < 0 || i > 99) {
            return i;
        }
        return i;
    }

    public String combine(String baseValue, int num) {
        return combine(baseValue, String.valueOf(num));
    }
    public String combine(String baseValue, String num) {
        return baseValue + StringUtils.leftPad(num, 2, "0");
    }



}
