package io.lbry.browser.ui.findcontent;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateUtils;
import android.text.method.LinkMovementMethod;
import android.util.Base64;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.core.widget.NestedScrollView;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewFeature;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.github.chrisbanes.photoview.PhotoView;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.Util;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputEditText;

import org.commonmark.node.Code;
import org.commonmark.node.Node;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.html.AttributeProvider;
import org.commonmark.renderer.html.AttributeProviderContext;
import org.commonmark.renderer.html.AttributeProviderFactory;
import org.commonmark.renderer.html.HtmlRenderer;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import io.lbry.browser.MainActivity;
import io.lbry.browser.R;
import io.lbry.browser.adapter.ClaimListAdapter;
import io.lbry.browser.adapter.CommentListAdapter;
import io.lbry.browser.adapter.InlineChannelSpinnerAdapter;
import io.lbry.browser.adapter.TagListAdapter;
import io.lbry.browser.dialog.RepostClaimDialogFragment;
import io.lbry.browser.dialog.CreateSupportDialogFragment;
import io.lbry.browser.exceptions.LbryUriException;
import io.lbry.browser.listener.DownloadActionListener;
import io.lbry.browser.listener.FetchClaimsListener;
import io.lbry.browser.listener.PIPModeListener;
import io.lbry.browser.listener.ScreenOrientationListener;
import io.lbry.browser.listener.SdkStatusListener;
import io.lbry.browser.listener.StoragePermissionListener;
import io.lbry.browser.listener.WalletBalanceListener;
import io.lbry.browser.model.Claim;
import io.lbry.browser.model.ClaimCacheKey;
import io.lbry.browser.model.Comment;
import io.lbry.browser.model.Fee;
import io.lbry.browser.model.LbryFile;
import io.lbry.browser.model.NavMenuItem;
import io.lbry.browser.model.Tag;
import io.lbry.browser.model.UrlSuggestion;
import io.lbry.browser.model.WalletBalance;
import io.lbry.browser.model.lbryinc.Reward;
import io.lbry.browser.model.lbryinc.Subscription;
import io.lbry.browser.tasks.BufferEventTask;
import io.lbry.browser.tasks.CommentCreateTask;
import io.lbry.browser.tasks.CommentListHandler;
import io.lbry.browser.tasks.CommentListTask;
import io.lbry.browser.tasks.GenericTaskHandler;
import io.lbry.browser.tasks.LighthouseSearchTask;
import io.lbry.browser.tasks.ReadTextFileTask;
import io.lbry.browser.tasks.SetSdkSettingTask;
import io.lbry.browser.tasks.claim.AbandonHandler;
import io.lbry.browser.tasks.claim.AbandonStreamTask;
import io.lbry.browser.tasks.claim.ClaimListResultHandler;
import io.lbry.browser.tasks.claim.ClaimListTask;
import io.lbry.browser.tasks.claim.ClaimSearchResultHandler;
import io.lbry.browser.tasks.claim.PurchaseListTask;
import io.lbry.browser.tasks.claim.ResolveTask;
import io.lbry.browser.tasks.file.DeleteFileTask;
import io.lbry.browser.tasks.file.FileListTask;
import io.lbry.browser.tasks.file.GetFileTask;
import io.lbry.browser.tasks.lbryinc.ChannelSubscribeTask;
import io.lbry.browser.tasks.lbryinc.ClaimRewardTask;
import io.lbry.browser.tasks.lbryinc.FetchStatCountTask;
import io.lbry.browser.tasks.lbryinc.LogFileViewTask;
import io.lbry.browser.ui.BaseFragment;
import io.lbry.browser.ui.controls.SolidIconView;
import io.lbry.browser.ui.publish.PublishFragment;
import io.lbry.browser.utils.Helper;
import io.lbry.browser.utils.Lbry;
import io.lbry.browser.utils.LbryAnalytics;
import io.lbry.browser.utils.LbryUri;
import io.lbry.browser.utils.Lbryio;
import io.lbry.lbrysdk.DownloadManager;
import io.lbry.lbrysdk.LbrynetService;
import io.lbry.lbrysdk.Utils;

import static android.os.Environment.DIRECTORY_DOWNLOADS;
import static android.os.Environment.DIRECTORY_MOVIES;
import static android.os.Environment.DIRECTORY_PICTURES;

