package app.fedilab.android.drawers;
/* Copyright 2019 Thomas Schneider
 *
 * This file is a part of Fedilab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Fedilab; if not,
 * see <http://www.gnu.org/licenses>. */

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityOptionsCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;

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

import app.fedilab.android.R;
import app.fedilab.android.activities.ShowAccountActivity;
import app.fedilab.android.activities.ShowConversationActivity;
import app.fedilab.android.activities.SlideMediaActivity;
import app.fedilab.android.asynctasks.RetrieveFeedsAsyncTask;
import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.Attachment;
import app.fedilab.android.client.Entities.Emojis;
import app.fedilab.android.client.Entities.Error;
import app.fedilab.android.client.Entities.Notification;
import app.fedilab.android.client.Entities.Status;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnPostActionInterface;
import app.fedilab.android.interfaces.OnRetrieveEmojiInterface;
import app.fedilab.android.interfaces.OnRetrieveRepliesInterface;
import app.fedilab.android.sqlite.Sqlite;
import app.fedilab.android.sqlite.StatusCacheDAO;
import es.dmoral.toasty.Toasty;

import static android.content.Context.MODE_PRIVATE;
import static app.fedilab.android.helper.Helper.makeEmojis;


/**
 * Created by Thomas on 14/01/2019.
 * Adapter for art drawer
 */
public class ArtListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface, OnRetrieveEmojiInterface, OnRetrieveRepliesInterface {

    private static final int DISPLAYED_STATUS = 1;
    private final int HIDDEN_STATUS = 0;
    private Context context;
    private List<Status> statuses;
    private ArtListAdapter statusListAdapter;


    public ArtListAdapter(List<Status> statuses) {

        this.statuses = statuses;
        statusListAdapter = this;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return statuses.size();
    }

    private Status getItemAt(int position) {
        if (statuses.size() > position)
            return statuses.get(position);
        else
            return null;
    }

    @Override
    public void onRetrieveReplies(APIResponse apiResponse) {
        if (apiResponse.getError() != null || apiResponse.getStatuses() == null || apiResponse.getStatuses().size() == 0) {
            return;
        }
        List<Status> modifiedStatus = apiResponse.getStatuses();
        notifyStatusChanged(modifiedStatus.get(0));
    }


    public Status getItem(int position) {
        if (statuses.size() > position && position >= 0)
            return statuses.get(position);
        else return null;
    }

    @Override
    public int getItemViewType(int position) {
        boolean show_account_boosts = false;
        boolean show_account_replies = false;
        if (context instanceof ShowAccountActivity) {
            SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
            show_account_boosts = sharedpreferences.getBoolean(Helper.SHOW_ACCOUNT_BOOSTS, true);
            show_account_replies = sharedpreferences.getBoolean(Helper.SHOW_ACCOUNT_REPLIES, true);
        }
        if (!Helper.filterToots(statuses.get(position), RetrieveFeedsAsyncTask.Type.ART, context instanceof ShowAccountActivity, show_account_boosts, show_account_replies)) {
            return HIDDEN_STATUS;
        } else {
            return DISPLAYED_STATUS;
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        this.context = parent.getContext();
        LayoutInflater layoutInflater = LayoutInflater.from(this.context);
        if (viewType != HIDDEN_STATUS)
            return new ViewHolderArt(layoutInflater.inflate(R.layout.drawer_art, parent, false));
        else
            return new ViewHolderEmpty(layoutInflater.inflate(R.layout.drawer_empty, parent, false));
    }

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {

        if (viewHolder.getItemViewType() != HIDDEN_STATUS) {
            final ViewHolderArt holder = (ViewHolderArt) viewHolder;
            final Status status = statuses.get(viewHolder.getAdapterPosition());


            if (status.getAccount() != null && status.getAccount().getAvatar() != null)
                Helper.loadGiF(context, status.getAccount(), holder.art_pp);

            if (status.getArt_attachment() != null)
                Glide.with(context)
                        .load(status.getArt_attachment().getPreview_url())
                        .into(holder.art_media);
            holder.art_pp.setOnClickListener(v -> {
                Intent intent = new Intent(context, ShowAccountActivity.class);
                Bundle b = new Bundle();
                b.putParcelable("account", status.getAccount());
                intent.putExtras(b);
                context.startActivity(intent);
            });

            holder.art_media.setOnClickListener(v -> {
                Intent intent = new Intent(context, SlideMediaActivity.class);
                Bundle b = new Bundle();
                ArrayList<Attachment> attachments = new ArrayList<>();
                if (status.getArt_attachment() != null)
                    attachments.add(status.getArt_attachment());
                else if (status.getMedia_attachments() != null && status.getMedia_attachments().size() > 0)
                    attachments.add(status.getMedia_attachments().get(0));
                intent.putParcelableArrayListExtra("mediaArray", attachments);
                b.putInt("bgcolor", context.getResources().getColor(R.color.cyanea_primary_dark));
                b.putInt("position", 1);
                intent.putExtras(b);
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    ActivityOptionsCompat options = ActivityOptionsCompat
                            .makeSceneTransitionAnimation((Activity) context, holder.art_media, status.getMedia_attachments().get(0).getUrl());
                    // start the new activity
                    context.startActivity(intent, options.toBundle());
                } else {
                    // start the new activity
                    context.startActivity(intent);
                }

            });
            holder.art_author.setOnClickListener(v -> {
                Intent intent = new Intent(context, ShowConversationActivity.class);
                Bundle b = new Bundle();
                b.putParcelable("status", status);
                intent.putExtras(b);
                context.startActivity(intent);
            });

            if (status.getAccount().getDisplayNameSpan() != null && status.getAccount().getDisplayNameSpan().toString().trim().length() > 0) {
                holder.art_username.setText(status.getAccount().getDisplayNameSpan(), TextView.BufferType.SPANNABLE);
                makeEmojis(context, holder.art_username, status.getAccount().getDisplayNameSpan(), status.getAccount().getEmojis());
            } else
                holder.art_username.setText(status.getAccount().getUsername());

            holder.art_acct.setText(String.format("@%s", status.getAccount().getAcct()));
        }

    }

