package me.arimelody.aridroid;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.RecyclerView;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;

public class ReleaseListAdapter extends RecyclerView.Adapter<ReleaseListAdapter.ReleaseViewHolder> {
    private final Context context;
    private final ArrayList<ReleaseModel> releases;
    private static HashMap<String, Integer> ReleaseTypes;

    public ReleaseListAdapter(@NonNull Context context) {
        this.context = context;
        releases = new ArrayList<>();

        if (ReleaseTypes == null) {
            ReleaseTypes = new HashMap<>();
            ReleaseTypes.put("single", R.string.release_type_single);
            ReleaseTypes.put("album", R.string.release_type_album);
            ReleaseTypes.put("ep", R.string.release_type_ep);
            ReleaseTypes.put("lp", R.string.release_type_lp);
            ReleaseTypes.put("compilation", R.string.release_type_compilation);
            ReleaseTypes.put("upcoming", R.string.release_type_upcoming);
        }
    }

    public void addRelease(ReleaseModel release) {
        releases.add(release);
        notifyItemInserted(releases.size());
    }

    public void removeRelease(int position) {
        releases.remove(position);
        notifyItemRemoved(position);
    }

    public void clearReleases() {
        int size = releases.size();
        releases.clear();
        notifyItemRangeRemoved(0, size);
    }

    @NonNull
    @Override
    public ReleaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.release_list_item, parent, false);
        return new ReleaseViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ReleaseViewHolder holder, int position) {
        ReleaseModel release = releases.get(position);

        holder.itemView.setOnClickListener(v -> {
            Intent intent = new Intent(context, ReleaseViewActivity.class);
            intent.putExtra("release", release.getId());
            context.startActivity(intent);
        });

        if (!release.getArtworkURL().isEmpty()) {
            Thread thread = new Thread(() -> {
                URL url;
                try {
                    url = new URL(context.getResources().getString(R.string.base_url) + release.getArtworkURL());
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                }

                // check cache
                Drawable cachedImage = Cache.drawables.get(url.toString());
                if (cachedImage != null) {
                    holder.artwork.post(() -> holder.artwork.setImageDrawable(cachedImage));
                    return;
                }
                // cache miss. download it!
                Drawable img;
                Bitmap bmp = SimpleDownloader.getImage(url);
                if (bmp != null) {
                    img = new BitmapDrawable(context.getResources(), bmp);
                } else {
                    img = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.default_music_art, null);
                }
                // store image in memory cache
                Cache.drawables.put(url.toString(), img);
                holder.artwork.post(() -> holder.artwork.setImageDrawable(img));
            });
            thread.start();
        }
        holder.artwork.setContentDescription(context.getString(R.string.music_artwork_description, release.getTitle()));

        holder.title.setText(release.getTitle());

        Calendar calendar = Calendar.getInstance(Locale.GERMANY);
        calendar.setTime(release.getReleaseDate());
        holder.year.setText(String.valueOf(calendar.get(Calendar.YEAR)));

        StringBuilder artist = new StringBuilder();
        ArrayList<MusicCreditModel> primaryCredits = new ArrayList<>();
        for (int i = 0; i < release.getCredits().size(); i++) {
            if (!release.getCredits().get(i).isPrimary()) continue;
            primaryCredits.add(release.getCredits().get(i));
        }
        for (int i = 0; i < primaryCredits.size(); i++) {
            if (i == 0) {
                artist.append(primaryCredits.get(i).getArtist().getName());
                continue;
            }
            if (i == primaryCredits.size() - 1) {
                artist.append(" & ").append(primaryCredits.get(i).getArtist().getName());
                break;
            }
            artist.append(", ").append(primaryCredits.get(i).getArtist().getName());
        }
        holder.artist.setText(artist.toString());

        // i can't make this linting error go away, please ignore it
        holder.type.setText(ReleaseTypes.getOrDefault(release.getType(), R.string.release_type_unknown));
    }

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

    public static class ReleaseViewHolder extends RecyclerView.ViewHolder {
        public final ImageView artwork;
        public final TextView title;
        public final TextView year;
        public final TextView artist;
        public final TextView type;

        public ReleaseViewHolder(@NonNull View itemView) {
            super(itemView);

            artwork = itemView.findViewById(R.id.artistAvatar);
            title = itemView.findViewById(R.id.musicTitle);
            year = itemView.findViewById(R.id.musicYear);
            artist = itemView.findViewById(R.id.musicArtist);
            type = itemView.findViewById(R.id.musicType);
        }
    }
}
