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

import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.ListView;

import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshGridView;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.OperationDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.launcher.android.ABVApplication;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.ViewMode;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.home.activity.OperationListActivity;
import jp.agentec.abook.abv.ui.home.adapter.AbstractOperationAdapter;
import jp.agentec.abook.abv.ui.home.adapter.OperationListAdapter;
import jp.agentec.abook.abv.ui.home.adapter.OperationPanelAdapter;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.StringUtil;

import static jp.agentec.abook.abv.bl.acms.type.OperationType.PANO;
import static jp.agentec.abook.abv.cl.util.PreferenceUtil.getUserPref;

/**
 * Created by leej on 2019/03/06.
 */

public abstract class OperationListHelper {
    private static final String TAG = "OperationListHelper";
    protected OperationListActivity mAppActivity;
    private AbstractOperationAdapter mAdapter;
    private PullToRefreshListView mPullToRefreshListView;
    private PullToRefreshGridView mPullToRefreshGridView;
    protected OperationLogic operationLogic = AbstractLogic.getLogic(OperationLogic.class);
    private List<OperationDto> operationDtoList = new ArrayList<>();

    // スマートフォンの1行のパンネル数
    private static final int NORMAL_SIZE_COLUMN = 1;
    // タブレット縦で1行のパンネル数
    private static final int LARGE_ORIENTATION_PORTRAIT_SIZE_COLUMN = 2;
    // タブレット横で1行のパンネル数
    private static final int LARGE_ORIENTATION_LANDSCAPE_SIZE_COLUMN = 3;


    public OperationListHelper(OperationListActivity activity) {
        mAppActivity = activity;
        mPullToRefreshListView = new PullToRefreshListView(activity);
        mPullToRefreshGridView = new PullToRefreshGridView(activity);
    }

    private List<OperationDto> filterOperationList() {
        try {

            operationDtoList = findOperationList();

            for (OperationDto operationDto : operationDtoList) {
                // 該当する作業の最後に同期した日付を取得
                String syncedDateStr = getUserPref(mAppActivity, String.format(AppDefType.UserPrefKey.SYNCED_OPERATION_ID, operationDto.operationId), "");
                Date syncedDate = null;
                if (!StringUtil.isNullOrEmpty(syncedDateStr)) {
                    syncedDate = DateTimeUtil.toDate(syncedDateStr, DateTimeFormat.yyyyMMddHHmmss_slash);
                }
                operationLogic.updateOperationNeedSyncFlg(operationDto, syncedDate);
            }
        } catch (Exception e) {
            Logger.e(TAG, "findOperationList", e);
            ErrorMessage.showErrorMessageToast(mAppActivity.getApplicationContext(), ErrorCode.E107);
        }
        return operationDtoList;
    }

    // リスト・パンネルビューの取得
    public ViewGroup getOperationView() {
        int checkedViewModeId = ABVApplication.getABVUIDataCache(mAppActivity).getViewMode();
        ViewGroup child;
        if (checkedViewModeId == ViewMode.PANEL) {
            child = getPanelModeView();
        } else if (checkedViewModeId == ViewMode.LIST) {
            child = getListModeView();
        } else {
            child = getPanelModeView();
        }
        return child;
    }

    // パネル式のViewを取得
    private ViewGroup getPanelModeView() {
        Logger.d(TAG, "getPanelModeView");
        mPullToRefreshGridView.setEmptyView(mAppActivity.findViewById(android.R.layout.simple_list_item_1));

        GridView child = mPullToRefreshGridView.getRefreshableView();

        mPullToRefreshGridView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<GridView>() {
            @Override
            public void onRefresh(PullToRefreshBase<GridView> refreshView) {
                // 新着更新処理
                mAppActivity.pullToGridViewRefresh(refreshView);
            }
        });

