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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.cl.util.BitmapUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;

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

public class OperationRelatedContentPanelAdapter extends BaseAdapter {
	final private String TAG = "OperationRelatedContentPanelAdapter";

	private Context context;
	private LayoutInflater inflater;
	private final int thumbnailSizeWidth;
	private final int thumbnailSizeHeight;
	private final int padding;
	private int categoryId;

    private List<ContentDto> listItem = new ArrayList<>();
	private OperationRelatedContentPanelListener mListener;
	private ConcurrentHashMap<Long, ViewHolder> viewHolderMap;

	public interface OperationRelatedContentPanelListener {
        boolean onContentDownload(long contentId);
        void onContentDownloadPause(ContentDto contentDto);
        void onContentDownloadResume(ContentDto contentDto);
        void onOpenContentView(long contentId);
		void onContentDelete(ContentDto contentDto);
		void onContentDownloadCancel(ContentDto contentDto);
	}

    public OperationRelatedContentPanelAdapter(Context context, List<ContentDto> listItem) {
        this.context = context;
        this.listItem = listItem;

        padding = (int) (4f * context.getResources().getDisplayMetrics().density + 0.5f);
        thumbnailSizeWidth = context.getResources().getDimensionPixelSize(R.dimen.content_panel_image_size_width) - padding;
        thumbnailSizeHeight = context.getResources().getDimensionPixelSize(R.dimen.content_panel_image_size_height) - padding;

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        viewHolderMap = new ConcurrentHashMap<>();
    }

	public void setAdapterListener(OperationRelatedContentPanelListener listener) {
		this.mListener = listener;
	}

    @Override
    public int getCount() {
        return listItem.size();
    }

    @Override
    public ContentDto getItem(int position) {
        return listItem.get(position);
    }

    @Override
    public long getItemId(int position) {
        return listItem.get(position).contentId;
    }

    public List<ContentDto> getListItem() {
        return listItem;
    }

    private static class ViewHolder {
        long contentId;
        TextView tvGenreName;
        RelativeLayout thumbnailLayout;
        TextView tvContentId;
        TextView tvLastDeliveryDate;
        TextView tvNewContentMark;
        TextView tvContentName;

        ImageView ivThumbnail;
        ProgressBar downloadProgressBar;

        LinearLayout operationLayout;
        Button btnSaveContent;
        Button btnDeleteContent;
        Button btnOpenContent;
        Button btnUpdateContent;
        Button btnPauseSave;
        Button btnRestartSave;
        Button btnCancelSave;
    }