    @Override
    public void onPostAction(int statusCode, API.StatusAction statusAction, String targetedId, Error error) {

        if (error != null) {
            Toasty.error(context, error.getError(), Toast.LENGTH_LONG).show();
            return;
        }
        Helper.manageMessageStatusCode(context, statusCode, statusAction);
        //When muting or blocking an account, its status are removed from the list
        List<Status> statusesToRemove = new ArrayList<>();
        if (statusAction == API.StatusAction.MUTE || statusAction == API.StatusAction.BLOCK) {
            for (Status status : statuses) {
                if (status.getAccount().getId().equals(targetedId))
                    statusesToRemove.add(status);
            }
            statuses.removeAll(statusesToRemove);
            statusListAdapter.notifyDataSetChanged();
        } else if (statusAction == API.StatusAction.UNSTATUS) {
            int position = 0;
            for (Status status : statuses) {
                if (status.getId().equals(targetedId)) {
                    statuses.remove(status);
                    statusListAdapter.notifyItemRemoved(position);
                    SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
                    //Remove the status from cache also
                    try {
                        new StatusCacheDAO(context, db).remove(StatusCacheDAO.ARCHIVE_CACHE, status);
                    } catch (Exception ignored) {
                    }
                    break;
                }
                position++;
            }
        } else if (statusAction == API.StatusAction.PIN || statusAction == API.StatusAction.UNPIN) {
            int position = 0;
            for (Status status : statuses) {
                if (status.getId().equals(targetedId)) {
                    if (statusAction == API.StatusAction.PIN)
                        status.setPinned(true);
                    else
                        status.setPinned(false);
                    statusListAdapter.notifyItemChanged(position);
                    break;
                }
                position++;
            }
        }
        if (statusAction == API.StatusAction.PEERTUBEDELETECOMMENT) {
            int position = 0;
            for (Status status : statuses) {
                if (status.getId().equals(targetedId)) {
                    statuses.remove(status);
                    statusListAdapter.notifyItemRemoved(position);
                    break;
                }
                position++;
            }
        }
    }

    private void notifyStatusChanged(Status status) {
        for (int i = 0; i < statusListAdapter.getItemCount(); i++) {
            //noinspection ConstantConditions
            if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) {
                try {
                    statusListAdapter.notifyItemChanged(i);
                } catch (Exception ignored) {
                }
            }
        }
    }

    @Override
    public void onRetrieveEmoji(Status status, boolean fromTranslation) {
        if (status != null) {
            if (!fromTranslation) {
                status.setEmojiFound(true);
            } else {
                status.setEmojiTranslateFound(true);
            }
            notifyStatusChanged(status);
        }
    }

    @Override
    public void onRetrieveEmoji(Notification notification) {

    }

    @Override
    public void onRetrieveSearchEmoji(List<Emojis> emojis) {

    }

    private static class ViewHolderEmpty extends RecyclerView.ViewHolder {
        ViewHolderEmpty(View itemView) {
            super(itemView);
        }
    }

    private static class ViewHolderArt extends RecyclerView.ViewHolder {
        ImageView art_media, art_pp;
        TextView art_username, art_acct;
        LinearLayout art_author;
        RelativeLayout status_show_more;
        ImageView show_more_button_art;

        ViewHolderArt(View itemView) {
            super(itemView);
            art_media = itemView.findViewById(R.id.art_media);
            art_pp = itemView.findViewById(R.id.art_pp);
            art_username = itemView.findViewById(R.id.art_username);
            art_acct = itemView.findViewById(R.id.art_acct);
            art_author = itemView.findViewById(R.id.art_author);
            status_show_more = itemView.findViewById(R.id.status_show_more);
            show_more_button_art = itemView.findViewById(R.id.show_more_button_art);
        }
    }

}