        // ラベル変更
        mAppActivity.getIntent();
        // リソースパターンの適用
        mPullToRefreshGridView.getLoadingLayoutProxy().setRefreshingLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                    R.string.updating,
                                                                                                    getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
        // リソースパターンの適用
        mPullToRefreshGridView.getLoadingLayoutProxy().setPullLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                R.string.pull_to_refresh_label,
                                                                                                getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
        // リソースパターンの適用
        mPullToRefreshGridView.getLoadingLayoutProxy().setReleaseLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                R.string.release_to_refresh_label,
                                                                                                getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));

        if (mAppActivity.isNormalSize()) {
            // スマートフォンの場合、1行当たりのパンネル数
            child.setNumColumns(NORMAL_SIZE_COLUMN);
        } else {
            // タブレットの場合、1行当たりのパンネル数
            if (mAppActivity.isOrientationPortrait()) {
                // 縦
                child.setNumColumns(LARGE_ORIENTATION_PORTRAIT_SIZE_COLUMN);
            } else {
                // 横
                child.setNumColumns(LARGE_ORIENTATION_LANDSCAPE_SIZE_COLUMN);
            }
        }

        OperationPanelAdapter adapter = new OperationPanelAdapter(mAppActivity, filterOperationList());
        child.setAdapter(adapter);

        // リストの要素であるボタンクリック処理
        adapter.setAdapterListener(new AbstractOperationAdapter.AbstractOperationListAdapterListener() {
            @Override
            public void openReport(OperationDto operationDto) {
                onClickReport(operationDto);
            }

            @Override
            public void onSyncOperation(final OperationDto operationDto) {
                mAppActivity.mQrCodeOperationId = null;
                // 同期処理
                mAppActivity.startSyncOperation(operationDto);
            }
        });

        child.setScrollingCacheEnabled(false);

        mAdapter = adapter;

        return mPullToRefreshGridView;
    }

    // リスト式のViewを取得
    private ViewGroup getListModeView() {
        Logger.d(TAG, "getListModeView");
        mPullToRefreshListView.setEmptyView(mAppActivity.findViewById(android.R.layout.simple_list_item_1));
        ListView child = mPullToRefreshListView.getRefreshableView();
        OperationListAdapter adapter = new OperationListAdapter(mAppActivity, filterOperationList());
        child.setAdapter(adapter);

        mPullToRefreshListView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                // 新着更新処理
                mAppActivity.pullToListViewRefresh(refreshView);

            }
        });

        // ラベル変更
        mPullToRefreshListView.getLoadingLayoutProxy().setRefreshingLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                    R.string.updating,
                                                                                                    getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
        // リソースパターンの適用
        mPullToRefreshListView.getLoadingLayoutProxy().setPullLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                R.string.pull_to_refresh_label,
                                                                                                getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
        // リソースパターンの適用
        mPullToRefreshListView.getLoadingLayoutProxy().setReleaseLabel(mAppActivity.getString(PatternStringUtil.patternToInt(mAppActivity.getApplicationContext(),
                                                                                                R.string.release_to_refresh_label,
                                                                                                getUserPref(mAppActivity.getApplicationContext(), AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));

        // リスト以外のクリック処理
        adapter.setAdapterListener(new AbstractOperationAdapter.AbstractOperationListAdapterListener() {
            @Override
            public void openReport(OperationDto operationDto) {
                onClickReport(operationDto);
            }

            @Override
            public void onSyncOperation(final OperationDto operationDto) {
                mAppActivity.mQrCodeOperationId = null;
                // 同期処理
                mAppActivity.startSyncOperation(operationDto);
            }
        });

        child.setScrollingCacheEnabled(false);
        mAdapter = adapter;
        return mPullToRefreshListView;
    }

    /**
     * 作業の画面更新
     */
    public void refreshList() {
        if (mAdapter != null) {
            mAdapter.setItem(filterOperationList());
        }
    }

    /**
     * プロジェクトの件数取得
     * @return
     */
    public int getOperationCount() {
        return operationDtoList.size();
    }

    /**
     * 表示中の作業の中に同期が必要な作業のみ返す。
     * @return 作業情報配列
     */
    public List<OperationDto> getNeedSyncOperationList() {
        List<OperationDto> needSyncOperationList = new ArrayList<>();
        for (OperationDto operationDto :  operationDtoList) {
            if (operationDto.needSyncFlg) {
                needSyncOperationList.add(operationDto);
            }
        }
        return needSyncOperationList;
    }
    /**
     * プロジェクトリスト取得
     * @return
     */
    public List<OperationDto> getOperationList() {
        return operationDtoList;
    }

    /**
     * 作業を検索してListを返す
     *
     * @return
     * @throws Exception
     * @throws NetworkDisconnectedException
     */
    abstract protected List<OperationDto> findOperationList() throws Exception;

    public void onClickReport(OperationDto operationDto) {
        if (ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            mAppActivity.autoSyncOperationId(operationDto.operationId);
            return;
        }
        if (operationDto.contentId != null && operationDto.contentId != 0) {
            // 作業画面
            mAppActivity.openReportView(operationDto);
        } else {
            if (operationDto.operationType == PANO) {
                // パノラマ登録画面
                mAppActivity.showPanoEntryDialog(operationDto);
            } else {
                // 何もしない
                Logger.e("not open target");
            }
        }
    }

}
