package me.arimelody.aridroid;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.util.LruCache;
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.recyclerview.widget.RecyclerView;

import java.io.InputStream;
import java.net.HttpURLConnection;
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> {
    Context context;
    Handler handler;
    ArrayList<ReleaseModel> releases;
    LruCache<URL, Bitmap> artworkCache;

    public static HashMap<String, Integer> ReleaseTypes = new HashMap<>();

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

        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);

        artworkCache = new LruCache<>(32);
    }

    public void addRelease(ReleaseModel release) {
        releases.add(release);
        handler.post(() -> notifyItemInserted(releases.size()));
    }

    public void removeRelease(int position) {
        releases.remove(position);
        handler.post(() -> notifyItemRemoved(position));
    }

    public void clearReleases() {
        int size = releases.size();
        releases.clear();
        handler.post(() -> 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);

        if (!release.getArtworkURL().isEmpty())
            holder.fetchReleaseArtwork(release.getArtworkURL(), artworkCache);
        holder.artwork.setContentDescription(release.getTitle() + " artwork");

        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).getName());
                continue;
            }
            if (i == primaryCredits.size() - 1) {
                artist.append(" & ").append(primaryCredits.get(i).getName());
                break;
            }
            artist.append(primaryCredits.get(i).getName()).append(", ");
        }
        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 {
        ImageView artwork;
        TextView title;
        TextView year;
        TextView artist;
        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);
        }

        void fetchReleaseArtwork(String artworkURL, LruCache<URL, Bitmap> artworkCache) {
            Thread thread = new Thread(() -> {
                try {
                    URL url = new URL(MainActivity.BASE_URL + artworkURL);

                    // check cache
                    Bitmap cachedImage = artworkCache.get(url);
                    if (cachedImage != null) {
                        artwork.post(() -> artwork.setImageBitmap(cachedImage));
                        return;
                    }

                    System.out.printf("Fetching %s...\n", url);
                    HttpURLConnection http = (HttpURLConnection) url.openConnection();
                    http.setRequestMethod("GET");
                    http.setRequestProperty("User-Agent", "aridroid/" + MainActivity.VERSION);
                    http.setRequestProperty("Accept", "image/*");

                    InputStream stream = http.getInputStream();
                    Bitmap img = BitmapFactory.decodeStream(stream);
                    // store image in memory cache
                    artworkCache.put(url, img);
                    artwork.post(() -> artwork.setImageBitmap(img));
                } catch (Exception e) {
                    System.err.printf("FATAL: Failed to fetch release artwork: %s\n", e);
                }
            });
            thread.start();
        }
    }
}