public class FileViewFragment extends BaseFragment implements
        MainActivity.BackPressInterceptor,
        DownloadActionListener,
        FetchClaimsListener,
        PIPModeListener,
        ScreenOrientationListener,
        SdkStatusListener,
        StoragePermissionListener,
        WalletBalanceListener {
    private static final int RELATED_CONTENT_SIZE = 16;
    private static final String DEFAULT_PLAYBACK_SPEED = "1x";
    public static final String CDN_PREFIX = "https://cdn.lbryplayer.xyz";

    private PlayerControlView castControlView;
    private Player currentPlayer;
    private boolean loadingNewClaim;
    private boolean startDownloadPending;
    private boolean fileGetPending;
    private boolean downloadInProgress;
    private boolean downloadRequested;
    private boolean loadFilePending;
    private boolean isPlaying;
    private boolean resolving;
    private boolean initialFileLoadDone;
    private Claim claim;
    private String currentUrl;
    private ClaimListAdapter relatedContentAdapter;
    private CommentListAdapter commentListAdapter;
    private BroadcastReceiver sdkReceiver;
    private Player.EventListener fileViewPlayerListener;

    private long elapsedDuration = 0;
    private long totalDuration = 0;
    private boolean elapsedPlaybackScheduled;
    private ScheduledExecutorService elapsedPlaybackScheduler;
    private boolean playbackStarted;
    private long startTimeMillis;
    private GetFileTask getFileTask;

    private boolean storagePermissionRefusedOnce;
    private View buttonPublishSomething;
    private View layoutLoadingState;
    private View layoutNothingAtLocation;
    private View layoutDisplayArea;
    private View layoutResolving;
    private int lastPositionSaved;

    private View tipButton;

    private WebView webView;
    private boolean webViewAdded;

    private Comment replyToComment;
    private View containerReplyToComment;
    private TextView textReplyingTo;
    private TextView textReplyToBody;
    private View buttonClearReplyToComment;
    private TextView textNothingAtLocation;

    private boolean postingComment;
    private boolean fetchingChannels;
    private View progressLoadingChannels;
    private View progressPostComment;
    private InlineChannelSpinnerAdapter commentChannelSpinnerAdapter;
    private AppCompatSpinner commentChannelSpinner;
    private TextInputEditText inputComment;
    private TextView textCommentLimit;
    private MaterialButton buttonPostComment;
    private ImageView commentPostAsThumbnail;
    private View commentPostAsNoThumbnail;
    private TextView commentPostAsAlpha;

    private View inlineChannelCreator;
    private TextInputEditText inlineChannelCreatorInputName;
    private TextInputEditText inlineChannelCreatorInputDeposit;
    private View inlineChannelCreatorInlineBalance;
    private TextView inlineChannelCreatorInlineBalanceValue;
    private View inlineChannelCreatorCancelLink;
    private View inlineChannelCreatorProgress;
    private MaterialButton inlineChannelCreatorCreateButton;

    // if this is set, scroll to the specific comment on load
    private String commentHash;

    private float floatingWalletPositionY;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_file_view, container, false);

        layoutLoadingState = root.findViewById(R.id.file_view_loading_state);
        layoutNothingAtLocation = root.findViewById(R.id.container_nothing_at_location);
        layoutResolving = root.findViewById(R.id.file_view_loading_container);
        layoutDisplayArea = root.findViewById(R.id.file_view_claim_display_area);
        buttonPublishSomething = root.findViewById(R.id.nothing_at_location_publish_button);

        tipButton = root.findViewById(R.id.file_view_action_tip);

        containerReplyToComment = root.findViewById(R.id.comment_form_reply_to_container);
        textReplyingTo = root.findViewById(R.id.comment_form_replying_to_text);
        textReplyToBody = root.findViewById(R.id.comment_form_reply_to_body);
        buttonClearReplyToComment = root.findViewById(R.id.comment_form_clear_reply_to);

        commentChannelSpinner = root.findViewById(R.id.comment_form_channel_spinner);
        progressLoadingChannels = root.findViewById(R.id.comment_form_channels_loading);
        progressPostComment = root.findViewById(R.id.comment_form_post_progress);
        inputComment = root.findViewById(R.id.comment_form_body);
        textCommentLimit = root.findViewById(R.id.comment_form_text_limit);
        buttonPostComment = root.findViewById(R.id.comment_form_post);
        commentPostAsThumbnail = root.findViewById(R.id.comment_form_thumbnail);
        commentPostAsNoThumbnail = root.findViewById(R.id.comment_form_no_thumbnail);
        commentPostAsAlpha = root.findViewById(R.id.comment_form_thumbnail_alpha);
        textNothingAtLocation = root.findViewById(R.id.nothing_at_location_text);

        inlineChannelCreator = root.findViewById(R.id.container_inline_channel_form_create);
        inlineChannelCreatorInputName = root.findViewById(R.id.inline_channel_form_input_name);
        inlineChannelCreatorInputDeposit = root.findViewById(R.id.inline_channel_form_input_deposit);
        inlineChannelCreatorInlineBalance = root.findViewById(R.id.inline_channel_form_inline_balance_container);
        inlineChannelCreatorInlineBalanceValue = root.findViewById(R.id.inline_channel_form_inline_balance_value);
        inlineChannelCreatorProgress = root.findViewById(R.id.inline_channel_form_create_progress);
        inlineChannelCreatorCancelLink = root.findViewById(R.id.inline_channel_form_cancel_link);
        inlineChannelCreatorCreateButton = root.findViewById(R.id.inline_channel_form_create_button);

        initUi(root);

        fileViewPlayerListener = new Player.EventListener() {
            @Override
            public void onPlaybackStateChanged(@Player.State int playbackState) {
                if (playbackState == Player.STATE_READY) {
                    elapsedDuration = MainActivity.appPlayer.getCurrentPosition();
                    totalDuration = MainActivity.appPlayer.getDuration() < 0 ? 0 : MainActivity.appPlayer.getDuration();
                    if (!playbackStarted) {
                        logPlay(currentUrl, startTimeMillis);
                        playbackStarted = true;

                        long lastPosition = loadLastPlaybackPosition();
                        if (lastPosition > -1) {
                            MainActivity.appPlayer.seekTo(lastPosition);
                        }
                    }
                    renderTotalDuration();
                    scheduleElapsedPlayback();
                    hideBuffering();

                    if (loadingNewClaim) {
                        Context context = getContext();
                        if (context instanceof MainActivity) {
                            MainActivity.appPlayer.setPlayWhenReady(((MainActivity) context).isMediaAutoplayEnabled());
                        }
                        loadingNewClaim = false;
                    }
                } else if (playbackState == Player.STATE_BUFFERING) {
                    Context ctx = getContext();
                    boolean sendBufferingEvents = true;

                    if (ctx != null) {
                        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(ctx);
                        sendBufferingEvents = sp.getBoolean(MainActivity.PREFERENCE_KEY_SEND_BUFFERING_EVENTS, true);
                    }

                    if (MainActivity.appPlayer != null && MainActivity.appPlayer.getCurrentPosition() > 0 && sendBufferingEvents) {
                        // we only want to log a buffer event after the media has already started playing
                        String mediaSourceUrl = getStreamingUrl();
                        long duration = MainActivity.appPlayer.getDuration();
                        long position = MainActivity.appPlayer.getCurrentPosition();
                        String userIdHash = Lbryio.currentUser != null ? String.valueOf(Lbryio.currentUser.getId()) : "0";
                        if (mediaSourceUrl.startsWith(CDN_PREFIX)) {
                            BufferEventTask bufferEvent = new BufferEventTask(claim.getPermanentUrl(), duration, position, 1, userIdHash);
                            bufferEvent.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
                        } else {
                            // sdk stream buffer events should be handled differently
                            Bundle bundle = new Bundle();
                            bundle.putString("url", claim.getPermanentUrl());
                            bundle.putLong("stream_duration", duration);
                            bundle.putLong("stream_position", position);
                            bundle.putString("user_id_hash", userIdHash);
                            LbryAnalytics.logEvent(LbryAnalytics.EVENT_BUFFER, bundle);
                        }
                    }

                    showBuffering();
                } else {
                    hideBuffering();
                }
            }

            @Override
            public void onIsPlayingChanged(boolean isPlayng) {
                isPlaying = isPlayng;
            }
        };

        return root;
    }

    public void onStart() {
        super.onStart();
        Context context = getContext();

        if (context instanceof MainActivity) {
            MainActivity activity = (MainActivity) context;
            activity.setBackPressInterceptor(this);
            activity.addDownloadActionListener(this);
            activity.addFetchClaimsListener(this);
            activity.addPIPModeListener(this);
            activity.addScreenOrientationListener(this);
            activity.addWalletBalanceListener(this);
            if (!MainActivity.hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, context)) {
                activity.addStoragePermissionListener(this);
            }
        }
    }

    private void checkParams() {
        boolean updateRequired = false;
        Context context = getContext();
        Map<String, Object> params = getParams();
        Claim newClaim = null;
        String newUrl = null;
        if (params != null) {
            if (params.containsKey("claim")) {
                newClaim = (Claim) params.get("claim");
                if (newClaim != null && !newClaim.equals(this.claim)) {
                    updateRequired = true;
                }
            }
            if (params.containsKey("url")) {
                LbryUri newLbryUri = LbryUri.tryParse(params.get("url").toString());
                if (newLbryUri != null) {
                    newUrl = newLbryUri.toString();
                    String qs = newLbryUri.getQueryString();
                    if (!Helper.isNullOrEmpty(qs)) {
                        String[] qsPairs = qs.split("&");
                        for (String pair : qsPairs) {
                            String[] parts = pair.split("=");
                            if (parts.length < 2) {
                                continue;
                            }
                            if ("comment_hash".equalsIgnoreCase(parts[0])) {
                                commentHash = parts[1];
                                break;
                            }
                        }
                    }

                    if (claim == null || !newUrl.equalsIgnoreCase(currentUrl)) {
                        updateRequired = true;
                    }
                }
            }
        } else if (currentUrl != null) {
            updateRequired = true;
        } else if (context instanceof MainActivity) {
            ((MainActivity) context).onBackPressed();
        }

        boolean invalidRepost = false;
        if (updateRequired) {
            if (context instanceof MainActivity) {
                ((MainActivity) context).clearNowPlayingClaim();
            }
            if (MainActivity.appPlayer != null) {
                MainActivity.appPlayer.setPlayWhenReady(false);
            }

            resetViewCount();
            resetFee();
            checkNewClaimAndUrl(newClaim, newUrl);

            if (newClaim != null) {
                claim = newClaim;
            }
            if (!Helper.isNullOrEmpty(newUrl)) {
                // check if the claim is already cached
                currentUrl = newUrl;
                ClaimCacheKey key = new ClaimCacheKey();
                key.setUrl(currentUrl);
                onNewClaim(currentUrl);
                if (Lbry.claimCache.containsKey(key)) {
                    claim = Lbry.claimCache.get(key);
                    if (Claim.TYPE_REPOST.equalsIgnoreCase(claim.getValueType())) {
                        claim = claim.getRepostedClaim();
                        if (claim == null || Helper.isNullOrEmpty(claim.getClaimId())) {
                            // Invalid repost, probably
                            invalidRepost = true;
                            renderNothingAtLocation();
                        } else if (claim.getName().startsWith("@")) {
                            // this is a reposted channel, so launch the channel url
                            if (context instanceof MainActivity) {
                                MainActivity activity = (MainActivity) context;
                                //activity.onBackPressed(); // remove the reposted url page from the back stack
                                activity.getSupportFragmentManager().popBackStack();
                                activity.openChannelUrl(!Helper.isNullOrEmpty(claim.getShortUrl()) ? claim.getShortUrl() : claim.getPermanentUrl());
                            }
                            return;
                        }
                    }
                } else {
                    resolveUrl(currentUrl);
                }
            } else if (claim == null) {
                // nothing at this location
                renderNothingAtLocation();
            }
        } else {
            checkAndResetNowPlayingClaim();
        }

        if (!Helper.isNullOrEmpty(currentUrl)) {
            Helper.saveUrlHistory(currentUrl, claim != null ? claim.getTitle() : null, UrlSuggestion.TYPE_FILE);
        }

        if (claim != null && !invalidRepost) {
            Helper.saveViewHistory(currentUrl, claim);
            if (Helper.isClaimBlocked(claim)) {
                renderClaimBlocked();
            } else {
                checkAndLoadRelatedContent();
                checkAndLoadComments();
                renderClaim();
                if (claim.getFile() == null) {
                    loadFile();
                } else {
                    initialFileLoadDone = true;
                }
            }
        }

        checkIsFileComplete();
    }

    private void renderNothingAtLocation() {
        Helper.setViewVisibility(layoutLoadingState, View.VISIBLE);
        Helper.setViewVisibility(layoutNothingAtLocation, View.VISIBLE);
        Helper.setViewVisibility(buttonPublishSomething, View.VISIBLE);
        Helper.setViewVisibility(layoutResolving, View.GONE);
        Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE);
        if (textNothingAtLocation != null) {
            textNothingAtLocation.setText(R.string.nothing_at_this_location);
        }
    }

    private void renderClaimBlocked() {
        Helper.setViewVisibility(layoutLoadingState, View.VISIBLE);
        Helper.setViewVisibility(layoutNothingAtLocation, View.VISIBLE);
        Helper.setViewVisibility(buttonPublishSomething, View.INVISIBLE);
        Helper.setViewVisibility(layoutResolving, View.GONE);
        Helper.setViewVisibility(layoutDisplayArea, View.INVISIBLE);
        if (textNothingAtLocation != null) {
            textNothingAtLocation.setMovementMethod(LinkMovementMethod.getInstance());
            textNothingAtLocation.setText(HtmlCompat.fromHtml(getString(R.string.dmca_complaint_blocked), HtmlCompat.FROM_HTML_MODE_LEGACY));
        }
    }

    private void checkNewClaimAndUrl(Claim newClaim, String newUrl) {
        boolean shouldResetNowPlaying = false;
        if (newClaim != null &&
                MainActivity.nowPlayingClaim != null &&
                !MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(newClaim.getClaimId())) {
            shouldResetNowPlaying = true;
        }
        if (!shouldResetNowPlaying &&
                newUrl != null &&
                MainActivity.nowPlayingClaim != null &&
                !newUrl.equalsIgnoreCase(MainActivity.nowPlayingClaim.getShortUrl()) &&
                !newUrl.equalsIgnoreCase(MainActivity.nowPlayingClaim.getPermanentUrl())) {
            shouldResetNowPlaying = true;
        }

        if (shouldResetNowPlaying) {
            if (MainActivity.appPlayer != null) {
                MainActivity.appPlayer.setPlayWhenReady(false);
            }
            Context context = getContext();
            if (context instanceof MainActivity) {
                ((MainActivity) context).clearNowPlayingClaim();
                resetPlayer();
            }
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            currentUrl = savedInstanceState.getString("url");
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        if (savedInstanceState != null) {
            savedInstanceState.putString("url", currentUrl);
        }
    }

    private void initWebView(View root) {
        Context ctx = getContext();
        if (ctx != null) {
            if (webView == null) {
                webView = new WebView(ctx);
                webView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
                webView.setWebViewClient(new LbryWebViewClient(ctx));
                WebSettings webSettings = webView.getSettings();
                webSettings.setAllowFileAccess(true);
                webSettings.setJavaScriptEnabled(false);
            }

            if (!webViewAdded && root != null) {
                ((RelativeLayout) root.findViewById(R.id.file_view_webview_container)).addView(webView);
                webViewAdded = true;
            }
        }
    }

    private void applyThemeToWebView() {
        Context context = getContext();
        if (context instanceof MainActivity && webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
            MainActivity activity = (MainActivity) context;
            WebSettingsCompat.setForceDark(webView.getSettings(), activity.isDarkMode() ? WebSettingsCompat.FORCE_DARK_ON : WebSettingsCompat.FORCE_DARK_OFF);
        }
    }

    private void logUrlEvent(String url) {
        Bundle bundle = new Bundle();
        bundle.putString("uri", url);
        LbryAnalytics.logEvent(LbryAnalytics.EVENT_OPEN_FILE_PAGE, bundle);
    }

    private void checkAndResetNowPlayingClaim() {
        if (MainActivity.nowPlayingClaim != null
                && claim != null &&
                !MainActivity.nowPlayingClaim.getClaimId().equalsIgnoreCase(claim.getClaimId())) {
            Context context = getContext();
            if (context instanceof MainActivity) {
                MainActivity activity = (MainActivity) context;
                activity.clearNowPlayingClaim();
                if (claim != null && !claim.isPlayable()) {
                    activity.stopExoplayer();
                }
            }
        }
    }

    private void onNewClaim(String url) {
        loadingNewClaim = true;
        initialFileLoadDone = false;
        playbackStarted = false;
        currentUrl = url;
        logUrlEvent(url);
        resetViewCount();
        resetFee();

        View root = getView();
        if (root != null) {
            if (relatedContentAdapter != null) {
                relatedContentAdapter.clearItems();
            }
            if (commentListAdapter != null) {
                commentListAdapter.clearItems();
            }
            ((RecyclerView) root.findViewById(R.id.file_view_related_content_list)).setAdapter(null);
            ((RecyclerView) root.findViewById(R.id.file_view_comments_list)).setAdapter(null);
        }
        if (MainActivity.appPlayer != null) {
            MainActivity.appPlayer.setPlayWhenReady(false);
        }
        resetPlayer();
    }

    public void onSdkReady() {
        if (loadFilePending) {
            loadFile();
        }
        checkOwnClaim();
        fetchChannels();
    }

    private String getStreamingUrl() {
        LbryFile lbryFile = claim.getFile();
        if (lbryFile != null) {
            if (!Helper.isNullOrEmpty(lbryFile.getDownloadPath()) && lbryFile.isCompleted()) {
                File file = new File(lbryFile.getDownloadPath());
                if (file.exists()) {
                    return Uri.fromFile(file).toString();
                }
            }

            if (!Helper.isNullOrEmpty(lbryFile.getStreamingUrl()) && (!claim.isFree() || !Lbryio.isSignedIn())) {
                return lbryFile.getStreamingUrl();
            }
        }

        return buildLbryTvStreamingUrl();
    }

    private String buildLbryTvStreamingUrl() {
        return String.format("https://cdn.lbryplayer.xyz/content/claims/%s/%s/stream", claim.getName(), claim.getClaimId());
    }

    private void loadFile() {
        if (!Lbry.SDK_READY) {
            // make use of the lbry.tv streaming URL
            loadFilePending = true;
            return;
        }

        loadFilePending = false;
        String claimId = claim.getClaimId();
        FileListTask task = new FileListTask(claimId, null, new FileListTask.FileListResultHandler() {
            @Override
            public void onSuccess(List<LbryFile> files, boolean hasReachedEnd) {
                if (files.size() > 0) {
                    claim.setFile(files.get(0));
                    checkIsFileComplete();
                    if (!claim.isPlayable() && !claim.isViewable()) {
                        showUnsupportedView();
                    }
                } else {
                    if (!claim.isPlayable() && !claim.isViewable()) {
                        restoreMainActionButton();
                    }
                }

                initialFileLoadDone = true;
            }

            @Override
            public void onError(Exception error) {
                initialFileLoadDone = true;
            }
        });
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public void openClaimUrl(String url) {
        resetViewCount();
        resetFee();
        currentUrl = url;

        ClaimCacheKey key = new ClaimCacheKey();
        key.setUrl(currentUrl);
        Claim oldClaim = claim;
        claim = null;
        if (Lbry.claimCache.containsKey(key)) {
            claim = Lbry.claimCache.get(key);
            if (oldClaim != null && oldClaim.getClaimId().equalsIgnoreCase(claim.getClaimId())) {
                // same claim
                return;
            }
        } else {
            resolveUrl(currentUrl);
        }

        resetMedia();
        onNewClaim(currentUrl);
        Helper.setWunderbarValue(currentUrl, getContext());

        if (claim != null) {
            Helper.saveViewHistory(url, claim);
            if (Helper.isClaimBlocked(claim)) {
                renderClaimBlocked();
            } else {
                checkAndLoadRelatedContent();
                checkAndLoadComments();
                renderClaim();
            }
        }
    }

    public void resetMedia() {
        View root = getView();
        if (root != null) {
            PlayerView view = root.findViewById(R.id.file_view_exoplayer_view);
            view.setShutterBackgroundColor(Color.BLACK);
            root.findViewById(R.id.file_view_exoplayer_container).setVisibility(View.GONE);
        }
        if (MainActivity.appPlayer != null) {
            MainActivity.appPlayer.stop();
        }
        resetPlayer();
    }

    public void onResume() {
        super.onResume();
        checkParams();

        Context context = getContext();
        Helper.setWunderbarValue(currentUrl, context);
        if (context instanceof MainActivity) {
            MainActivity activity = (MainActivity) context;
            LbryAnalytics.setCurrentScreen(activity, "File", "File");
            if (claim != null && claim.isPlayable() && activity.isInFullscreenMode()) {
                enableFullScreenMode();
            }
        }

        if (MainActivity.appPlayer != null) {
            if (MainActivity.playerReassigned) {
                setPlayerForPlayerView();
                MainActivity.playerReassigned = false;
            }

            View root = getView();
            if (root != null) {
                PlayerView playerView = root.findViewById(R.id.file_view_exoplayer_view);
                if (playerView.getPlayer() == null) {