    @Override
	public View getView(int position, View convertView, final ViewGroup parent) {
		ViewHolder holder = null;

		Logger.d(TAG, "OperationRelatedContentPanelAdapter getView ......");

		if (null == convertView) {
			holder = new ViewHolder();
            if (Build.MODEL.equals("SHT-W09")) {
                convertView = inflater.inflate(R.layout.item_related_content_panel_render_sht_w09, null);
            } else {
                convertView = inflater.inflate(R.layout.item_related_content_panel_render, null);
            }
			holder.tvContentId = (TextView) convertView.findViewById(R.id.content_id);
			holder.tvLastDeliveryDate = (TextView) convertView.findViewById(R.id.last_delivery_date);
            holder.tvNewContentMark = (TextView) convertView.findViewById(R.id.new_content_mark);
			holder.tvContentName = (TextView) convertView.findViewById(R.id.content_name);
			holder.thumbnailLayout = (RelativeLayout) convertView.findViewById(R.id.content_thumbnail_layout);
			holder.ivThumbnail = (ImageView) convertView.findViewById(R.id.content_thumbnail);
			holder.downloadProgressBar = (ProgressBar) convertView.findViewById(R.id.content_download_progress);
			holder.operationLayout = (LinearLayout) convertView.findViewById(R.id.operation_layout);
			holder.btnSaveContent = (Button) convertView.findViewById(R.id.save_content);
			holder.btnOpenContent = (Button) convertView.findViewById(R.id.open_content);
            holder.btnUpdateContent = (Button) convertView.findViewById(R.id.update_content);
			holder.btnDeleteContent = (Button) convertView.findViewById(R.id.delete_content);
			holder.btnPauseSave = (Button) convertView.findViewById(R.id.pause_save);
			holder.btnRestartSave = (Button) convertView.findViewById(R.id.restart_save);
			holder.btnCancelSave = (Button) convertView.findViewById(R.id.cancel_save);
            convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		final ContentDto contentDto = getItem(position);

		// コンテンツID
		holder.tvContentId.setText(context.getString(R.string.content_num) + " " + contentDto.contractContentId);

		// 最後の公開処理日
		String lastDeliveryDate = DateTimeUtil.toString(contentDto.lastDeliveryDate, DateTimeFormat.yyyyMMdd_slash);
		if (lastDeliveryDate != null) {
            // リソースパターンの適用
			holder.tvLastDeliveryDate.setText(lastDeliveryDate + " " + PatternStringUtil.patternToString(context,
                                                                        R.string.content_update,
                                                                        getUserPref(context, AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
		}

		// コンテンツ名
		holder.tvContentName.setText(" " + contentDto.contentName);

		// サムネイル
		if (holder.ivThumbnail.getDrawable() != null) {
			((BitmapDrawable) holder.ivThumbnail.getDrawable()).getBitmap().recycle();
		}

		Bitmap resized = BitmapUtil.getResizedBitmap(contentDto.thumbnailNormalPath, thumbnailSizeWidth, thumbnailSizeHeight, Config.RGB_565);
		// nullの場合サムネイルなしイメージを表示
		if (resized == null) {
			resized = BitmapUtil.getResizedBitmapResource(context.getResources(), R.drawable.not_exist_thumbnail, thumbnailSizeWidth, thumbnailSizeHeight, Config.RGB_565);
		}
		// レイアウトを画像サイズに合わせる
		ViewGroup.LayoutParams params = holder.thumbnailLayout.getLayoutParams();
		params.width = resized.getWidth() + padding;
		params.height = resized.getHeight() + padding;
		holder.ivThumbnail.setImageBitmap(resized);

		createDownloadView(holder, contentDto);

		// 操作
		configureOperationButton(holder, contentDto);

		holder.contentId = getItemId(position);
		viewHolderMap.put(contentDto.contentId, holder);
		return convertView;
	}

	public void configureOperationButton(final ViewHolder holder, final ContentDto contentDto) {

		Logger.d(TAG, "configureOperationButton ......");

        holder.tvNewContentMark.setVisibility(View.GONE);
		holder.operationLayout.setVisibility(View.VISIBLE);
		holder.btnSaveContent.setVisibility(View.GONE);
		holder.btnDeleteContent.setVisibility(View.GONE);
		holder.btnOpenContent.setVisibility(View.GONE);
        holder.btnUpdateContent.setVisibility(View.GONE);
		holder.btnPauseSave.setVisibility(View.GONE);
		holder.btnRestartSave.setVisibility(View.GONE);
		holder.btnCancelSave.setVisibility(View.GONE);

        setNewRibbon(holder, contentDto);

        if (contentDto.downloadingFlg && !contentDto.isDownloadPaused()) {
            Logger.d(TAG, "isPauseDownloading ......");
            // ダウンロード中
            holder.btnPauseSave.setVisibility(View.VISIBLE);
            holder.btnPauseSave.setOnClickListener(new OnDownloadPauseButtonClickListener(contentDto));

        } else if (!contentDto.downloadedFlg && !contentDto.isDownloadPaused() ) {
            Logger.d(TAG, "isDownloadable ......");
            holder.btnSaveContent.setVisibility(View.VISIBLE);
            holder.btnSaveContent.setOnClickListener(new OnDownloadButtonClickListener(contentDto));

        } else if (contentDto.downloadedFlg && contentDto.updatedFlg && !contentDto.isDownloadPaused() ) {
            Logger.d(TAG, "isOpenable & isDeletable & isUpdatable......");
            holder.btnOpenContent.setVisibility(View.VISIBLE);
            holder.btnOpenContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    mListener.onOpenContentView(contentDto.contentId);
                }
            });

            holder.btnDeleteContent.setVisibility(View.VISIBLE);
            holder.btnDeleteContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    mListener.onContentDelete(contentDto);
                }
            });

