package tr.xip.wanikani.app.activity;

import android.content.Intent;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import com.squareup.picasso.Picasso;

import org.apache.commons.lang3.text.WordUtils;

import java.text.SimpleDateFormat;
import java.util.Arrays;

import retrofit2.Call;
import retrofit2.Response;
import tr.xip.wanikani.R;
import tr.xip.wanikani.client.WaniKaniApi;
import tr.xip.wanikani.client.task.callback.ThroughDbCallback;
import tr.xip.wanikani.database.DatabaseManager;
import tr.xip.wanikani.managers.PrefManager;
import tr.xip.wanikani.models.BaseItem;
import tr.xip.wanikani.models.CriticalItem;
import tr.xip.wanikani.models.ItemsList;
import tr.xip.wanikani.models.KanjiList;
import tr.xip.wanikani.models.RadicalsList;
import tr.xip.wanikani.models.Request;
import tr.xip.wanikani.models.UnlockItem;
import tr.xip.wanikani.models.VocabularyList;
import tr.xip.wanikani.utils.Fonts;
import tr.xip.wanikani.widget.ObservableScrollView;
import tr.xip.wanikani.widget.RelativeTimeTextView;

/**
 * Created by xihsa_000 on 3/23/14.
 */
public class ItemDetailsActivity extends AppCompatActivity {

    public static final String ARG_ITEM = "arg_item";
    private static final String TAG = "ItemDetailsActivity";
    private static final int FLIPPER_CONTENT = 0;
    private static final int FLIPPER_PROGRESS_BAR = 1;

    Toolbar mToolbar;

    TextView mTitle;
    ImageView mTitleImage;
    TextView mLevel;
    TextView mMeaning;

    CardView mItemCard;

    CardView mAlternativeMeaningsAndUserSynonymsCard;
    TextView mAlternativeMeanings;
    LinearLayout mAlternativeMeaningsHolder;
    TextView mUserSynonyms;
    LinearLayout mUserSynonymsHolder;

    CardView mReadingsCard;
    TextView mReading;
    LinearLayout mReadingHolder;
    TextView mOnyomi;
    LinearLayout mOnyomiHolder;
    TextView mKunyomi;
    LinearLayout mKunyomiHolder;

    TextView mReadingNote;
    CardView mReadingNoteCard;

    TextView mMeaningNote;
    CardView mMeaningNoteCard;

    LinearLayout mLocked;
    LinearLayout mBurned;
    TextView mBurnedDate;
    LinearLayout mProgressContent;

    CardView mProgressCard;

    TextView mAlternativeMeaningsTitle;
    TextView mUserSynonymsTitle;
    TextView mReadingTitle;
    TextView mMeaningNoteTitle;
    TextView mReadingNoteTitle;
    TextView mProgressTitle;

    ImageView mSRSLogo;
    TextView mSRSLevel;
    LinearLayout mUnlockHolder;
    TextView mUnlocked;
    LinearLayout mNextAvailableHolder;
    RelativeTimeTextView mNextAvailable;
    RelativeLayout mMeaningCorrectHolder;
    TextView mMeaningCorrectPercentage;
    RelativeLayout mMeaningIncorrectHolder;
    TextView mMeaningIncorrectPercentage;
    LinearLayout mMeaningMaxStreakHolder;
    TextView mMeaningMaxStreak;
    LinearLayout mMeaningCurrentStreakHolder;
    TextView mMeaningCurrentStreak;
    RelativeLayout mReadingCorrectHolder;
    TextView mReadingCorrectPercentage;
    RelativeLayout mReadingIncorrectHolder;
    TextView mReadingIncorrectPercentage;
    LinearLayout mReadingMaxStreakHolder;
    TextView mReadingMaxStreak;
    LinearLayout mReadingCurrentStreakHolder;
    TextView mReadingCurrentStreak;

    ProgressBar mMeaningCorrectProgressBar;
    ProgressBar mMeaningIncorrectProgressBar;
    ProgressBar mReadingCorrectProgressBar;
    ProgressBar mReadingIncorrectProgressBar;

    ObservableScrollView mScrollView;

    ViewFlipper mFlipper;

    BaseItem mItem;

    private int mToolbarHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Intent intent = getIntent();
        mItem = (BaseItem) intent.getSerializableExtra(ARG_ITEM);

