package com.mxt.anitrend.base.custom.view.widget;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.mxt.anitrend.R;
import com.mxt.anitrend.base.interfaces.event.RetroCallback;
import com.mxt.anitrend.base.interfaces.view.CustomView;
import com.mxt.anitrend.databinding.WidgetToolbarFavouriteBinding;
import com.mxt.anitrend.model.entity.base.CharacterBase;
import com.mxt.anitrend.model.entity.base.MediaBase;
import com.mxt.anitrend.model.entity.base.StaffBase;
import com.mxt.anitrend.model.entity.base.StudioBase;
import com.mxt.anitrend.presenter.widget.WidgetPresenter;
import com.mxt.anitrend.util.CompatUtil;
import com.mxt.anitrend.util.KeyUtil;
import com.mxt.anitrend.util.NotifyUtil;
import com.mxt.anitrend.util.graphql.AniGraphErrorUtilKt;
import com.mxt.anitrend.util.graphql.GraphUtil;
import com.mxt.anitrend.util.media.MediaUtil;

import io.github.wax911.library.model.request.QueryContainerBuilder;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import timber.log.Timber;

/**
 * Created by max on 2018/01/31.
 * Widget for handling favourite toggles
 */

public class FavouriteToolbarWidget extends FrameLayout implements CustomView, RetroCallback<ResponseBody>, View.OnClickListener {

    private WidgetPresenter<ResponseBody> presenter;
    private WidgetToolbarFavouriteBinding binding;

    private StaffBase staffBase;
    private MediaBase mediaBase;
    private StudioBase studioBase;
    private CharacterBase characterBase;

    private QueryContainerBuilder queryContainer;

    private final String TAG = FavouriteToolbarWidget.class.getSimpleName();

    public FavouriteToolbarWidget(@NonNull Context context) {
        super(context);
        onInit();
    }

    public FavouriteToolbarWidget(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        onInit();
    }

    public FavouriteToolbarWidget(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        onInit();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public FavouriteToolbarWidget(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        onInit();
    }

    @Override
    public void onInit() {
        presenter = new WidgetPresenter<>(getContext());
        binding = WidgetToolbarFavouriteBinding.inflate(CompatUtil.INSTANCE.getLayoutInflater(getContext()), this, true);
        queryContainer = GraphUtil.INSTANCE.getDefaultQuery(false)
                .putVariable(KeyUtil.arg_page_limit, KeyUtil.SINGLE_ITEM_LIMIT);
        binding.setOnClickEvent(this);
    }

    /**
     * Clean up any resources that won't be needed
     */
    @Override
    public void onViewRecycled() {
        resetFlipperState();
        if(presenter != null)
            presenter.onDestroy();
    }

    private void resetFlipperState() {
        if(binding.widgetFlipper.getDisplayedChild() == WidgetPresenter.LOADING_STATE)
            binding.widgetFlipper.setDisplayedChild(WidgetPresenter.CONTENT_STATE);
    }

    public void setModel(StaffBase staffBase) {
        this.staffBase = staffBase;
        setIconType();
        queryContainer.putVariable(KeyUtil.arg_staffId, staffBase.getId());
        presenter.getParams().putParcelable(KeyUtil.arg_graph_params, queryContainer);
        binding.widgetFlipper.setVisibility(VISIBLE);
    }

    public void setModel(CharacterBase characterBase) {
        this.characterBase = characterBase;
        setIconType();
        queryContainer.putVariable(KeyUtil.arg_characterId, characterBase.getId());
        presenter.getParams().putParcelable(KeyUtil.arg_graph_params, queryContainer);
        binding.widgetFlipper.setVisibility(VISIBLE);
    }

    public void setModel(StudioBase studioBase) {
        this.studioBase = studioBase;
        setIconType();
        queryContainer.putVariable(KeyUtil.arg_studioId, studioBase.getId());
        presenter.getParams().putParcelable(KeyUtil.arg_graph_params, queryContainer);
        binding.widgetFlipper.setVisibility(VISIBLE);
    }

    public void setModel(MediaBase mediaBase) {
        this.mediaBase = mediaBase;
        setIconType();
        queryContainer.putVariable(MediaUtil.isAnimeType(mediaBase) ? KeyUtil.arg_animeId : KeyUtil.arg_mangaId, mediaBase.getId());
        presenter.getParams().putParcelable(KeyUtil.arg_graph_params, queryContainer);
        binding.widgetFlipper.setVisibility(VISIBLE);
    }

    public boolean isModelSet() {
        return staffBase != null || characterBase != null ||
                studioBase != null || mediaBase != null;
    }

    @Override
    public void onClick(View view) {
        if(presenter.getSettings().isAuthenticated())
            if (view.getId() == R.id.widget_flipper) {
                if (isModelSet()) {
                    if (binding.widgetFlipper.getDisplayedChild() == WidgetPresenter.CONTENT_STATE) {
                        binding.widgetFlipper.showNext();
                        presenter.requestData(KeyUtil.MUT_TOGGLE_FAVOURITE, getContext(), this);
                    } else
                        NotifyUtil.INSTANCE.makeText(getContext(), R.string.busy_please_wait, Toast.LENGTH_SHORT).show();
                } else
                    NotifyUtil.INSTANCE.makeText(getContext(), R.string.text_activity_loading, Toast.LENGTH_SHORT).show();
            }
            else
                NotifyUtil.INSTANCE.makeText(getContext(), R.string.info_login_req, R.drawable.ic_group_add_grey_600_18dp, Toast.LENGTH_SHORT).show();
    }

    private void setIconType() {
        boolean isFavourite = false, requiresTint = true;

        if(mediaBase != null) {
            isFavourite = mediaBase.isFavourite();
            requiresTint = false;
        }
        else if (studioBase != null)
            isFavourite = studioBase.isFavourite();
        else if (staffBase != null)
            isFavourite = staffBase.isFavourite();
        else if (characterBase != null)
            isFavourite = characterBase.isFavourite();

        if(isFavourite)
            binding.widgetLike.setImageDrawable(requiresTint ? CompatUtil.INSTANCE.getTintedDrawable(getContext(),
                    R.drawable.ic_favorite_white_24dp) : CompatUtil.INSTANCE.getDrawable(getContext(), R.drawable.ic_favorite_white_24dp));
        else
            binding.widgetLike.setImageDrawable(requiresTint ? CompatUtil.INSTANCE.getTintedDrawable(getContext(),
                    R.drawable.ic_favorite_border_white_24dp) : CompatUtil.INSTANCE.getDrawable(getContext(), R.drawable.ic_favorite_border_white_24dp));

        resetFlipperState();
    }

    @Override
    public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
        try {
            if(response.isSuccessful()) {
                if(mediaBase != null)
                    mediaBase.toggleFavourite();
                else if (studioBase != null)
                    studioBase.toggleFavourite();
                else if (staffBase != null)
                    staffBase.toggleFavourite();
                else if (characterBase != null)
                    characterBase.toggleFavourite();
                setIconType();
            } else {
                Timber.tag(TAG).w(AniGraphErrorUtilKt.apiError(response));
                NotifyUtil.INSTANCE.makeText(getContext(), R.string.text_error_request, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            Timber.tag(TAG).w(e);
            e.printStackTrace();
        }
    }

    @Override
    public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable throwable) {
        try {
            Timber.tag(TAG).e(throwable);
            resetFlipperState();
        } catch (Exception e) {
            Timber.tag(TAG).e(e);
            e.printStackTrace();
        }
    }
}
