package jp.agentec.abook.abv.ui.home.helper;

import java.util.List;
import java.util.Map;

import jp.agentec.abook.abv.bl.acms.type.OperationSortingType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.OperationGroupMasterDao;
import jp.agentec.abook.abv.bl.data.dao.WorkingReportDao;
import jp.agentec.abook.abv.bl.dto.OperationDto;
import jp.agentec.abook.abv.bl.dto.OperationGroupMasterDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.OperationGroupMasterLogic;
import jp.agentec.abook.abv.launcher.android.ABVApplication;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.home.activity.OperationListActivity;
import jp.agentec.adf.util.CollectionUtil;

import static jp.agentec.abook.abv.cl.util.PreferenceUtil.getUserPref;

public class OperationGroupMasterListHelper extends CategoryOperationListHelper<OperationGroupMasterDto> {

    private static final String TAG = "OperationGroupMasterListHelper";
    private OperationGroupMasterDao mOperationGroupMasterDao = AbstractDao.getDao(OperationGroupMasterDao.class);
    private OperationGroupMasterLogic mOperationGroupMasterLogic = AbstractLogic.getLogic(OperationGroupMasterLogic.class);

    public OperationGroupMasterListHelper(OperationListActivity appActivity) {
        super(appActivity);
        // キャッシュのスタックを利用する
        stack = ABVApplication.getABVUIDataCache(mAppActivity).operationGroupMasterStack;

        if (stack.size() == 0) {
            // スタックが空の場合、全体を入れる
            OperationGroupMasterDto operationGroupMasterDto;
            // 保存されたoperationGroupmasterIdが0または、存在しない場合
            if (mAppActivity.getOperationGroupMasterId() == 0 || !mOperationGroupMasterDao.isExistOperationGroupMaster(mAppActivity.getOperationGroupMasterId())) {
                // 最上位階層をセット
                operationGroupMasterDto = mOperationGroupMasterDao.getTopOperationGroupMaster();
                if (operationGroupMasterDto != null) {
                    pushList(operationGroupMasterDto);
                }
            } else {
                // 前回開いた際のIDでセット
                List<OperationGroupMasterDto> operationGroupMasterDtoList = mOperationGroupMasterLogic.getParentOperationGroupMasterForPath(mAppActivity.getOperationGroupMasterId());
                if (CollectionUtil.isNotEmpty(operationGroupMasterDtoList)) {
                    for (OperationGroupMasterDto dto : operationGroupMasterDtoList) {
                        pushList(dto);
                    }
                }
            }
        } else {
            // スタックに積まれている分だけパンくずボタンを作成
            for (int i = 0; i < stack.size(); i++) {
                OperationGroupMasterDto groupDto = stack.get(i);
                addBreadCrumbs(groupDto.operationGroupMasterName, i + 1);
            }
        }
    }

    /**
     * データの取得処理（新着更新処理完了後行われる）
     * @return 作業一覧に表示されるリスト
     * @throws Exception
     */
    @Override
    protected List<OperationDto> findOperationList() throws Exception {
        // クリアフラグがfalseの場合
        if (ABVEnvironment.getInstance().getOperationGroupMasterClearFlg()) {
            // 表示する作業種別が既に削除された場合、最上位階層に戻る（リセット）
            popList(breadCrumbList.size() - 1, false);
            // クリアフラグをfalseにセット
            ABVEnvironment.getInstance().setOperationGroupMasterClearFlg(false);
            // 作業種別の選択画面を閉じる
            mAppActivity.closeOperationGroupMasterDialog();
        }
        OperationGroupMasterDto peekOperationGroupMasterDto = stack.peek();

        mAppActivity.checkBatchNeedSyncButton(peekOperationGroupMasterDto.operationGroupMasterId);
        // ソート方向
        int operationSortType = mAppActivity.getSortCondition();
        OperationSortingType operationSortingType = OperationSortingType.parse(operationSortType);
        // 報告 or 定期点検
        String reportTypeStr = getUserPref(mAppActivity, AppDefType.UserPrefKey.OPERATION_REPORT_TYPES, null);

        List<OperationDto> list = mOperationGroupMasterLogic.getOperationByOperationGroupMasterId(peekOperationGroupMasterDto.operationGroupMasterId, reportTypeStr, operationSortingType);

        // ローカル保存している分を補正する
        WorkingReportDao dao = AbstractDao.getDao(WorkingReportDao.class);
        Map<Long, Integer> working = dao.getWorkingTaskReportCounts();
        for (OperationDto dto : list) {
            Integer workingCount = working.get(dto.operationId);
            if (workingCount != null) {
                dto.statusNotStartedCount += workingCount;
            }
        }
        return list;
    }

    /**
     * 親階層へ移動処理
     * @param popCount いくつ上の階層を表示するか指定します。
     * @param isReload リロードする・しない判定
     */
    @Override
    public void popList(int popCount, boolean isReload) {
        for (int i = 0; i < popCount; i++) {
            stack.pop();
            // パンくずリスト削除
            removeBreadCrumbs(breadCrumbList.get(breadCrumbList.size() - 1));
        }
        // 移動した作業種別のIDセット
        mAppActivity.setOperationGroupMasterId(stack.get(getStackSize() - 1).operationGroupMasterId);

        breadCrumbList.get(breadCrumbList.size() - 1);
        if (isReload) {
            // 作業一覧画面を更新する
            refreshList();
        }
    }

    @Override
    public void pushList(OperationGroupMasterDto operationGroupMasterDto) {
        if (operationGroupMasterDto == null) {
            Logger.w(TAG, "[pushList] groupDto is null");
            return;
        }
        // パンくずリスト追加
        addBreadCrumbs(operationGroupMasterDto.operationGroupMasterName);
        // ID保存
        mAppActivity.setOperationGroupMasterId(operationGroupMasterDto.operationGroupMasterId);
        stack.push(operationGroupMasterDto);
        refreshList();
    }

    @Override
    public String getPrePeekName() {
        String groupName = "";

        if (stack.size() > 1) {
            groupName = stack.get(stack.size() - 2).operationGroupMasterName;
        }

        return groupName;
    }

    @Override
    public String getPeekName() {
        String groupName = "";

        if (stack.size() > 0) {
            groupName = stack.peek().operationGroupMasterName;
        }

        return groupName;
    }

    /**
     * 親階層の情報で下の階層をリストで取得
     * @return List<OperationGroupMasterDto>
     */
    @Override
    public List<OperationGroupMasterDto> getChildList() {
        OperationGroupMasterDto peekOperationGroupMasterDto = stack.peek();
        return getChildList(peekOperationGroupMasterDto.operationGroupMasterId);
    }

    /**
     * 親階層のIDで下の階層をリストで取得
     * @param operationGroupMasterId
     * @return List<OperationGroupMasterDto>
     */
    public List<OperationGroupMasterDto> getChildList(Integer operationGroupMasterId) {
        return mOperationGroupMasterDao.getOperationGroupMasterChildList(operationGroupMasterId);
    }
}