        switch (mItem.getType()) {
            case RADICAL:
                setTheme(R.style.AppTheme_Radical);
                break;
            case KANJI:
                setTheme(R.style.AppTheme_Kanji);
                break;
            case VOCABULARY:
                setTheme(R.style.AppTheme_Vocabulary);
                break;
        }

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_item_details);

        setUpActionBar();

        mFlipper = (ViewFlipper) findViewById(R.id.details_view_flipper);

        mAlternativeMeaningsTitle = (TextView) findViewById(R.id.details_title_alternative_meanings);
        mUserSynonymsTitle = (TextView) findViewById(R.id.details_title_user_synonyms);
        mReadingTitle = (TextView) findViewById(R.id.details_title_reading);
        mMeaningNoteTitle = (TextView) findViewById(R.id.details_title_meaning_note);
        mReadingNoteTitle = (TextView) findViewById(R.id.details_title_reading_note);
        mProgressTitle = (TextView) findViewById(R.id.details_progress_title);

        setUpScrollView();

        mItemCard = (CardView) findViewById(R.id.item_card);

        mTitle = (TextView) findViewById(R.id.title);
        mTitleImage = (ImageView) findViewById(R.id.title_image);

        mLevel = (TextView) findViewById(R.id.details_level);
        mMeaning = (TextView) findViewById(R.id.details_meaning);

        mAlternativeMeaningsAndUserSynonymsCard = (CardView)
                findViewById(R.id.details_alternative_meanings_and_user_synonyms_card);

        mAlternativeMeanings = (TextView) findViewById(R.id.details_alternative_meanings);
        mAlternativeMeaningsHolder = (LinearLayout) findViewById(R.id.details_alternative_meanings_holder);
        mUserSynonyms = (TextView) findViewById(R.id.details_user_synonyms);
        mUserSynonymsHolder = (LinearLayout) findViewById(R.id.details_user_synonyms_holder);

        mReadingsCard = (CardView) findViewById(R.id.details_readings_card);

        mReading = (TextView) findViewById(R.id.details_reading);
        mReadingHolder = (LinearLayout) findViewById(R.id.details_readings_reading_holder);
        mOnyomi = (TextView) findViewById(R.id.details_readings_onyomi);
        mOnyomiHolder = (LinearLayout) findViewById(R.id.details_readings_onyomi_holder);
        mKunyomi = (TextView) findViewById(R.id.details_readings_kunyomi);
        mKunyomiHolder = (LinearLayout) findViewById(R.id.details_readings_kunyomi_holder);

        mReadingNote = (TextView) findViewById(R.id.details_reading_note);
        mReadingNoteCard = (CardView) findViewById(R.id.details_reading_note_card);

        mMeaningNote = (TextView) findViewById(R.id.details_meaning_note);
        mMeaningNoteCard = (CardView) findViewById(R.id.details_meaning_note_card);

        mLocked = (LinearLayout) findViewById(R.id.details_progress_locked);

        mBurned = (LinearLayout) findViewById(R.id.details_progress_burned);
        mBurnedDate = (TextView) findViewById(R.id.details_progress_burned_date);
        mProgressContent = (LinearLayout) findViewById(R.id.details_progress_content);

        mProgressCard = (CardView) findViewById(R.id.details_progress_card);

        mSRSLogo = (ImageView) findViewById(R.id.details_progress_srs_logo);
        mSRSLevel = (TextView) findViewById(R.id.details_progress_srs_level);
        mUnlockHolder = (LinearLayout) findViewById(R.id.details_progress_unlocked_holder);
        mUnlocked = (TextView) findViewById(R.id.details_progress_unlocked);
        mNextAvailableHolder = (LinearLayout) findViewById(R.id.details_progress_next_available_holder);
        mNextAvailable = (RelativeTimeTextView) findViewById(R.id.details_progress_next_available);
        mMeaningCorrectHolder = (RelativeLayout) findViewById(R.id.details_progress_meaning_correct_holder);
        mMeaningCorrectPercentage = (TextView) findViewById(R.id.details_progress_meaning_correct_percentage);
        mMeaningIncorrectHolder = (RelativeLayout) findViewById(R.id.details_progress_meaning_incorrect_holder);
        mMeaningIncorrectPercentage = (TextView) findViewById(R.id.details_progress_meaning_incorrect_percentage);
        mMeaningMaxStreakHolder = (LinearLayout) findViewById(R.id.details_progress_meaning_max_streak_holder);
        mMeaningMaxStreak = (TextView) findViewById(R.id.details_progress_meaning_max_streak);
        mMeaningCurrentStreakHolder = (LinearLayout) findViewById(R.id.details_progress_meaning_current_streak_holder);
        mMeaningCurrentStreak = (TextView) findViewById(R.id.details_progress_meaning_current_streak);
        mReadingCorrectHolder = (RelativeLayout) findViewById(R.id.details_progress_reading_correct_holder);
        mReadingCorrectPercentage = (TextView) findViewById(R.id.details_progress_reading_correct_percentage);
        mReadingIncorrectHolder = (RelativeLayout) findViewById(R.id.details_progress_reading_incorrect_holder);
        mReadingIncorrectPercentage = (TextView) findViewById(R.id.details_progress_reading_incorrect_percentage);
        mReadingMaxStreakHolder = (LinearLayout) findViewById(R.id.details_progress_reading_max_streak_holder);
        mReadingMaxStreak = (TextView) findViewById(R.id.details_progress_reading_max_streak);
        mReadingCurrentStreakHolder = (LinearLayout) findViewById(R.id.details_progress_reading_current_streak_holder);
        mReadingCurrentStreak = (TextView) findViewById(R.id.details_progress_reading_current_streak);

        mMeaningCorrectProgressBar = (ProgressBar) findViewById(R.id.details_progress_meaning_correct_progress);
        mMeaningIncorrectProgressBar = (ProgressBar) findViewById(R.id.details_progress_meaning_incorrect_progress);
        mReadingCorrectProgressBar = (ProgressBar) findViewById(R.id.details_progress_reading_correct_progress);
        mReadingIncorrectProgressBar = (ProgressBar) findViewById(R.id.details_progress_reading_incorrect_progress);

        mReading.setTypeface(new Fonts().getKanjiFont(this));
        mOnyomi.setTypeface(new Fonts().getKanjiFont(this));
        mKunyomi.setTypeface(new Fonts().getKanjiFont(this));

        switch (mItem.getType()) {
            case RADICAL:
                switchToRadicalMode();
                break;
            case KANJI:
                switchToKanjiMode();
                break;
            case VOCABULARY:
                switchToVocabularyMode();
                break;
        }

        if (mItem instanceof UnlockItem || mItem instanceof CriticalItem) {
            load(mItem.getType().toString(), mItem.getLevel(), mItem.getCharacter(), mItem.getImage());
        } else {
            if (mItem != null)
                loadData();
            else {
                Log.e(TAG, "No item object passed; exiting...");
                Toast.makeText(getApplicationContext(), R.string.error_couldnt_load_data, Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        super.onBackPressed();
        return true;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.item_details, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        switch (id) {
            case R.id.action_details_view_on_web:
                Intent intent = new Intent(this, Browser.class);
                intent.putExtra(Browser.ARG_ACTION, Browser.ACTION_ITEM_DETAILS);

                if (mItem.getType().equals(BaseItem.ItemType.RADICAL)) {
                    intent.putExtra(Browser.ARG_ITEM_TYPE, BaseItem.ItemType.RADICAL);
                    intent.putExtra(Browser.ARG_ITEM, mMeaning.getText().toString());
                }
                if (mItem.getType().equals(BaseItem.ItemType.KANJI)) {
                    intent.putExtra(Browser.ARG_ITEM_TYPE, BaseItem.ItemType.KANJI);
                    intent.putExtra(Browser.ARG_ITEM, mTitle.getText().toString());
                }
                if (mItem.getType().equals(BaseItem.ItemType.VOCABULARY)) {
                    intent.putExtra(Browser.ARG_ITEM_TYPE, BaseItem.ItemType.VOCABULARY);
                    intent.putExtra(Browser.ARG_ITEM, mTitle.getText().toString());
                }

                startActivity(intent);
        }
        return super.onOptionsItemSelected(item);
    }

    // TODO: ...
    private void setUpScrollView() {
        mScrollView = (ObservableScrollView) findViewById(R.id.details_scrollview);
        mScrollView.setCallbacks(new ObservableScrollView.Callbacks() {
            @Override
            public void onScrollChanged(int x, int y, int oldx, int oldy) {
                if (y <= 0) {
                    mToolbar.setAlpha(1f);
                } else if (y <= mToolbarHeight) {
                    mToolbar.setAlpha(1 - (1 * (y / (float) mToolbarHeight)));
                } else {
                    mToolbar.setAlpha(0f);
                }
            }
        });
    }

    private void setUpActionBar() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

        ActionBar mActionBar = getSupportActionBar();
        mActionBar.setDisplayHomeAsUpEnabled(true);
        mActionBar.setDisplayShowTitleEnabled(false);

        mToolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mToolbarHeight = mToolbar.getHeight();
            }
        });
    }

    private void switchToRadicalMode() {
        mAlternativeMeaningsHolder.setVisibility(View.GONE);
        mReadingsCard.setVisibility(View.GONE);
        mReadingNoteCard.setVisibility(View.GONE);
        mReadingCorrectHolder.setVisibility(View.GONE);
        mReadingIncorrectHolder.setVisibility(View.GONE);
        mReadingMaxStreakHolder.setVisibility(View.GONE);
        mReadingCurrentStreakHolder.setVisibility(View.GONE);
    }

    private void switchToKanjiMode() {
        mReadingHolder.setVisibility(View.GONE);
    }

    private void switchToVocabularyMode() {
        mOnyomiHolder.setVisibility(View.GONE);
        mKunyomiHolder.setVisibility(View.GONE);
    }

    private void loadData() {
        /** Title */
        if (mItem.getImage() != null) {
            mTitleImage.setVisibility(View.VISIBLE);
            Picasso.with(getApplicationContext()).load(mItem.getImage()).into(mTitleImage);
            mTitleImage.setColorFilter(getResources().getColor(android.R.color.white),
                    PorterDuff.Mode.SRC_ATOP);
            mTitle.setVisibility(View.GONE);
        } else {
            mTitleImage.setVisibility(View.GONE);
            mTitle.setText(mItem.getCharacter());
            mTitle.setTypeface(new Fonts().getKanjiFont(this));
            mTitle.setVisibility(View.VISIBLE);
        }

        /** Reading (Kana) */
        if (mItem.getType().equals(BaseItem.ItemType.VOCABULARY))
            mReading.setText(mItem.getKana());

        /** Meaning */
        String[] meanings = mItem.getMeaning().split(", ");
        mMeaning.setText(WordUtils.capitalize(meanings[0]));

        if (meanings.length > 1) {
            mAlternativeMeanings.setText("");
            for (int i = 0; i < meanings.length; i++) {
                if (i != 0) {
                    if (i == 1)
                        mAlternativeMeanings.setText(WordUtils.capitalize(meanings[i]));
                    else
                        mAlternativeMeanings.setText(mAlternativeMeanings.getText().toString()
                                + ", " + WordUtils.capitalize(meanings[i]));
                }
            }
        } else
            mAlternativeMeaningsHolder.setVisibility(View.GONE);

        /** Kanji readings */
        if (mItem.getType().equals(BaseItem.ItemType.KANJI)) {
            if (mItem.getOnyomi() != null)
                mOnyomi.setText(mItem.getOnyomi());
            else
                mOnyomiHolder.setVisibility(View.GONE);

            if (mItem.getKunyomi() != null)
                mKunyomi.setText(mItem.getKunyomi());
            else
                mKunyomiHolder.setVisibility(View.GONE);

            if (mItem.getImportantReading().equals("onyomi"))
                mKunyomi.setTextColor(getResources().getColor(R.color.text_gray_light));
            else
                mOnyomi.setTextColor(getResources().getColor(R.color.text_gray_light));
        }

        /** Level */
        mLevel.setText(mItem.getLevel() + "");

        /** User specific info */
        if (mItem.isUnlocked())
            showUserSpecific();
        else
            hideUserSpecific();

        mFlipper.setDisplayedChild(FLIPPER_CONTENT);
    }

    private void showUserSpecific() {
        /** Check whether burned and display content accordingly */
        if (mItem.isBurned()) {
            mBurned.setVisibility(View.VISIBLE);
            SimpleDateFormat sdf = new SimpleDateFormat("MMMM d, yyyy");
            mBurnedDate.setText(sdf.format(mItem.getBurnedDate()));
        }

        /** SRS Level */
        if (mItem.getSrsLevel().equals("apprentice")) {
            mSRSLogo.setImageResource(R.drawable.apprentice);
            mSRSLevel.setText(R.string.srs_title_apprentice);
        }
        if (mItem.getSrsLevel().equals("guru")) {
            mSRSLogo.setImageResource(R.drawable.guru);
            mSRSLevel.setText(R.string.srs_title_guru);
        }
        if (mItem.getSrsLevel().equals("master")) {
            mSRSLogo.setImageResource(R.drawable.master);
            mSRSLevel.setText(R.string.srs_title_master);
        }
        if (mItem.getSrsLevel().equals("enlighten")) {
            mSRSLogo.setImageResource(R.drawable.enlighten);
            mSRSLevel.setText(R.string.srs_title_enlightened);
        }
        if (mItem.getSrsLevel().equals("burned")) {
            mSRSLogo.setImageResource(R.drawable.burned);
            mSRSLevel.setText(R.string.srs_title_burned);
        }

        /** Unlock date */
        SimpleDateFormat unlockDateFormat = new SimpleDateFormat("MMMM d, yyyy");
        mUnlocked.setText(unlockDateFormat.format(mItem.getUnlockDate()) + "");

        /** Next available */
        SimpleDateFormat availableDateFormat = new SimpleDateFormat("dd MMMM HH:mm");

        if (PrefManager.isUseSpecificDates()) {
            mNextAvailable.setText(availableDateFormat.format(mItem.getAvailableDate()) + "");
        } else {
            mNextAvailable.setReferenceTime(mItem.getAvailableDate());
        }
        mNextAvailableHolder.setVisibility(mItem.isBurned() ? View.GONE : View.VISIBLE);

        /** Meaning */
        mMeaningCorrectPercentage.setText(mItem.getMeaningCorrectPercentage() + "");
        mMeaningIncorrectPercentage.setText(mItem.getMeaningIncorrectPercentage() + "");

        mMeaningCorrectProgressBar.setProgress(mItem.getMeaningCorrectPercentage());
        mMeaningIncorrectProgressBar.setProgress(mItem.getMeaningIncorrectPercentage());

        mMeaningMaxStreak.setText(mItem.getMeaningMaxStreak() + "");
        mMeaningCurrentStreak.setText(mItem.getMeaningCurrentStreak() + "");

        /** Reading (For Kanji and Vocabulary) */
        if (mItem.getType().equals(BaseItem.ItemType.KANJI) || mItem.getType().equals(BaseItem.ItemType.VOCABULARY)) {
            mReadingCorrectPercentage.setText(mItem.getReadingCorrectPercentage() + "");
            mReadingIncorrectPercentage.setText(mItem.getReadingIncorrectPercentage() + "");

            mReadingMaxStreak.setText(mItem.getReadingMaxStreak() + "");
            mReadingCurrentStreak.setText(mItem.getReadingCurrentStreak() + "");

            mReadingCorrectProgressBar.setProgress(mItem.getReadingCorrectPercentage());
            mReadingIncorrectProgressBar.setProgress(mItem.getReadingIncorrectPercentage());
        }

        /** User synonyms */
        if (mItem.getUserSynonyms() != null) {
            String synonyms = WordUtils.capitalize(
                    Arrays.toString(mItem.getUserSynonyms()).replace("[", "").replace("]", ""));
            mUserSynonyms.setText(synonyms);
        } else {
            if (mAlternativeMeaningsHolder.getVisibility() == View.GONE)
                mAlternativeMeaningsAndUserSynonymsCard.setVisibility(View.GONE);
            else
                mUserSynonymsHolder.setVisibility(View.GONE);
        }

        /** Reading note */
        if (mItem.getReadingNote() != null)
            mReadingNote.setText(mItem.getReadingNote());
        else
            mReadingNoteCard.setVisibility(View.GONE);

        /** Meaning note */
        if (mItem.getMeaningNote() != null)
            mMeaningNote.setText(mItem.getMeaningNote());
        else
            mMeaningNoteCard.setVisibility(View.GONE);
    }

    private void hideUserSpecific() {
        if (mAlternativeMeaningsHolder.getVisibility() == View.GONE)
            mAlternativeMeaningsAndUserSynonymsCard.setVisibility(View.GONE);
        else
            mUserSynonymsHolder.setVisibility(View.GONE);

        mMeaningNoteCard.setVisibility(View.GONE);
        mReadingNoteCard.setVisibility(View.GONE);
        mProgressContent.setVisibility(View.GONE);
        mLocked.setVisibility(View.VISIBLE);
    }

    private void load(String type, final int level, final String character, final String image) {
        if (mFlipper != null) {
            mFlipper.setDisplayedChild(FLIPPER_PROGRESS_BAR);
        }

        /** In case of a radical item */
        if (type.equals(BaseItem.TYPE_RADICAL)) {
            WaniKaniApi.getRadicalsList(level + "").enqueue(new ThroughDbCallback<Request<RadicalsList>, RadicalsList>() {
                @Override
                public void onResponse(Call<Request<RadicalsList>> call, Response<Request<RadicalsList>> response) {
                    super.onResponse(call, response);
                    if (response.isSuccessful() && response.body().requested_information != null) {
                        load(response.body().requested_information);
                    } else {
                        onFailure(call, null);
                    }
                }

                @Override
                public void onFailure(Call<Request<RadicalsList>> call, Throwable t) {
                    super.onFailure(call, t);

                    RadicalsList list = new RadicalsList();
                    list.addAll(DatabaseManager.getItems(BaseItem.ItemType.RADICAL, new int[]{level}));

                    if (list.size() != 0) {
                        load(list);
                    } else {
                        showErrorAndExit();
                    }
                }

                void load(ItemsList list) {
                    if (character != null) {
                        for (BaseItem item : list) {
                            if (item.getCharacter() != null) {
                                if (item.getCharacter().equals(character)) {
                                    mItem = item;
                                    loadData();
                                    break;
                                }
                            }
                        }
                    } else {
                        for (BaseItem item : list) {
                            if (item.getImage() != null) {
                                if (item.getImage().equals(image)) {
                                    mItem = item;
                                    loadData();
                                    break;
                                }
                            }
                        }
                    }
                }
            });
        }

        /** In case of a Kanji item */
        if (type.equals(BaseItem.TYPE_KANJI)) {
            WaniKaniApi.getKanjiList(level + "").enqueue(new ThroughDbCallback<Request<KanjiList>, KanjiList>() {
                @Override
                public void onResponse(Call<Request<KanjiList>> call, Response<Request<KanjiList>> response) {
                    super.onResponse(call, response);
                    if (response.isSuccessful() && response.body().requested_information != null) {
                        load(response.body().requested_information);
                    } else {
                        onFailure(call, null);
                    }
                }

                @Override
                public void onFailure(Call<Request<KanjiList>> call, Throwable t) {
                    super.onFailure(call, t);

                    KanjiList list = new KanjiList();
                    list.addAll(DatabaseManager.getItems(BaseItem.ItemType.KANJI, new int[]{level}));

                    if (list.size() != 0) {
                        load(list);
                    } else {
                        showErrorAndExit();
                    }
                }

                void load(ItemsList list) {
                    for (BaseItem item : list) {
                        if (item.getCharacter().equals(character)) {
                            mItem = item;
                            loadData();
                            break;
                        }
                    }
                }
            });
        }

        /** In case of a vocabulary item */
        WaniKaniApi.getVocabularyList(level + "").enqueue(new ThroughDbCallback<Request<VocabularyList>, VocabularyList>() {
            @Override
            public void onResponse(Call<Request<VocabularyList>> call, Response<Request<VocabularyList>> response) {
                super.onResponse(call, response);
                if (response.isSuccessful() && response.body().requested_information != null) {
                    load(response.body().requested_information);
                } else {
                    onFailure(call, null);
                }
            }

            @Override
            public void onFailure(Call<Request<VocabularyList>> call, Throwable t) {
                super.onFailure(call, t);

                VocabularyList list = new VocabularyList();
                list.addAll(DatabaseManager.getItems(BaseItem.ItemType.VOCABULARY, new int[]{level}));

                if (list.size() != 0) {
                    load(list);
                } else {
                    showErrorAndExit();
                }
            }

            void load(ItemsList list) {
                for (BaseItem item : list) {
                    if (item.getCharacter().equals(character)) {
                        mItem = item;
                        loadData();
                        break;
                    }
                }
            }
        });
    }

    private void showErrorAndExit() {
        Log.e(TAG, "Failed to fetch item info; exiting...");
        Toast.makeText(getApplicationContext(), R.string.error_couldnt_load_data, Toast.LENGTH_SHORT).show();
        finish();
    }
}