            holder.btnUpdateContent.setVisibility(View.VISIBLE);
            holder.btnUpdateContent.setOnClickListener(new OnDownloadButtonClickListener(contentDto));

        } else if (contentDto.downloadedFlg && !contentDto.updatedFlg) {
            Logger.d(TAG, "isOpenable & isDeletable......");
            holder.btnOpenContent.setVisibility(View.VISIBLE);
            holder.btnOpenContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    mListener.onOpenContentView(contentDto.contentId);
                }
            });

            holder.btnDeleteContent.setVisibility(View.VISIBLE);
            holder.btnDeleteContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    mListener.onContentDelete(contentDto);
                }
            });

        }else if (contentDto.isDownloadPaused()) {
            // ダウンロード一時停止中
            Logger.d(TAG, "isDownloadPaused & isCancelable......");
            holder.btnRestartSave.setVisibility(View.VISIBLE);
            holder.btnRestartSave.setOnClickListener(new OnDownloadResumeButtonClickListener(contentDto));

            holder.btnCancelSave.setVisibility(View.VISIBLE);
            holder.btnCancelSave.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(final View v) {
                    mListener.onContentDownloadCancel(contentDto);
                }
            });

        }
	}

	private void setNewRibbon(ViewHolder holder, final ContentDto contentDto) {
        if (!contentDto.downloadedFlg && contentDto.newFlg) {
            holder.tvNewContentMark.setVisibility(View.VISIBLE);
            // リソースパターンの適用
            holder.tvNewContentMark.setText(PatternStringUtil.patternToString(context,
                                                R.string.new_content,
                                                getUserPref(context, AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        } else {
            holder.tvNewContentMark.setVisibility(View.GONE);
        }
    }

	public void updateDownloadView(ContentDto contentDto) {
		Logger.d(TAG, "updateDownloadView ......");
		ViewHolder holder = viewHolderMap.get(contentDto.contentId);
		if (holder != null && holder.contentId == contentDto.contentId) {
			createDownloadView(holder, contentDto);
			if (listItem.indexOf(contentDto) == 0) {
				notifyDataSetChanged();
			}
		}
	}

	/**
	 * ダウンロードの状態によって表示が変化するViewを作成する
	 * 
	 * @param holder
	 * @param contentDto
	 */
	private void createDownloadView(ViewHolder holder, final ContentDto contentDto) {
		Logger.d(TAG, "createDownloadView ......");

		ProgressBar downloadProgressBar = holder.downloadProgressBar;
        ImageView thumbnail = holder.ivThumbnail;
        thumbnail.setEnabled(false);

		if (contentDto.downloadingFlg) {
			if (contentDto.isDownloadPaused()) {
				// ダウンロード一時停止中
				downloadProgressBar.setEnabled(false);
            } else if (contentDto.isDownloadInitializing()) {
                // 初期化中
                downloadProgressBar.setEnabled(true);
            } else {
				// ダウンロード中
				downloadProgressBar.setEnabled(true);
			}

			// プログレスバー設定
			downloadProgressBar.setProgress(contentDto.downloadProgress);
			downloadProgressBar.setVisibility(View.VISIBLE);
		} else {
			downloadProgressBar.setProgress(0);
			downloadProgressBar.setVisibility(View.INVISIBLE);
		}

		// ボタン制御
        configureOperationButton(holder, contentDto);
	}


    private class OnDownloadButtonClickListener implements View.OnClickListener{
        private ContentDto contentDto;

        public OnDownloadButtonClickListener(ContentDto contentDto) {
            this.contentDto = contentDto;
        }

        @Override
        public void onClick(final View v) {
            contentDto.downloadingFlg = true;
            updateDownloadView(contentDto);
            // ダウンロード登録に時間がかかるので非同期処理で実行
            AsyncTask<Params, Void, Result> task = new AsyncTask<Params, Void, Result>() {
                @Override
                protected Result doInBackground(Params... params) {
                    Logger.d(TAG, "onContentDownload start ......");
                    Result result = new Result();
                    result.result = mListener.onContentDownload(params[0].contentId);
                    return result;
                }

                @Override
                protected void onPostExecute(Result result) {
                    Logger.d(TAG, "onContentDownload after ......");
                    if (!result.result) {
                        contentDto.downloadingFlg = false;
                    }
                }
            };
            Params params = new Params();
            params.contentId = contentDto.contentId;
            task.execute(params);
        }
    }

    private  class OnDownloadPauseButtonClickListener implements View.OnClickListener{
        private ContentDto contentDto;

        public OnDownloadPauseButtonClickListener(ContentDto contentDto) {
            this.contentDto = contentDto;
        }

        @Override
        public void onClick(View v) {
            AsyncTask<Params, Void, Void> task = new AsyncTask<Params, Void, Void>() {
                @Override
                protected Void doInBackground(Params... params) {
                    Logger.d(TAG, "onContentDownloadPause start ......");
                    mListener.onContentDownloadPause(contentDto);
                    return null;
                }
            };

            Params params = new Params();
            params.contentId = contentDto.contentId;
            task.execute(params);

        }
    }

    private class OnDownloadResumeButtonClickListener implements View.OnClickListener{
        private ContentDto contentDto;

        public OnDownloadResumeButtonClickListener(ContentDto contentDto) {
            this.contentDto = contentDto;
        }

        @Override
        public void onClick(View v) {
            // ダウンロード登録に時間がかかるので非同期処理で実行
            AsyncTask<Params, Void, Void> task = new AsyncTask<Params, Void, Void>() {
                @Override
                protected Void doInBackground(Params... params) {
                    Logger.d(TAG, "onContentDownloadResume start ......");
                    mListener.onContentDownloadResume(contentDto);
                    return null;
                }
            };
            Params params = new Params();
            params.contentId = contentDto.contentId;
            task.execute(params);

        }
    }

    class Params {
        long contentId;
    }

    class Result {
        boolean result;
    }
}
